余弦相似度
基于余弦定理计算相似度的应用很多,比如推荐系统中的协同过滤,计算文本的相似性等等。它用计算两者空间向量的夹角来表示两者的相似性。
先看一下余弦定理的公式:
WUV=∑UiVi∑U2i‾‾‾‾‾‾√∑V2i‾‾‾‾‾‾√
上诉公式表示UV两者的相似度,Ui表示U在i纬度的数值。
在用户行为数据(用户只有操作和未操作两种状态,也就是0,1)中公式可以表示为:
WUV=|N(u)⋂N(v)||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