我想将DBSCAN与度量sklearn.metrics.pairwise.cosine_similarity一起使用以将余弦相似度接近1(即,其向量(来自“ the”原点)的向量平行或几乎平行)的点聚类。
问题:
eps是两个样本之间的最大距离,DBSCAN会将它们视为在同一邻域中-这意味着,如果两个点之间的距离小于或等于,则这些点为被视为邻居;
但是
sklearn.metrics.pairwise.cosine_similarity发出介于-1和1之间的值,并且如果两个点之间的距离介于0.75和1之间,则我希望DBSCAN将两个点视为相邻点-即大于或等于 0.75。
我看到两种可能的解决方案:
将一系列值传递给DBSCAN的eps参数,例如eps = [0.75,1]
将值eps = -0.75传递给DBSCAN,但(以某种方式)强制其使用由sklearn.metrics.pairwise.cosine_similarity吐出的余弦相似度矩阵的负值
我不知道如何实现这两个。
任何指导将不胜感激!
答案 0 :(得分:1)
DBSCAN
有一个metric
关键字参数。文档字符串:
metric:字符串或可调用 在计算实例中实例之间的距离时使用的度量 特征数组。如果metric是字符串或可调用,则必须是以下之一 metrics.pairwise.calculate_distance为其允许的选项 指标参数。 如果度量是“预先计算的”,则假定X是距离矩阵,并且 必须是正方形。 X可能是一个稀疏矩阵,在这种情况下,只有“非零” 元素可能被视为DBSCAN的邻居。
因此,最简单的操作可能是使用余弦相似度作为距离度量标准来预先计算距离矩阵,并对距离矩阵进行预处理,使其适合您定制的距离标准(可能类似于D = np.abs(np.abs(CD) -1)
,其中CD是您的余弦距离矩阵),然后将metric
设置为precomputed
,并为D
(即数据)传递预先计算的距离矩阵X
。
例如:
#!/usr/bin/env python
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.cluster import DBSCAN
total_samples = 1000
dimensionality = 3
points = np.random.rand(total_samples, dimensionality)
cosine_distance = cosine_similarity(points)
# option 1) vectors are close to each other if they are parallel
bespoke_distance = np.abs(np.abs(cosine_distance) -1)
# option 2) vectors are close to each other if they point in the same direction
bespoke_distance = np.abs(cosine_distance - 1)
results = DBSCAN(metric='precomputed', eps=0.25).fit(bespoke_distance)
答案 1 :(得分:0)
A)签出通用DBSCAN,它在相似性方面也可以正常工作。有了余弦,sklearn还是会变慢。
B)您可以轻松使用:余弦距离= 1-余弦相似度。但这很可能导致sklearn实现在O(n²)中运行。
C)您甚至可以通过-cosinesimilarity
作为预先计算的距离矩阵,并使用-0.75作为eps。
d)仅制作一个二进制距离矩阵(但是在O(n²)存储器中很慢),其中余弦相似度的距离= 0大于阈值,否则为0。然后使用eps = 0.5的DBSCAN。仅当相似度>阈值时,才能显示距离
答案 2 :(得分:0)
一些选择:
dist = np.abs(cos_sim - 1)
在这里接受了答案dist = np.arccos(cos_sim) / np.pi
https://math.stackexchange.com/a/3385463/816178 dist = 1 - (sim + 1) / 2
https://math.stackexchange.com/q/3241174/816178 我发现它们在此应用程序中的工作原理都是一样的(在层次集群中预先计算的距离;我也遇到了麻烦)。据我了解,#2是数学上更正确的方法。保持角距离。