1、问题描述:在进行sklearn包学习的时候,发现其中的sklearn.metrics.pairwise.pairwise_distance
函数可以实现各种距离度量,恰好我用到了余弦距离,于是就调用了该函数pairwise_distances(train_data, metric='cosine')
但是对其中细节不是很理解,所以自己动手写了个实现。
2、问题解决:
余弦的距离公式:
d
c
o
s
i
n
e
=
1
−
u
⋅
v
∥
u
∥
⋅
∥
v
∥
d_{cosine} = 1 - \frac{u \cdot v }{\lVert u \rVert \cdot \lVert v \rVert}
dcosine=1−∥u∥⋅∥v∥u⋅v
# 导入必要的包
from math import sqrt
import numpy as np
# d是数据
test_similarity = np.dot(d, d.T)
n_users = d.shape[0]
def normal_l2(u, v):
"""
计算二范数
"""
norm_l2_u = sqrt(np.dot(u,u))
norm_l2_v = sqrt(np.dot(v,v))
return norm_l2_u * norm_l2_v
for i in range(n_users):
for j in range(n_users):
test_similarity[i][j] /= normal_l2(d[i], d[j])
# 下面和sklearn源码一致
test_similarity *= -1
test_similarity += 1
# 将结果进行截断,不然会有负值(其实是0)
np.clip(test_similarity, 0, 2, out=test_similarity)
# 将结果变成普通的小数表示,不加这一步则会得到科学记数法的表示
test_similarity[np.diag_indices_from(test_similarity)] = 0.0