用sklearn对弧度距离矩阵进行DBSCAN?

Posted

技术标签:

【中文标题】用sklearn对弧度距离矩阵进行DBSCAN?【英文标题】:Conduct DBSCAN on radian distance matrix with sklearn? 【发布时间】:2016-10-08 04:01:55 【问题描述】:

我希望对几个时间戳(以分钟为单位)进行聚类。 所以到目前为止我所做的是:

1) 将点转换为弧度

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

2) 生成距离矩阵

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

3) 分配到每个点的最短距离

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)

现在我想在距离矩阵上使用 DBSCAN,如何将其聚类到弧度距离?

谢谢!

【问题讨论】:

我认为你的距离矩阵不是距离矩阵。 为什么要将简单的线性测量转换为角度? (顺便说一句,大多数时钟的表盘上都是 12 小时,而不是 24 小时) @Anony-Mousse 它是!我设法弄明白了! @TomMorris 我想区分早上 9 点和晚上 9 点 【参考方案1】:

好的,经过大量挖掘后,我意识到我可以简单地将 DBSCAN 指标设置为“预计算”,使用 .fit() 方法并传入我的距离矩阵。对于那些感兴趣的人,这里是来源:

import numpy as np
from math import pi
from sklearn.cluster import DBSCAN

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

#using default values, set metric to 'precomputed'
db = DBSCAN(eps=((100 / (24*60)) * 2 * pi ), min_samples = 2, metric='precomputed')

#check db
print(db)

db.fit(dist)

#get labels
labels = db.labels_

#get number of clusters
no_clusters = len(set(labels)) - (1 if -1 in labels else 0)

print('No of clusters:', no_clusters)
print('Cluster 0 : ', np.nonzero(labels == 0)[0])
print('Cluster 1 : ', np.nonzero(labels == 1)[0])

输出:

[[ 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.        ]]

DBSCAN(algorithm='auto', eps=0.4363323129985824, leaf_size=30,
metric='precomputed', min_samples=2, p=None, random_state=None)

No of clusters: 2
Cluster 0 :  [0 1]
Cluster 1 :  [2 3 4]

【讨论】:

以上是关于用sklearn对弧度距离矩阵进行DBSCAN?的主要内容,如果未能解决你的问题,请参考以下文章

如何在sklearn dbscan中使用多个内核?

使用 sklearn DBSCAN 模型对新条目进行分类

无监督学习小记(参考)

sklearn 的标准 DBSCAN 怎么跑得这么快?

scikit-learn 中的 DBSCAN(仅使用指标)

DBSCAN 集群甚至无法处理 40k 数据,但使用 python 和 sklearn 处理 10k 数据