基于物品的协同过滤算法itemCF原理及python代码实现
基于物品的协同过滤算法主要分为两步:
(1)计算物品之间的相似度;
(2)根据物品之间的相似度以及⽤户历史⾏为给⽤户⽣成推荐列表。
计算物品之间的相似度公式:
|N(i)|是喜欢物品i的⽤户数,所以分⼦是同时喜欢物品i和物品j的⽤户数。上述公式可以理解为喜欢物品i的⽤户中有多少⽐例的⽤户也喜欢物品j。分母惩罚了物品j的权重,可以避免推荐出热门的物品,从⽽使推荐系统更致⼒于挖掘长尾信息。
⽤itemCF算法计算物品的相似⾸先度时,建⽴⽤户-物品倒排表,然后对于每个⽤户,将他物品列表中的物品两两在共现矩阵C中加1.详细代码如下所⽰:
#建⽴物品倒排表,计算物品相似度
def itemCF(user_dict):
N=dict()
C=defaultdict(defaultdict)
W=defaultdict(defaultdict)
for key in user_dict:
for i in user_dict[key]:
if i[0] not in N.keys(): #i[0]表⽰movie_id
python新手代码及作用N[i[0]]=0
N[i[0]]+=1              #N[i[0]]表⽰评论过某电影的⽤户数
for j in user_dict[key]:
if i==j:
continue
if j[0] not in C[i[0]].keys():  ##这⾥⼀开始⽤的是if j[0] not in C[i[0]].keys()是不对的;感谢评论区同学的指正。⼤家下载代码后要改过来。
C[i[0]][j[0]]=0
C[i[0]][j[0]]+=1      #C[i[0]][j[0]]表⽰电影两两之间的相似度,eg:同时评论过电影1和电影2的⽤户数
for i,related_item in C.items():
for j,cij in related_item.items():
W[i][j]=cij/math.sqrt(N[i]*N[j])
return W
在得到物品之间的相似度后,itemCF算法通过如下公式计算⽤户u对⼀个物品j的兴趣:
这⾥N(u)是⽤户喜欢的物品的集合,S(j,K)是和物品j最相似的K个物品的集合,w是物品j和i的相似度,r是⽤户u对物品i的兴趣。该公式的含义是,和⽤户历史上感兴趣的物品越相似的物品,越有可能在⽤户的推荐列表中获得⽐较⾼的排名。(这是《推荐系统实践》的公式)
按我对其代码的理解,公式写成下⾯形式可能更好理解:
S(i,K)是和物品i最相似的K个物品的集合,对于不同的i,物品j都必须满⾜与i的相似度在前K个,否则跳过该物品i。最后得到的是物品j在⽤户喜欢的物品中的加权和,再进⾏排序即可向⽤户推荐其最感兴趣的物品。(这⾥解释得有点乱,具体可以看我的,当然也有可能是我理解错误,望指正)
该公式的详细代码如下所⽰:
#结合⽤户喜好对物品排序
def recommondation(user_id,user_dict,K):
rank=defaultdict(int)
l=list()
W=itemCF(user_dict)
for i,score in user_dict[user_id]: #i为特定⽤户的电影id,score为其相应评分
for j,wj in sorted(W[i].items(),key=itemgetter(1),reverse=True)[0:K]: #sorted()的返回值为list
if j in user_dict[user_id]:
continue
rank[j]+=score*wj #先出⽤户评论过的电影集合,对每⼀部电影id,假设其中⼀部电影id1,出与该电影最相似的K部电影,计算出在id1下⽤户对每部电影的兴    l=sorted(rank.items(),key=itemgetter(1),reverse=True)[0:10]
return l
结果如下:
第⼀列为⽤户Id,每个⽤户评论过多部电影,所以这⾥展⽰的不是具体的电影名称,⽽是具体的某⼀⽤户,第⼆列为我们为该⽤户推荐的⼗
部电影。
⼲货:附上,开发环境是Python2.7,代码包含详细解释,有兴趣的童鞋可以了解⼀下,有问题可以和我交流。
参考:
《推荐系统实践》作者: 项亮

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。