python kmeans кластеризация центроидов реальных данных - PullRequest
0 голосов
/ 16 января 2020

Я полагал, что 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)

Ответы [ 2 ]

1 голос
/ 16 января 2020

На самом деле 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) и давать начальные центры."

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

0 голосов
/ 16 января 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])

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

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

enter image description here

...