无法理解余弦相似性的python函数

时间:2018-04-26 08:27:36

标签: python numpy math linear-algebra cosine-similarity

我正在通过blog中的示例来理解推荐系统中使用的协同过滤方法。我遇到了余弦相似性,表示为

enter image description here

在python中使用numpy将其写为

def similarity(ratings, kind='user', epslion=1e-9):
      if kind == 'user' :
         sim = ratings.dot(ratings.T)
      elif (kind=='item'):
          sim = ratings.T.dot(ratings) + epslion
      norms = np.array([np.sqrt(np.diagonal(sim))])

      return  (sim / norms / norms.T )
  

问题

  1. 代码中规范计算背后的数学是什么
  2. 等式中(sim / norms / norms.T )如何等于sim(u,u`)
  3. 提前感谢您的时间 - 如果我错过了任何内容,请在评论中过度强调或强调一个特定的要点。

1 个答案:

答案 0 :(得分:3)

评级存储在numpy矩阵ratings中,其中行对应于用户(索引u),而列对应于项目(索引i)。由于您要计算sim(u, u'),即用户之间的相似度,我们假设低于kind = 'user'

现在,让我们首先看一下没有平方根缩放因子的r_{ui}r_{u'i}。该表达式总结为i,可以解释为r的矩阵乘法与r的转置,即:

\sum_i r_{ui}r_{u'i} = \sum_i r_{ui}(r^T)_{iu'} =: s_{uu'}

如上所述,我们将结果矩阵表示为s(代码中的变量sim)。根据定义,此矩阵是对称的,其行/列标有“用户”索引u/u'

现在,缩放“因子”f_{u} := \sqrt\sum_i r^2_{ui}实际上是一个用u索引的向量(其中每个项都是矩阵r的相应行的欧几里德范数)。但是,在构建s_{uu'}之后,我们可以看到f_{u}只不过是\sqrt s_{uu}

最后,感兴趣的相似性因子是s_{uu'}/f{u}/f{u'}。发布的代码为所有索引u/u'计算此值,并将结果作为矩阵返回。为此,它:

  1. sim(上面的矩阵s)计算为ratings.dot(ratings.T)
  2. 获取其对角线的平方根(上面的向量f)为np.sqrt(np.diagonal(sim))
  3. 以有效的方式对s进行行/列缩放,然后将其表示为二维数组norms = np.array([np.sqrt(np.diagonal(sim))])(请注意帖子中缺少的[])< / LI>
  4. 最后,矩阵s_{uu'}/f{u}/f{u'}计算为sim / norms / norms.T。此处,由于norms具有形状(1, num_of_users),因此第一个分区执行列缩放,而norms.T分割则缩放行。