1D数字阵列聚类

时间:2012-07-16 22:25:01

标签: arrays cluster-analysis data-mining dimension partition-problem

  

可能重复:
  Cluster one-dimensional data optimally?

所以,假设我有一个这样的数组:

[1,1,2,3,10,11,13,67,71]

有没有一种方便的方法将数组分区为这样的东西?

[[1,1,2,3],[10,11,13],[67,71]]

我查看了类似的问题但是大多数人建议使用k-means来聚集点,例如scipy,这对于像我这样的初学者来说非常混乱。另外我认为k-means更适合两维或更多维聚类吧?有没有办法根据数字将N个数组分组到多个分区/聚类?

有些人还建议使用严格的范围分区,但并不总是将结果呈现为  预期

4 个答案:

答案 0 :(得分:91)

不要将多维聚类算法用于一维问题。单个维度很多比您想象的更加特殊,因为您实际上可以排序它,这使事情变得更加容易。

事实上,它通常甚至不称为聚类,但例如分割或自然中断优化。

您可能希望查看Jenks Natural Breaks Optimization和类似的统计方法。 Kernel Density Estimation 也是一个很好的方法,具有强大的统计背景。密度的局部最小值是将数据分成簇的好地方,有统计学的理由这样做。 KDE可能是聚类1维数据的最佳方法。

使用KDE,再次证明一维数据表现得更好。在1D,你有当地的最小值;但在2D中你可能有马鞍点和这样的“可能”分裂点。请参阅此Wikipedia illustration of a saddle point,了解这一点可能适合或不适合拆分群集。

答案 1 :(得分:5)

您可以查找离散算法。 1D离散化问题与您提出的问题非常相似。他们根据频率,分组策略等决定截止点。

weka在其离散化过程中使用以下算法。

  

weka.filters.supervised.attribute.Discretize

     

使用Fayyad& Irani的MDL方法或Kononeko的MDL标准

     

weka.filters.unsupervised.attribute.Discretize

     

使用简单的分箱

答案 2 :(得分:1)

CKwrap 是一个快速而直接的 k-means 聚类函数,尽管文档上有点少。

示例用法

pip 安装 ckwrap

import ckwrap

nums= np.array([1,1,2,3,10,11,13,67,71])
km = ckwrap.ckmeans(nums,3)

print(km.labels)
# [0 0 0 0 1 1 1 2 2]


buckets = [[],[],[]]
for i in range(len(nums)):
    buckets[km.labels[i]].append(nums[i])
print(buckets)
# [[1, 1, 2, 3], [10, 11, 13], [67, 71]]
exit()

我希望作者希望您使用 nd 数组功能,而不是创建列表列表。

其他措施:

km.centers
km.k
km.sizes
km.totss
km.betweenss
km.withinss

底层算法基于此article

答案 3 :(得分:0)

这个简单的算法有效:

points = [0.1, 0.31,  0.32, 0.45, 0.35, 0.40, 0.5 ]

clusters = []
eps = 0.2
points_sorted = sorted(points)
curr_point = points_sorted[0]
curr_cluster = [curr_point]
for point in points_sorted[1:]:
    if point <= curr_point + eps:
        curr_cluster.append(point)
    else:
        clusters.append(curr_cluster)
        curr_cluster = [point]
    curr_point = point
clusters.append(curr_cluster)
print(clusters)

上面的例子将点聚集到一个组中,这样一个组中的每个元素至多与组中的另一个元素相距eps。这就像带有 DBSCAN 的聚类算法 eps=0.2, min_samples=1。正如其他人指出的那样,一维数据允许您直接解决问题,而不是使用像 DBSCAN 这样的大枪。

对于一些包含 <1000 元素的小型数据集,上述算法的速度提高了 10-100 倍。