kmeans.transform return 每个点到其指定簇的欧几里得距离吗?

Does kmeans.transform return the euclidian distance of each point to its assigned cluster?

我有以下数据集,我用 k=3

拟合了一个 kmeans
import numpy as np

from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans

# Generate some random clusters
X, y = make_blobs()
kmeans = KMeans(n_clusters=3).fit(X)

我正在通过 using kmeans.transform(X)

计算每个点到每个分配的簇的距离
# squared distance to cluster center
X_dist = kmeans.transform(X)**2

import pandas as pd
df = pd.DataFrame(X_dist.sum(axis=1).round(2), columns=['sqdist'])
df['label'] = y

df.head()

我明白了

sqdist  label
0   200.04  1
1   303.11  0
2   267.50  0
3   181.64  1
4   334.58  2

现在如果我想“手动”计算这个距离,我会这样做

X_dt = pd.DataFrame(X)
X_dt['cluster'] = y
for k, centroid in enumerate(kmeans.cluster_centers_):
    
    d = np.linalg.norm(X - centroid, axis=1)
    X_dt[f'cluster_distance_{k}'] = d

这会给我这个

X_dt.head()

0   1   cluster cluster_distance_0  cluster_distance_1  cluster_distance_2
0   3.445588    2.479573    1   0.523083    9.900408    10.086907
1   6.942484    -7.084589   0   9.992428    14.212855   1.119853
2   5.673418    -7.160752   0   9.765687    13.117708   0.233798
3   4.000135    1.330473    1   1.124870    10.108471   8.842795
4   -6.925704   -1.042616   2   11.441470   1.076678    14.230793

如果我们查看最后的 X_dt

,我们会注意到两件事
  1. 数据点未分配给与其“最接近”的质心
  2. 手动计算时的距离与使用kmeans.transform
  3. 计算时的“距离”不一致

知道为什么会发生这两件事吗?

每个问题:

  1. 你这里的标签 y 是 pre-generated by make_blobs(),不是 KMean 的预测集群。由于make_blobs()是gaussian生成的,label是每个数据点的高斯中心,不一定是最近的中心。要获得 KMean 的预测集群,请使用以下内容:
kmeans = KMeans(n_clusters=3).fit(X)
kmeans.labels_
  1. 什么kmeans.transform(X) returns已经是到每个簇中心的L2范数距离了,不用再计算了。您可以将其与 np.linalg.norm().
  2. 的返回值进行比较