OpenCV KMeans(K均值)Python输出簇数问题
我正在使用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')
祝好,
Stefan
1 个回答
0
这个特性有时候是很有用的,但不同的实现方式可能会有所不同。
这是怎么发生的:当随机初始化或者使用Lloyd迭代时,可能会出现某个聚类失去所有对象的情况。在MacQueen k-means算法中,它应该始终保留至少一个对象。假设在一维空间中,有两个对象分别在1和2的位置,它们被分配到聚类c1。这个聚类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