K均值聚类中节点与质心之间的距离是多少?

12

有没有一种方法可以提取kmeans聚类中节点和质心之间的距离。

我对文本嵌入数据集进行了Kmeans聚类,想知道每个簇中与质心相距较远的节点是哪些,以便检查相应节点的特征,看它们有何不同。

提前感谢!

3个回答

24

KMeans.transform() 返回每个样本到聚类中心的距离数组。

import numpy as np

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

import matplotlib.pyplot as plt
plt.style.use('ggplot')
import seaborn as sns

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

# plot the cluster centers and samples 
sns.scatterplot(kmeans.cluster_centers_[:,0], kmeans.cluster_centers_[:,1], 
                marker='+', 
                color='black', 
                s=200);
sns.scatterplot(X[:,0], X[:,1], hue=y, 
                palette=sns.color_palette("Set1", n_colors=3));

enter image description here

transform X并取每行的和(axis=1)来确定距离中心最远的样本。

# squared distance to cluster center
X_dist = kmeans.transform(X)**2

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

df.head()
    sqdist  label
0   211.12  0
1   257.58  0
2   347.08  1
3   209.69  0
4   244.54  0

一个可视化检查--相同的图形,只是这次突出显示每个聚类中心最远的点:

# for each cluster, find the furthest point
max_indices = []
for label in np.unique(kmeans.labels_):
    X_label_indices = np.where(y==label)[0]
    max_label_idx = X_label_indices[np.argmax(X_dist[y==label].sum(axis=1))]
    max_indices.append(max_label_idx)

# replot, but highlight the furthest point
sns.scatterplot(kmeans.cluster_centers_[:,0], kmeans.cluster_centers_[:,1], 
                marker='+', 
                color='black', 
                s=200);
sns.scatterplot(X[:,0], X[:,1], hue=y, 
                palette=sns.color_palette("Set1", n_colors=3));
# highlight the furthest point in black
sns.scatterplot(X[max_indices, 0], X[max_indices, 1], color='black');

enter image description here


1
完美的答案。基本上,除了找到集群中最远的节点外,我还尝试为每个集群设置一个阈值,并过滤掉所有具有比阈值更大的“sqdist”的节点。因此,我正在计算每个集群的“sqdist”平均值,并将其用作阈值,您认为这样做是否合理? - Arav
不知道你的下游用例是什么,很难说这是否合理,但似乎这是一种获取所有最接近中心点的点的合理方法。如果你认为这是对你最初问题的最佳答案,请随意接受答案 - Kevin

1

0

Kevin的回答很好,但我觉得它没有回答所提出的问题(也许我完全读错了)。如果您想查看每个单独的聚类中心并获取该聚类中距离中心最远的点,则需要使用聚类标签来获取每个点到该聚类质心的距离。上面的代码只是找到每个聚类中距离所有其他聚类中心最远的点(您可以在图片中看到,这些点总是在聚类的另外两个聚类的远侧)。为了查看单个聚类,您需要像以下内容:

center_dists = np.array([X_dist[i][x] for i,x in enumerate(y)])

这将为您提供每个点到其簇质心的距离。然后通过运行与Kevin上面几乎相同的代码,它将为您提供每个簇中最远的点。

max_indices = []
for label in np.unique(kmeans.labels_):
    X_label_indices = np.where(y==label)[0]
    max_label_idx = X_label_indices[np.argmax(center_dists[y==label])]
    max_indices.append(max_label_idx)

这个 center_dists 代码是替换 Kevin 代码中的 X_dist 吗? - KSp
是的。Kevin代码中的X_dist用于获取center_dists,然后将其插入到for循环的相同位置,以获取每个集群中距离集群中心最远的点。 - JBarrett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接