Кластеризация центроидов реальных данных в Python

Я решил, что sklearn kmeans использует воображаемые точки в качестве центроидов кластера.

Пока я не нашел возможности использовать реальные точки данных в качестве центроидов в sklearn.

В настоящее время я вычисляю точку данных, ближайшую к центроиду, но подумал, что может быть более простой способ.

Кстати, я не обязательно ограничиваюсь kmeans.

Поиск в Google по кластеризации с реальными центроидами данных также не дал результатов.

У кого-нибудь была такая же проблема раньше?

import numpy as np
from sklearn.cluster import KMeans
import math

def distance(a, b):
    dist = math.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2)
    return dist

x = np.random.rand(10)
y = np.random.rand(10)

xy = np.array((x,y)).T

kmeans = KMeans(n_clusters=2)
kmeans.fit(xy)
centroids  = kmeans.cluster_centers_

print(np.where(xy == centroids[0])[0])

for c in centroids:
    nearest = min(xy, key=lambda x: distance(x, c))
    print('centroid', c)
    print('nearest data point to centroid', nearest)

person gimba    schedule 16.01.2020    source источник
comment
Что вы имеете в виду под kmeans использует воображаемые точки в качестве центроидов кластера?   -  person Sociopath    schedule 16.01.2020
comment
Центроиды вычисляются путем взятия среднего значения кластера, поэтому они не встречаются во входных данных   -  person gimba    schedule 16.01.2020
comment
k-medoids недоступен в sklearn, извините. А у pycluster только довольно плохой алгоритм.   -  person Has QUIT--Anony-Mousse    schedule 19.01.2020


Ответы (2)


Фактически sklearn.cluster.KMeans теперь позволяет использовать настраиваемые центроиды. см. раздел init здесь https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html или в исходном коде sklearn.kmneans здесь: https://github.com/scikit-learn/scikit-learn/blob/b194674c4/sklearn/cluster/_kmeans.py#L649

"Если передан ndarray, он должен иметь форму (n_clusters, n_features) и давать начальные центры."

Я надеюсь, что это сработает. Пожалуйста, попробуй.

person Poe Dator    schedule 16.01.2020
comment
Спасибо за комментарий. На самом деле я не знаю заранее центроиды кластеров. Я хочу вычислить центроиды кластера, которые являются реальными точками данных, которые исходят из входных данных. - person gimba; 16.01.2020
comment
Именно так я понял ваш вопрос. Я предполагал, что вы выберете несколько своих точек данных в качестве начальных центроидов и передадите их функции. - person Poe Dator; 16.01.2020

Центроиды не обязательно должны быть точками в вашем наборе. Поскольку вы находитесь в двумерном пространстве, вы найдете центроиды с двумерными координатами. Если вы хотите напечатать расстояния между каждым центроидом и каждой точкой, вы можете:

import numpy as np
import pandas as pd
from sklearn.cluster import KMeans

x = np.random.rand(10)
y = np.random.rand(10)

xy = np.array((x,y)).T

kmeans = KMeans(n_clusters=2)
kmeans.fit(xy)
centroids  = kmeans.cluster_centers_

for centroid in centroids:
    print(f'List of distances between centroid {centroid} and each point:\n\
          {np.linalg.norm(centroid-xy, axis=1)}\n')

List of distances between centroid [0.87236496 0.74034618] and each point:
          [0.21056113 0.84946149 0.83381298 0.31347176 0.40811323 0.85442416
 0.44043437 0.66736601 0.55282619 0.14813826]

List of distances between centroid [0.37243631 0.37851987] and each point:
          [0.77005698 0.29192851 0.25249753 0.60881231 0.2219568  0.24264077
 0.27374379 0.39968813 0.31728732 0.58604271]

Как видите, этот прогноз соответствует центроиду, до которого расстояние минимально:

kmeans.predict(xy)
array([0, 0, 0, 0, 1, 1, 0, 1, 1, 1])


distances = np.vstack([np.linalg.norm(centroids[0]-xy, axis=1),
                     np.linalg.norm(centroids[1]-xy, axis=1)])
distances.argmin(axis=0)
array([0, 0, 0, 0, 1, 1, 0, 1, 1, 1])

Построим график данных: центроиды имеют квадратную форму, а точки имеют форму круга, размер которого обратно пропорционален расстоянию от его центроида.

Теперь, хотя на рисунке показаны другие случайные точки данных, я надеюсь, что это поможет.

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

person FBruzzesi    schedule 16.01.2020