余弦相似度

时间:2017-03-17 20:01:10

标签: python numpy scikit-learn similarity cosine-similarity

我正在阅读并遇到了这个公式:

enter image description here

该公式用于余弦相似性。我认为这看起来很有趣,我创建了一个numpy数组,其user_id为row,item_id为column。例如,让M成为这个矩阵:

M = [[2,3,4,1,0],[0,0,0,0,5],[5,4,3,0,0],[1,1,1,1,1]] 

此处,矩阵内的条目是人u根据行i和列u向项i提供的评分。我想计算项(行)之间的这个矩阵的余弦相似度。我认为这应该产生5 x 5矩阵。我试着做

df = pd.DataFrame(M)
item_mean_subtracted = df.sub(df.mean(axis=0), axis=1)
similarity_matrix = item_mean_subtracted.fillna(0).corr(method="pearson").values

但是,这似乎不对。

1 个答案:

答案 0 :(得分:3)

以下是调整余弦相似度的可能实现:

import numpy as np
from scipy.spatial.distance import pdist, squareform

M = np.asarray([[2, 3, 4, 1, 0], 
                [0, 0, 0, 0, 5], 
                [5, 4, 3, 0, 0], 
                [1, 1, 1, 1, 1]])

M_u = M.mean(axis=1)
item_mean_subtracted = M - M_u[:, None]
similarity_matrix = 1 - squareform(pdist(item_mean_subtracted.T, 'cosine'))

<强>说明:

  • 我正在利用NumPy broadcasting来减去平均值。
  • 如果M是稀疏矩阵,您可以执行以下操作:M.toarray()
  • 来自docs
      

    Y = pdist(X,'余弦')
      计算向量u和v之间的余弦距离,
      1 - u⋅v/(|| u || 2 || v || 2
      其中|| * || 2 是其参数*的2范数,而u⋅v是u和v的点积。

  • 通过T方法执行数组转置。

<强>演示:

In [277]: M_u
Out[277]: array([ 2. ,  1. ,  2.4,  1. ])

In [278]: item_mean_subtracted
Out[278]: 
array([[ 0. ,  1. ,  2. , -1. , -2. ],
       [-1. , -1. , -1. , -1. ,  4. ],
       [ 2.6,  1.6,  0.6, -2.4, -2.4],
       [ 0. ,  0. ,  0. ,  0. ,  0. ]])

In [279]: np.set_printoptions(precision=2)

In [280]: similarity_matrix
Out[280]: 
array([[ 1.  ,  0.87,  0.4 , -0.68, -0.72],
       [ 0.87,  1.  ,  0.8 , -0.65, -0.91],
       [ 0.4 ,  0.8 ,  1.  , -0.38, -0.8 ],
       [-0.68, -0.65, -0.38,  1.  ,  0.27],
       [-0.72, -0.91, -0.8 ,  0.27,  1.  ]])