`cosine` 度量在 sklearn 聚类算法中如何工作?
How does `cosine` metric works in sklearn's clustering algorithoms?
我对 cosine
指标在 sklearn 的聚类算法中的工作方式感到困惑。
例如,DBSCAN有一个参数eps
,它指定了聚类时的最大距离。然而,更大的余弦相似度意味着两个向量更接近,这与我们的 distance
概念正好相反。
我发现 pairwise_metric 中有 cosine_similarity
和 cosine_distance
(只有 1-cos()
),当我们指定指标为 cosine
时,我们使用cosine_similarity
。
那么,在聚类的时候,DBSCAN是如何比较cosine_similarity和@param eps
来判断两个向量是否有相同的label的呢?
一个例子
import numpy as np
from sklearn.cluster import DBSCAN
samples = [[1, 0], [0, 1], [1, 1], [2, 2]]
clf = DBSCAN(metric='cosine', eps=0.1)
result = clf.fit_predict(samples)
print(result)
它输出[-1, -1, -1, -1] 这意味着这四个点在同一个簇中
然而,
点对 [1,1], [2, 2]
,
- 它的 cosine_similarity 是 4/(4) = 1,
- 余弦距离将为 1-1 = 0,因此它们在同一簇中
点对[1,1], [1,0]
,
- 它的 cosine_similarity 是 1/sqrt(2),
- 余弦距离将是1-1/sqrt(2) = 0.29289321881345254,这个距离比我们的
eps
0.1大,为什么DBSCAN把它们聚类到同一个簇中?
感谢@Stanislas Morbieu 的回答,我终于明白了 cosine
指标的意思是 cosine_distance
即 1-cosine
DBSCAN在scikit-learn中的实现依赖NearestNeighbors (see the implementation of DBSCAN).
这里是一个例子,看看它如何与余弦度量一起工作:
import numpy as np
from sklearn.neighbors import NearestNeighbors
samples = [[1, 0], [0, 1], [1, 1], [2, 2]]
neigh = NearestNeighbors(radius=0.1, metric='cosine')
neigh.fit(samples)
rng = neigh.radius_neighbors([[1, 1]])
print([samples[i] for i in rng[1][0]])
输出[[1, 1], [2, 2]]
,即半径0.1
.
距离[1, 1]
最近的点
所以在 DBSCAN 中余弦距离小于 eps
的点往往在同一个簇中。
DBSCAN的参数min_samples
起着重要的作用。由于默认设置为5
,没有点可以认为是核心点。
设置为1
,示例代码:
import numpy as np
from sklearn.cluster import DBSCAN
samples = [[1, 0], [0, 1], [1, 1], [2, 2]]
clf = DBSCAN(metric='cosine', eps=0.1, min_samples=1)
result = clf.fit_predict(samples)
print(result)
输出 [0 1 2 2]
这意味着 [1, 1] 和 [2, 2] 在同一个簇中(编号 2)。
顺便说一句,输出 [-1, -1, -1, -1]
并不意味着点在同一个簇中,而是所有点都不在簇中。
我对 cosine
指标在 sklearn 的聚类算法中的工作方式感到困惑。
例如,DBSCAN有一个参数eps
,它指定了聚类时的最大距离。然而,更大的余弦相似度意味着两个向量更接近,这与我们的 distance
概念正好相反。
我发现 pairwise_metric 中有 cosine_similarity
和 cosine_distance
(只有 1-cos()
),当我们指定指标为 cosine
时,我们使用cosine_similarity
。
那么,在聚类的时候,DBSCAN是如何比较cosine_similarity和@param eps
来判断两个向量是否有相同的label的呢?
一个例子
import numpy as np from sklearn.cluster import DBSCAN samples = [[1, 0], [0, 1], [1, 1], [2, 2]] clf = DBSCAN(metric='cosine', eps=0.1) result = clf.fit_predict(samples) print(result)
它输出[-1, -1, -1, -1] 这意味着这四个点在同一个簇中
然而,
点对
[1,1], [2, 2]
,- 它的 cosine_similarity 是 4/(4) = 1,
- 余弦距离将为 1-1 = 0,因此它们在同一簇中
点对
[1,1], [1,0]
,- 它的 cosine_similarity 是 1/sqrt(2),
- 余弦距离将是1-1/sqrt(2) = 0.29289321881345254,这个距离比我们的
eps
0.1大,为什么DBSCAN把它们聚类到同一个簇中?
感谢@Stanislas Morbieu 的回答,我终于明白了 cosine
指标的意思是 cosine_distance
即 1-cosine
DBSCAN在scikit-learn中的实现依赖NearestNeighbors (see the implementation of DBSCAN).
这里是一个例子,看看它如何与余弦度量一起工作:
import numpy as np
from sklearn.neighbors import NearestNeighbors
samples = [[1, 0], [0, 1], [1, 1], [2, 2]]
neigh = NearestNeighbors(radius=0.1, metric='cosine')
neigh.fit(samples)
rng = neigh.radius_neighbors([[1, 1]])
print([samples[i] for i in rng[1][0]])
输出[[1, 1], [2, 2]]
,即半径0.1
.
[1, 1]
最近的点
所以在 DBSCAN 中余弦距离小于 eps
的点往往在同一个簇中。
DBSCAN的参数min_samples
起着重要的作用。由于默认设置为5
,没有点可以认为是核心点。
设置为1
,示例代码:
import numpy as np
from sklearn.cluster import DBSCAN
samples = [[1, 0], [0, 1], [1, 1], [2, 2]]
clf = DBSCAN(metric='cosine', eps=0.1, min_samples=1)
result = clf.fit_predict(samples)
print(result)
输出 [0 1 2 2]
这意味着 [1, 1] 和 [2, 2] 在同一个簇中(编号 2)。
顺便说一句,输出 [-1, -1, -1, -1]
并不意味着点在同一个簇中,而是所有点都不在簇中。