在不使用阈值的情况下对值数组进行聚类



我想将一个 1D 数据集分割,其中每个值表示一个错误分为 2 个段:

  • 具有最小值的聚类
  • 所有其他

例:

X = np.array([1, 1.5, 0.4, 1.1, 23, 24, 22.5, 21, 20, 25, 40, 50, 50, 51, 52, 53]).reshape(-1, 1)

在这个小示例中,我想重新组合集群中的前 4 个值,而忘记其他值。我不想要基于阈值的解决方案。关键是感兴趣的质心簇并不总是具有相同的值。它可能是1e-6,也可能是1e-3的,也可能是1的。

我的想法是使用 k 均值聚类算法,如果我知道数据中存在多少聚类,该算法将正常工作。在上面的示例中,数字为 3,一个围绕 1(感兴趣的聚类),一个围绕 22,一个围绕 51。但可悲的是,我不知道集群的数量...仅搜索 2 个聚类不会导致按预期对数据集进行分割。

kmeans = KMeans(n_clusters=2, random_state=0).fit(X)
kmeans.labels_

返回太大的聚类 1,其中还包括以 22 为中心的聚类中的数据。

array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0])

我确实在选择k的方法上找到了一些有趣的答案,但它使算法复杂化,我觉得一定有更好的方法来解决这个问题。

我愿意接受任何可以在提供的X数组上工作的建议和示例。

您可能会发现AffinityPropagation在这里很有用,因为它不需要指定要生成的集群数量。但是,您可能需要调整damping factorpreference,以便产生预期的结果。

在提供的示例中,默认参数似乎可以完成这项工作:

from sklearn.cluster import AffinityPropagation
X = np.array([1, 1.5, 0.4, 1.1, 23, 24, 22.5, 
21, 20, 25, 40, 50, 50, 51, 52, 53]).reshape(-1, 1)
ap = AffinityPropagation(random_state=12).fit(X)
y = ap.predict(X)
print(y)
# array([0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2], dtype=int64)

要从X获取单个集群,可以使用y进行索引:

first_cluster = X[y==0].ravel()
first_cluster
# array([1. , 1.5, 0.4, 1.1])
second_cluster = X[y==1].ravel()
second_cluster
# array([23. , 24. , 22.5, 21. , 20. , 25. ])

最新更新