Я пытаюсь применить К-средние через следующий фрагмент кода в 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
в некоторых прогонах возникает этот ненормальный случай, в то время как в других результаты просто идеальны.
Кто-нибудь может подсказать мне, каким должен быть мой подход к устранению этой аномалии. Я хочу каждый раз получать достойные результаты от 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)). Возможно, что он превышает предел для типа данных.
Мы будем очень признательны за любые предложения в этом выпуске.