【问题标题】:Distance between nodes and the centroid in a kmeans cluster?kmeans集群中节点和质心之间的距离?
【发布时间】:2019-06-11 21:39:02
【问题描述】:

用于提取 kmeans 集群中节点和质心之间距离的任何选项。

我已经对文本嵌入数据集进行了 Kmeans 聚类,我想知道每个集群中哪些节点远离质心,以便我可以检查各个节点的特性是否有所不同.

提前致谢!

【问题讨论】:

    标签: python-3.x scikit-learn k-means euclidean-distance


    【解决方案1】:

    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));
    

    transformX 并取每一行的总和 (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');
    

    【讨论】:

    • 完美答案。基本上,除了找到集群中最远的节点外,我还尝试为每个集群设置一个阈值,并过滤掉所有那些“sqdist”大于阈值的节点。所以我从每个集群的“sqdist”中取平均值并将其用作阈值,从您的角度来看,这听起来合理吗?
    • 在不了解您的下游用例的情况下很难说这是明智的,但它似乎是一种合理的方法来获取最接近中心点的所有点。如果您认为这是对原始问题的最佳答案,请随时 accept the answer
    【解决方案2】:

    如果你使用 Python 和 sklearn。

    从这里: https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans

    你可以得到labels_cluster_centers_

    现在,您确定采用每个节点的向量及其集群中心的距离函数。按labels_ 过滤并计算每个标签内每个点的距离。

    【讨论】:

      【解决方案3】:

      Kevin 在上面有一个很好的答案,但我觉得它没有回答所提出的问题(也许我完全看错了)。如果您试图查看每个单独的集群中心并获取该集群中离中心最远的点,您将需要使用集群标签来获取每个点到该集群质心的距离。上面的代码只是在每个集群中找到距离所有其他集群中心最远的点(您可以在图片中看到,这些点始终位于集群的远端,远离其他 2 个集群)。为了查看各个集群,您需要以下内容:

      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 来的?
      • 是的。 Kevin 代码中的 X_dist 用于获取 center_dists。然后将其插入 for 循环中的同一点,以获取每个集群中离集群中心最远的点。
      猜你喜欢
      • 2019-01-14
      • 1970-01-01
      • 2019-11-20
      • 2015-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      • 2019-05-06
      相关资源
      最近更新 更多