OpenCV KMeans(K-Means)Python 输出聚类数问题

3
我正在使用OpenCV的Python接口对多维数据(通常是7维)进行K-Means聚类。我发现聚类结果有些奇怪。当请求n个聚类(索引从0到n)时,有些聚类没有分配到点,这导致聚类数少于预期。是否有人成功地使用过OpenCV的Python K-Means实现?一些用户经验或建议将非常有帮助。
下面是我的Python代码片段:
points = cv.CreateMat(dim1, dim2, cv.CV_32FC2)
clusters = cv.CreateMat(dim1, 1, cv.CV_32SC1)
for a in range(0,dim0):
   for b in range(0,dim1):
       for c in range(0,dim2):
           #print float(list[a*dim1*dim2 + b*dim2 + c])
           cv.Set2D( points, b, c, float(list[a*dim1*dim2 + b*dim2 + c]) )
cv.KMeans2(points, numClusters, clusters, (cv.CV_TERMCRIT_EPS + cv.CV_TERMCRIT_ITER, 100000, 0.00000001), 50)

for d in range(0,dim1):
    f.write(str(int(clusters[d,0])))
    f.write(' ')
    f.write('\n')

问候,

斯特凡


我不知道cv,但是:numClusters是什么?每个点都在某个簇中吗?你能检查一些点,距离最近的<距离到其他簇的距离吗? - denis
NumClusters是要生成的簇数。每个点最终都会被分配到某个簇中。问题在于有些簇是空的。这实际上意味着生成的簇数少于NumClusters。 - tisch
你的numClusters的值是多少 -- 10,100 -- Npoints和Ndim又是什么?你能检查几个点吗?可以尝试不同的numClusters/其他参数/初始中心吗? - denis
@Denis,目前我有180个聚类。我的点的维度是7。输入了642个点。到目前为止还没有尝试过其他聚类数量。没有定义初始中心的方法。 - tisch
以每个簇仅有3-4个点来计算,其中一些必定为空(如果是Poisson分布,则大约3%为空 + 10%单元素)。你只能尝试Ncluster 190、200……一直到出现180为止 :( - denis
1个回答

0

这可能是一个理想的属性,它因实现而异。

如何发生:当随机初始化或使用Lloyd迭代时,可能会发生一个簇失去所有对象的情况。在MacQueen k-means中,它应该始终保留至少一个对象。假设在1d中,有(除其他外)分配给簇c1的对象为1和2。簇c1的平均值为1.5。现在,如果有另外两个簇的平均值移动到0.6和2.4,则这两个对象将被重新分配,簇c1将突然变为空。

为什么这可能是可取的:假设您事先不知道最佳的k值,您可能只是决定选择一个过大的k并查看一些簇是否退化。

很可能这表明您的数据集与k-means不兼容。K-means非常挑剔,令人惊讶的是它仍然可以满足大多数情况。一般来说,k-means不喜欢大小相差但彼此接近的聚类。因为k-means总是在中间分裂!此外,在您的特定情况下,k可能太高了。

以下是一个一维示例,说明k-means不喜欢的情况:(A和B是它们各自聚类的对象;第二行表示真实均值和两个均值之间的中间分割线。k-means将重新分配并进一步向左分裂。

AAAAAAAAAAAAA BBBBB
      A    |    B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接