您可以做的是使用集群质心以及标签来索引到集群质心,以获取每个示例的表示方式。然后,您可以分别计算每个示例的失真。回想一下,K-Means 聚类结果的失真或惯性只是示例与其对应的代表质心之间的平方差之和。要计算单个失真值,您只需找到每个示例的代表质心,然后找到分量的平方差之和。总失真是所有这些值的总和。
因此:
cluster_centers = km.cluster_centers_
centroids = cluster_centers[y_km]
distortion = ((df_tr_std - centroids)**2.0).sum(axis=1)
第一行代码访问您拟合的 K-means 模型的聚类中心。第二行代码使用拟合结果输出的标签获取每个示例的代表性质心。对于最后一行,您可以通过减去输入的每一行或示例及其代表质心分量来计算失真,将每个元素平方,然后沿每一行求和。
在不需要临时变量的情况下,在一行中执行此操作可能很方便:
distortion = ((df_tr_std - km.cluster_centers_[y_km])**2.0).sum(axis=1)
现在为您提供每个示例的计算失真。具体来说,distortion 是一个 N, NumPy 数组,N 是数据集中示例的数量。每个元素对应于相应示例对整体失真的贡献。
要验证,您可以检查km.inertia_,即总失真与最后一行计算的失真数组的总和相匹配,因此请检查distortion.sum() 和km.inertia_。
作为一个可重现的例子:
In [27]: import numpy as np
In [28]: from sklearn.cluster import KMeans
In [29]: df_tr_std = np.random.rand(1000,3)
In [30]: km = KMeans(n_clusters=3, init='k-means++',n_init=10,max_iter=300,tol=
...: 1e-04,random_state=0)
In [31]: y_km = km.fit_predict(df_tr_std)
In [32]: distortion = ((df_tr_std - km.cluster_centers_[y_km])**2.0).sum(axis=1)
In [33]: km.inertia_
Out[33]: 147.01626670004867
In [34]: distortion.sum()
Out[34]: 147.01626670004865
请注意,值的尾部存在一些细微差异,这是由于数值精度造成的,但您可以放心,我们已经分别计算了每个示例的失真。
一旦你有了扭曲的数组,你可以在你的数据框中添加一个额外的列来代表这些,你可以根据你的需要找到哪一行给你带来了最大或最小的扭曲。