23

我有一个在一组对象上运行的算法。该算法产生一个分数值,指示集合中元素之间的差异。

排序后的输出是这样的:

[1,1,5,6,1,5,10,22,23,23,50,51,51,52,100,112,130,500,512,600,12000,12230]

如果您将这些值放在电子表格上,您会看到它们组成了组

[1,1,5,6,1,5] [10,22,23,23] [50,51,51,52] [100,112,130] [500,512,600] [12000,12230]

有没有办法以编程方式获取这些分组?

也许一些使用机器学习库的聚类算法?还是我想多了?

我看过 scikit 但他们的例子对于我的问题来说太先进了......

4

3 回答 3

35

不要对一维数据使用聚类

聚类算法是为多变量数据设计的。当您拥有一维数据时,对其进行排序,并寻找最大的差距。这在 1d 中是微不足道的和快速的,在 2d 中是不可能的。如果您想要更高级的东西,请使用核密度估计 (KDE) 并寻找局部最小值来拆分数据集。

这个问题有很多重复:

于 2013-08-22T16:13:46.663 回答
28

如果您不知道集群的数量,一个不错的选择是MeanShift

import numpy as np
from sklearn.cluster import MeanShift, estimate_bandwidth

x = [1,1,5,6,1,5,10,22,23,23,50,51,51,52,100,112,130,500,512,600,12000,12230]

X = np.array(zip(x,np.zeros(len(x))), dtype=np.int)
bandwidth = estimate_bandwidth(X, quantile=0.1)
ms = MeanShift(bandwidth=bandwidth, bin_seeding=True)
ms.fit(X)
labels = ms.labels_
cluster_centers = ms.cluster_centers_

labels_unique = np.unique(labels)
n_clusters_ = len(labels_unique)

for k in range(n_clusters_):
    my_members = labels == k
    print "cluster {0}: {1}".format(k, X[my_members, 0])

此算法的输出:

cluster 0: [ 1  1  5  6  1  5 10 22 23 23 50 51 51 52]
cluster 1: [100 112 130]
cluster 2: [500 512]
cluster 3: [12000]
cluster 4: [12230]
cluster 5: [600]

修改quantile变量可以改变聚类数选择标准

于 2013-08-21T18:01:23.203 回答
7

您可以使用集群对这些进行分组。诀窍是要了解您的数据有两个维度:您可以看到的维度,以及看起来像 [1, 2, 3... 22] 的“空间”维度。您可以像这样在numpy中创建此矩阵:

import numpy as np

y = [1,1,5,6,1,5,10,22,23,23,50,51,51,52,100,112,130,500,512,600,12000,12230]
x = range(len(y))
m = np.matrix([x, y]).transpose()

然后您可以对矩阵执行聚类,其中:

from scipy.cluster.vq import kmeans
kclust = kmeans(m, 5)

kclust 的输出将如下所示:

(array([[   11,    51],
       [   15,   114],
       [   20, 12115],
       [    4,     9],
       [   18,   537]]), 21.545126372346271)

对你来说,最有趣的部分是矩阵的第一列,它表示沿 x 维的中心是什么:

kclust[0][:, 0]
# [20 18 15  4 11]

然后,您可以根据它们最接近的五个中心中的哪一个将您的点分配给一个集群:

assigned_clusters = [abs(cluster_indices - e).argmin() for e in x]
# [3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 0, 0, 0]
于 2013-08-21T17:52:36.103 回答