【问题标题】:Is there a way to output the distortions for each row when creating clusters with kmeans?用kmeans创建集群时,有没有办法输出每一行的失真?
【发布时间】:2018-08-10 00:59:54
【问题描述】:

这里有一点代码:

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)

我尝试引用惯性_,但那是完全失真。以下代码用于计算各个距离:

distance = euclidean_distances(km.cluster_centers_, df_tr_std)

但它将距离分成 3 个数组(或者我创建的许多簇)。有没有办法在不按标签/集群分隔的情况下做到这一点?

我想用一列距离扩展我的原始数据集,以便我可以识别最大距离。我也想要最近的距离,但我能够使用以下代码找到:

closest, _ = pairwise_distances_argmin_min(km.cluster_centers_, df_tr_std)

【问题讨论】:

    标签: python machine-learning scikit-learn k-means


    【解决方案1】:

    您可以做的是使用集群质心以及标签来索引到集群质心,以获取每个示例的表示方式。然后,您可以分别计算每个示例的失真。回想一下,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
    

    请注意,值的尾部存在一些细微差异,这是由于数值精度造成的,但您可以放心,我们已经分别计算了每个示例的失真。

    一旦你有了扭曲的数组,你可以在你的数据框中添加一个额外的列来代表这些,你可以根据你的需要找到哪一行给你带来了最大或最小的扭曲。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-09
      • 1970-01-01
      • 2020-07-13
      • 2021-05-02
      • 2020-01-25
      • 1970-01-01
      相关资源
      最近更新 更多