如何在sklearn的kmeans新版本中使用预先计算的距离矩阵?

时间:2020-06-05 12:36:02

标签: python scikit-learn k-means

我正在按以下方式计算自己的距离矩阵,并希望将其用于聚类。

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个使用kmeans的聚类(例如聚类1:0,1和聚类2:2,3,4)。

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

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

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

很高兴在需要时提供更多详细信息

2 个答案:

答案 0 :(得分:1)

kMeans需要到聚类的质心的距离(“均值”)(每次迭代),而不是点之间的成对距离。所以不像k近邻,预先计算此数据将无济于事*。 precompute_distances处不推荐使用的参数的含义是,是先计算所有点中心距离还是在循环中计算所有点中心距离。有关详细信息,请参见PR11950。该PR增强了性能,从而消除了对该参数的需要。

*好吧,我可能会发现,如果将数据放入BallTree之类的搜索结构(同样请参见k邻域)中,可能会加快速度,从而不必计算所有的点质心距离。但尚不清楚这有多大帮助,并且只有在我认为k很大时才真正有用。无论如何,这里没有做。

答案 1 :(得分:1)

如果您最终将结果馈送给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()

[![enter image description here][1]][1]


  [1]: https://i.stack.imgur.com/RTC5k.png
相关问题