【问题标题】:Clustering dense data points horizontally水平聚类密集数据点
【发布时间】:2017-01-28 22:50:54
【问题描述】:

我在一个二维 numpy 数组中有一组大约 34,000 个数据标签及其各自的特征(状态概率),可视化为散点图,看起来像 。

很容易看出,大部分 b 数据点位于底部且非常密集。我想使用聚类算法来提取底部区域。我不追求完美的结果。这只是关于提取大部分 b 点。

到目前为止,我已经尝试了 DBSCAN 算法:

import sklearn.cluster as sklc

data1, data2 = zip(*dist_list[1])
data = np.array([data1, data2]).T

core_samples, labels_db = sklc.dbscan(
    data,  # array has to be (n_samples, n_features)
    eps=2.0,
    min_samples=5,
    metric='euclidean',
    algorithm='auto'
)
core_samples_mask = np.zeros_like(labels_db, dtype=bool)
core_samples_mask[core_samples] = True

unique_labels = set(labels_db)

n_clusters_ = len(unique_labels) - (1 if -1 in labels_db else 0)

colors = plt.cm.Spectral(np.linspace(0, 1, len(unique_labels)))
for k, col in zip(unique_labels, colors):
    if k == -1:
        # Black used for noise.
        col = 'k'

    class_member_mask = (labels_db == k)

    xy = data[class_member_mask & core_samples_mask]
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=col, markeredgecolor='k', markersize=6)

    xy = data[class_member_mask & ~core_samples_mask]
    plt.plot(xy[:, 0], xy[:, 1], 'x', markerfacecolor=col, markeredgecolor='k', markersize=4)

plt.rcParams["figure.figsize"] = (15, 15)
plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()

产生。

增加最小样本量只会导致更小的垂直线被归类为噪声,而更长(和更密集)的垂直线会保留下来。

我还尝试使用scipy.cluster.hierarchy 进行聚类:

thresh = 2
clusters = hcluster.fclusterdata(data, thresh, criterion="distance")

plt.scatter(*data.T, c=clusters)
title = "t=%f, n=%d" % (thresh, len(set(clusters)))
plt.title(title)
plt.show()

这导致了类似的垂直分类。请查看该情节的评论。以我的名声,我还不能发布两个以上的链接。

现在我的问题是,我在校准算法时犯了错误吗?还是我选择的算法一开始就错了?如何提取b个数据点的密集区域?

【问题讨论】:

  • This 是我使用 scipy 层次算法后得到的类似分类。
  • 尝试扩展您的数据。 x 轴的范围从 0 到 35,000,而 y 轴的范围从 0 到 1。垂直距离远小于水平距离,这就是算法将数据点垂直聚类的原因。查看 Scikit-learn (scikit-learn.org/stable/modules/preprocessing.html) 的预处理实用程序。
  • 也许你想多了。看起来您只需对 y 值应用阈值就可以做得很好,例如中位数 +/- 0.01。
  • 一维(线性)数组怎么样,例如有事件(或没有事件)的时间线?我们如何在没有预先指定的情况下找到密度,聚类为最高密度(1 个点是无限密度,2 个接近点非常高,但也许有 5 或 15 个点的聚类接近高密度)?这是一个简单的过程,还是必须反复进行?在 SAS(我选择的语言)中,可以使用滞后代码找到 n 点的平均值 link

标签: python scipy scikit-learn cluster-analysis dbscan


【解决方案1】:
  1. 永远不要包含 ID 属性。您的“节点索引”不应该用于相似度计算,不是吗?

  2. 当您的属性具有不同的单位和规模时,您需要非常小心。一种流行的启发式方法是StandardScaler,即将每个属性归一化以具有单位方差。但是考虑到您的数据分布(x 上均匀,y 上偏斜),我认为标准化的使用并没有得到理论的充分支持 - 它假设高斯分布。

这两者的结合就是你得到这个结果的原因:你的 x 轴完全支配了结果。从字面上看,它的影响力是 y 轴的 10000 倍以上您仅基于节点 ID 有效地进行聚类...

永远不要假设集群“有效”。所有这些方法都非常对预处理敏感,因此需要谨慎应用。

【讨论】:

    猜你喜欢
    • 2021-07-25
    • 2021-01-27
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    相关资源
    最近更新 更多