这里有一小段代码:
df_tr_std = stats.zscore(df_tr[clmns])km = KMeans(n_clusters=3, init='k-means++',n_init=10,max_iter=300,tol=1e-04,random_state=0)y_km = km.fit_predict(df_tr_std)
我尝试引用inertial_,但那是总畸变。以下代码可以计算各个距离:
distance = euclidean_distances(km.cluster_centers_, df_tr_std)
但它将距离分成了3个数组(或者根据我创建的聚类数量)。有没有办法在不按标签/聚类分离的情况下做到这一点?
我想在我的原始数据集中添加一列距离,以便我可以识别出最大的距离。我也想要最接近的距离,但我能够使用以下代码找到它:
closest, _ = pairwise_distances_argmin_min(km.cluster_centers_, df_tr_std)
回答:
你可以使用聚类中心和标签来索引聚类中心,以获得每个样本的表示。然后,你可以单独计算每个样本的畸变。回顾一下,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 npIn [28]: from sklearn.cluster import KMeansIn [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.01626670004867In [34]: distortion.sum()Out[34]: 147.01626670004865
请注意,数值的末尾有些微小的差异,这是由于数值精度引起的,但你可以确信我们已经单独计算了每个样本的畸变。
一旦你有了畸变数组,你可以在数据框中添加一个代表这些畸变的额外列,并根据需要找出哪一行给出了最大或最小的畸变。