【问题标题】:How to use precomputed distance matrix in new version of kmeans in sklearn?如何在sklearn的新版本kmeans中使用预先计算的距离矩阵?
【发布时间】:2020-09-24 16:05:50
【问题描述】:

我正在计算自己的距离矩阵,如下所示,我想将其用于聚类。

import numpy as np
from math import pi

#points containing time value in minutes
points = [100, 200, 600, 659, 700]

def convert_to_radian(x):
    return((x / (24 * 60)) * 2 * pi)

rad_function = np.vectorize(convert_to_radian)
points_rad = rad_function(points)

#generate distance matrix from each point
dist = points_rad[None,:] - points_rad[:, None]

#Assign shortest distances from each point
dist[((dist > pi) & (dist <= (2*pi)))] = dist[((dist > pi) & (dist <= (2*pi)))] -(2*pi)
dist[((dist > (-2*pi)) & (dist <= (-1*pi)))] = dist[((dist > (-2*pi)) & (dist <= (-1*pi)))] + (2*pi) 
dist = abs(dist)

#check dist
print(dist)

我的距离矩阵如下所示。

[[0.         0.43633231 2.18166156 2.43909763 2.61799388]
 [0.43633231 0.         1.74532925 2.00276532 2.18166156]
 [2.18166156 1.74532925 0.         0.25743606 0.43633231]
 [2.43909763 2.00276532 0.25743606 0.         0.17889625]
 [2.61799388 2.18166156 0.43633231 0.17889625 0.        ]]

我希望有 2 个集群(例如,集群 1:0,1 和集群 2:2,3,4),使用 kmeans 对上述预先计算的距离矩阵。

当我检查 kmeans 文档时,似乎不推荐使用预先计算的距离 -> precompute_distances='deprecated'

文档链接:https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html

我想知道使用我预先计算的距离矩阵来执行 kmeans 的其他选项是什么。

如果需要,我很乐意提供更多详细信息

【问题讨论】:

    标签: python scikit-learn k-means


    【解决方案1】:

    kMeans 需要到簇的质心(“均值”)的距离(在每次迭代中),而不是点之间的成对距离。所以不像例如k-最近邻,预先计算此数据无济于事*。此处不推荐使用的参数precompute_distances 的含义是先计算所有点中心距离,还是循环计算;详情见PR11950。该 PR 进行了性能增强,无需此参数。

    * 好吧,如果将数据放入像 BallTree 这样的搜索结构(再次参见 k-neighbors)中,我可能会看到可能会加快速度,这样就不需要计算所有的点质心距离;但目前尚不清楚这有多大帮助,并且只有当我认为 k 很大时才会真正有用。无论如何,这里没有这样做。

    【讨论】:

      【解决方案2】:

      如果您最终要将结果提供给 sklearn,您是否真的想使用自己的距离矩阵进行聚类?如果没有,那么您可以通过将点矩阵重塑为 (-1, 1) 数组来直接在数据集上使用 KMeans(numpy 使用 -1 作为一种填充物来返回原始轴长度的重塑)

      import numpy as np
      from math import pi
      from sklearn.cluster import KMeans
      import matplotlib.pyplot as plt
      
      #points containing time value in minutes
      points = [100, 200, 600, 659, 700]
      
      def convert_to_radian(x):
          return((x / (24 * 60)) * 2 * pi)
      
      rad_function = np.vectorize(convert_to_radian)
      points_rad = rad_function(points)
      
      lbls = KMeans(n_clusters=2).fit_predict(points_rad.reshape((-1,1)))
      print(lbls) # prints the following: [0 0 1 1 1]
      
      fig, ax = plt.subplots()
      
      ax.scatter(points_rad, points_rad, c=lbls)
      
      plt.show()
      

      【讨论】:

        猜你喜欢
        • 2014-08-24
        • 2020-10-23
        • 2016-12-06
        • 2015-09-14
        • 1970-01-01
        • 2016-04-09
        • 1970-01-01
        • 1970-01-01
        • 2018-08-05
        相关资源
        最近更新 更多