我正在通过blog中的示例来理解推荐系统中使用的协同过滤方法。我遇到了余弦相似性,表示为
在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 )
问题
(sim / norms / norms.T )
如何等于sim(u,u`)
提前感谢您的时间 - 如果我错过了任何内容,请在评论中过度强调或强调一个特定的要点。
答案 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'
计算此值,并将结果作为矩阵返回。为此,它:
sim
(上面的矩阵s
)计算为ratings.dot(ratings.T)
f
)为np.sqrt(np.diagonal(sim))
s
进行行/列缩放,然后将其表示为二维数组norms = np.array([np.sqrt(np.diagonal(sim))])
(请注意帖子中缺少的[]
)< / LI>
s_{uu'}/f{u}/f{u'}
计算为sim / norms / norms.T
。此处,由于norms
具有形状(1, num_of_users)
,因此第一个分区执行列缩放,而norms.T
分割则缩放行。