余弦相似度优化实现

cosine similarity optimized implementation

我试图理解这段优化代码,以找到用户矩阵之间的余弦相似度。

def fast_similarity(ratings,epsilon=1e-9):
    # epsilon -> small number for handling dived-by-zero errors
    sim = ratings.T.dot(ratings) + epsilon
    norms = np.array([np.sqrt(np.diagonal(sim))])
    return (sim / norms / norms.T)

如果收视率=

           items           
     u  [
     s    [1,2,3]
     e    [4,5,6]
     r    [7,8,9] 
     s  ]

nomrs 将等于 = [1^2 + 5^2 + 9^2]

但是为什么要写sim/norms/norms.T来计算余弦相似度呢? 感谢任何帮助。

通过代码我们得到:

first

这意味着,在 sim 矩阵的对角线上,我们得到了每一列相乘的结果。

如果你想使用一个简单的矩阵,你可以尝试一下:

second

而且你可以很容易地检查这个 gram matrix(这就是这个矩阵乘积的命名方式)有这个 属性。

现在代码定义了 norms,它只是一个数组,采用我们的 gram matrix 的对角线,并在其中的每个元素上应用一个 sqrt。

这将为我们提供一个包含每列标准值的数组:

third

所以基本上 norms 向量包含 result 矩阵每一列的范数值。

一旦我们拥有所有这些数据,我们就可以评估这些用户之间的余弦相似度,所以我们知道余弦相似度的评估方式如下:

forth

请注意: fifth

所以我们的相似度将是:

six

所以我们只需要用我们的代码变量替换这些术语就可以得到:

seven

这解释了为什么你有这行代码:

return sim / norms / norms.T

编辑: 由于我似乎不清楚,所以每次我在这个答案中谈论矩阵乘法时,我都指的是两个矩阵的 DOT PRODUCT

This actually means that when it's written A*B we actually develop and solve as A.T * B