【问题标题】:Get nearest point to centroid, scikit-learn?获取离质心最近的点,scikit-learn?
【发布时间】:2014-03-06 19:46:27
【问题描述】:

我正在使用 K-means 来解决聚类问题。我试图找到最接近质心的数据点,我相信它被称为中心点。

有没有办法在 scikit-learn 中做到这一点?

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    这不是 medoid,但您可以尝试以下方法:

    >>> import numpy as np
    >>> from sklearn.cluster import KMeans
    >>> from sklearn.metrics import pairwise_distances_argmin_min
    >>> X = np.random.randn(10, 4)
    >>> km = KMeans(n_clusters=2).fit(X)
    >>> closest, _ = pairwise_distances_argmin_min(km.cluster_centers_, X)
    >>> closest
    array([0, 8])
    

    数组closest 包含X 中最接近每个质心的点的索引。所以X[0]X中离质心0最近的点,X[8]是离质心1最近的点。

    【讨论】:

    • 我认为这个答案的问题在下面得到了正确解决。 pairwise_distances_argmin_min 可能会返回重复项
    【解决方案2】:

    我尝试了上述答案,但结果出现重复。 无论聚类结果如何,上面都会找到最近的数据点。因此它可以返回同一个集群的副本。

    如果您想在中心指示的同一集群中找到最接近的数据,试试这个。

    此解决方案给出的数据点来自所有不同的集群,并且返回的数据点的数量与集群的数量相同。

    import numpy as np
    from sklearn.cluster import KMeans
    from sklearn.metrics import pairwise_distances_argmin_min
    
    # assume the total number of data is 100
    all_data = [ i for i in range(100) ]
    tf_matrix = numpy.random.random((100, 100))
    
    # set your own number of clusters
    num_clusters = 2
    
    m_km = KMeans(n_clusters=num_clusters)  
    m_km.fit(tf_matrix)
    m_clusters = m_km.labels_.tolist()
    
    centers = np.array(m_km.cluster_centers_)
    
    closest_data = []
    for i in range(num_clusters):
        center_vec = centers[i]
        data_idx_within_i_cluster = [ idx for idx, clu_num in enumerate(m_clusters) if clu_num == i ]
    
        one_cluster_tf_matrix = np.zeros( (  len(data_idx_within_i_cluster) , centers.shape[1] ) )
        for row_num, data_idx in enumerate(data_idx_within_i_cluster):
            one_row = tf_matrix[data_idx]
            one_cluster_tf_matrix[row_num] = one_row
    
        closest, _ = pairwise_distances_argmin_min(center_vec, one_cluster_tf_matrix)
        closest_idx_in_one_cluster_tf_matrix = closest[0]
        closest_data_row_num = data_idx_within_i_cluster[closest_idx_in_one_cluster_tf_matrix]
        data_id = all_data[closest_data_row_num]
    
        closest_data.append(data_id)
    
    closest_data = list(set(closest_data))
    
    assert len(closest_data) == num_clusters
    

    【讨论】:

    • pmids_idx_in_i_clusterdata_idx_in_i_cluster 是什么? (两人身份不明)
    【解决方案3】:

    您要实现的基本上是矢量量化,但是是“反向”的。 Scipy 有一个非常优化的功能,比提到的其他方法快得多。输出与 pairwise_distances_argmin_min() 相同。

        from scipy.cluster.vq import vq
    
        # centroids: N-dimensional array with your centroids
        # points:    N-dimensional array with your data points
    
        closest, distances = vq(centroids, points)
    

    当你用非常大的数组执行它时,最大的不同是,我用一个包含 100000+ 点和 65000+ 质心的数组执行它,这种方法比 pairwise_distances_argmin_min() 快 4 倍scikit,如下图:

         start_time = time.time()
         cl2, dst2 = vq(centroids, points)
         print("--- %s seconds ---" % (time.time() - start_time))
         --- 32.13545227050781 seconds ---
    
         start_time = time.time()
         cl2, dst2 = pairwise_distances_argmin_min(centroids, points)
         print("--- %s seconds ---" % (time.time() - start_time))
         --- 131.21064710617065 seconds ---
    

    【讨论】:

      猜你喜欢
      • 2018-09-06
      • 2016-11-16
      • 2018-07-02
      • 2021-11-04
      • 2017-02-07
      • 1970-01-01
      • 2019-10-20
      • 1970-01-01
      • 2017-03-10
      相关资源
      最近更新 更多