谈谈余弦相似度

基于余弦定理计算相似度的应用很多,比如推荐系统中的协同过滤,计算文本的相似性等等。它用计算两者空间向量的夹角来表示两者的相似性。

先看一下余弦定理的公式:
$$
W_{UV}=\frac{∑U_iV_i}{\sqrt{∑U_i2}\sqrt{∑V_i2}}
$$
上诉公式表示UV两者的相似度,Ui表示U在i纬度的数值。

在用户行为数据(用户只有操作和未操作两种状态,也就是0,1)中公式可以表示为:
$$
W_{UV}=\frac{|N(u)\bigcap N(v)|}{\sqrt{|N(U)||N(V)|}}
$$
我们默认数据是用户行为数据,如用户A操作了物品a表示为:A a

我们的数据源是log日志:

A a

A c

B c

B b

C a

….

把数据整理成一个user_item表

A a c

B c b

C a

….

我们发现这个矩阵是稀疏的,如果两两算相似性,有操作交集是0的情况,复杂度太高。可以换一种思路,现求得交集不为零的用户对,再除以公式的分母。,这就需要一个倒排表了。

a A C

c A B

b B

...

下面是python实现的例子,输入的是用户行为数据

(A,a),

(A ,c),

(B, c),

(B, b),

(C, a)

….

import math
def UserSimilarity(train):
    user_item=dict()
    item_user=dict()
    N=dict()
    for line in train:
        u=line[0]
        i=line[2]
        if u not in user_item:
            user_item[u]=set()
        user_item[u].add(i)
        if u not in N:
            N[u]=0
        N[u]+=1
        if i not in item_user:
            item_user[i]=set()
        item_user[i].add(u)
    C=dict()
    for u in user_item:
        C[u]=dict()
        for i in user_item[u]:
            for v in item_user[i]:
                if u==v:
                    continue
                C[u][v]+=1
    for u in C:
        for v in C[u]:
            C[u][v]=C[u][v]/math.sqrt(N[u]*N[v])
    return C
posted @ 2017-06-14 20:34  马天池  阅读(1573)  评论(0)    收藏  举报