Все центры совпадают при кластеризации K-средних - PullRequest
4 голосов
/ 09 мая 2020

Я пытаюсь применить К-средние через следующий фрагмент кода в Python. По сути, arr представляет собой массив numpy, имеющий значения в трех столбцах ( Данные с несколькими функциями , которые я хочу кластеризовать). Здесь я использовал следующие значения: cv.TERM_CRITERIA_EPS = 1.0, cv.TERM_CRITERIA_MAX_ITER = 10 и attempts = 10. (согласно значениям по умолчанию в ссылке на документацию OpenCV выше).

Чтобы указать c, мои три столбца arr - это изображение RGB, форма которого изменена так, что каждый столбец представляет канал цвета.

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 в некоторых прогонах возникает этот ненормальный случай, в то время как в других результаты просто идеальны.

enter image description here

Кто-нибудь может подсказать мне, каким должен быть мой подход к устранению этой аномалии. Я хочу каждый раз получать достойные результаты от K-Means, а не ждать удачи. Также (не знаю, актуально это здесь или нет), ситуация такая же в представлении scikit-learn для K-средних . Это немного улучшится, если я увеличу n_init и max_iter до 30 и 300 соответственно, но все равно останется. Инициализация K-Means ++ тоже не помогает.

EDIT: На основании комментария @dhanushka я записал значение компактности при использовании cv2.KMEANS_PP_CENTERS. Это получилось следующим образом (рисунок ниже), т.е. компактность = 61555894.92789865, когда результат идеальный, а компактность = 0,0 для «странного» случая (все центры в (0,0,0)). Возможно, что он превышает предел для типа данных.

enter image description here

Мы будем очень признательны за любые предложения в этом выпуске.

1 Ответ

0 голосов
/ 09 мая 2020

Ваш код каждый раз работает нормально:

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]]
...