Почему FCM так кластеризует?

Рейтинг: 0Ответов: 1Опубликовано: 11.04.2023

Почему в Fuzzy C-Means (FCM) при указанном n_clusters=10 все равно количество кластеров скачет туда-сюда? Например, на рисунке ниже выводит только 9 кластеров. Понимаю, что он может иметь меньше 10 элементов для вывода, и тогда результат будет как в 1 строчке. Но почему 10 строчка пуста?

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import *
from sklearn.datasets import load_digits
from sklearn.cluster import KMeans
import skfuzzy as fuzz

digits = load_digits()
X = digits.data
y = digits.target

n_clusters = 10

FCMmodel = fuzz.cluster.cmeans(X.T, n_clusters, 2, error=0.005, maxiter=1000)

FCMlabels = np.argmax(FCMmodel[1], axis=0)

print("FCM")
fig, ax = plt.subplots(n_clusters, 10, figsize=(10, n_clusters))
for i in range(n_clusters):
    cluster_imgs = X[FCMlabels == i]
    for j in range(min(10, len(cluster_imgs))):
        ax[i, j].imshow(cluster_imgs[j].reshape((8, 8)), cmap=plt.cm.gray_r)
        ax[i, j].axis('off')

plt.show()

Результат работы видно на картинке ниже.

result

Почему на изображении ниже кластера всего восемь, я могу лишь догадываться.

введите сюда описание изображения

Ответы

▲ 1Принят

А давайте посмотрим по 10 самых уверенных представителей каждого из кластеров:

fig, ax = plt.subplots(n_clusters, 10, figsize=(n_clusters, 10))
for i in range(n_clusters):
    cluster_imgs = np.argsort(FCMmodel[1][i,:])
    for j in range(10):
        cluster_img = X[cluster_imgs[j], :]
        ax[i,j].imshow(cluster_img.reshape((8, 8)), cmap=plt.cm.gray_r)
        ax[i,j].axis('off')

Вот картинка, полученная вашим кодом:

введите сюда описание изображения

Вот картинка, добавленная моим кодом:

введите сюда описание изображения

Проблема судя по всему в том, что каждая цифра принадлежит нескольким кластерам. И есть такие кластеры, в принадлежности к которым модель более уверена, чем к другим. Или в равной степени уверена. И есть такие кластеры, уверенность принадлежности к которым меньше. В результате, когда вы берёте argmax сразу по всей матрице, то у вас вполне могут получиться не охваченными какие-то из таких "слабых" кластеров, принадлежность к которым более слабо выражена, чем к другим. Эти "слабые" кластера просто не попадают в результат работы argmax.