我正在尝试通过 Python 中的以下代码片段应用 K-Means。基本上, arr
是一个 numpy 数组,在三列中具有值(我想要聚类的 Data with Multiple Features )。在这里,我使用了以下值: cv.TERM_CRITERIA_EPS = 1.0
、 cv.TERM_CRITERIA_MAX_ITER = 10
和 attempts = 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
,在某些运行中会出现这种异常情况,而在其他情况下,结果是完美的。任何人都可以建议我,关于我应该采取什么方法来消除这种异常。我希望每次都从 K-Means 中获得不错的结果,而不是等待好运。另外(不知道这在这里是否相关), scikit-learn representation of K-Means 的情况相同。如果我将
n_init
和 max_iter
分别增加到 30 和 300,这会有所改善,但仍然存在。 K-Means++ 初始化也无济于事。编辑: 根据@dhanushka 的评论,我记录了使用 cv2.KMEANS_PP_CENTERS 的紧凑性值。它如下(下图),即输出完美时紧凑度 = 61555894.92789865,而“奇怪”情况下紧凑度 = 0.0(所有中心都在 (0,0,0))。可能超过了数据类型的限制。
在这个问题上的任何线索将不胜感激。
最佳答案
您的代码每次都对我有用:
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/