我正在尝试通过 Python 中的以下代码片段应用 K-Means。基本上, arr 是一个 numpy 数组,在三列中具有值(我想要聚类的 Data with Multiple Features )。在这里,我使用了以下值: cv.TERM_CRITERIA_EPS = 1.0cv.TERM_CRITERIA_MAX_ITER = 10attempts = 10 。 (根据上面 OpenCV 文档链接中的默认值)。

具体来说,我的三列 arr 是一个 RGB 图像,它被重新塑造成每列代表一个颜色 channel 。

import cv2
import numpy as np

Z = np.float32(arr)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
ret, label, center = cv2.kmeans(Z, 4, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
labelToUse = (label.flatten()).astype('int32')
centerToUse = center.astype('float64')

虽然这在 70% 的情况下给了我完美的结果,但在 30% 的时间里我遇到了一个奇怪的情况 ,如下图所示(左边的是 centerToUse ,右边的是 labelToUse )。也就是说,我所有的聚类中心都是 (0, 0, 0),而所有数据点的标签都是 0,除了最后三个(分别为 3、2 和 1)。此外,对于相同的 arr ,在某些运行中会出现这种异常情况,而在其他情况下,结果是完美的。

python - 所有中心都在 K-Means 聚类上重合-LMLPHP

任何人都可以建议我,关于我应该采取什么方法来消除这种异常。我希望每次都从 K-Means 中获得不错的结果,而不是等待好运。另外(不知道这在这里是否相关), scikit-learn representation of K-Means 的情况相同。如果我将 n_initmax_iter 分别增加到 30 和 300,这会有所改善,但仍然存在。 K-Means++ 初始化也无济于事。

编辑: 根据@dhanushka 的评论,我记录了使用 cv2.KMEANS_PP_CENTERS 的紧凑性值。它如下(下图),即输出完美时紧凑度 = 61555894.92789865,而“奇怪”情况下紧凑度 = 0.0(所有中心都在 (0,0,0))。可能超过了数据类型的限制。

python - 所有中心都在 K-Means 聚类上重合-LMLPHP

在这个问题上的任何线索将不胜感激。

最佳答案

您的代码每次都对我有用:

import cv2
import numpy as np

arr=cv2.imread('F:/ImagesForTest/lena.jpg')
Z = np.float32(arr)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1)
ret, label, center = cv2.kmeans(Z, 4, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
labelToUse = (label.flatten()).astype('uint8')
centerToUse = center.astype('float64')
print(ret)
print(labelToUse)
print(centerToUse)

输出始终如下所示:
746189834.28125
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
[[111.20652008 134.6521759  228.45652771 ...  76.47826385  51.76087189
  126.43478394]
 [ 62.84615707  27.25000191  92.94231415 ...  76.61538696  51.42308044
  130.98077393]
 [ 78.15841675  65.23762512 168.42573547 ... 122.78217316 136.54455566
  209.80197144]
 [ 78.06511688  57.17674255 149.40930176 ... 133.32092285 150.96278381
  207.73487854]]

关于python - 所有中心都在 K-Means 聚类上重合,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61689930/

10-12 22:21