转载请注明出处:http://blog.csdn.net/gamer_gyt
博主微博:http://weibo.com/234654758
Github:https://github.com/thinkgamer
公众号:搜索与推荐Wiki
个人网站:http://thinkgamer.github.io
推荐系统在我们的生活中无处不在,比如购物网站,视频音乐网站,新闻网站等,那么推荐系统是如何工作的,他是基于什么方式实现的?可以在《推荐系统开发实战》这本书中进行系统的了解和学习,本篇文章是该系列文章的开篇之作,带领大家认识一下基于最近相似用户的推荐。以下内容摘自于《推荐系统开发实战》
- 嗨,Susan,最近有什么好看的电影吗?
- Thinkgamer,我觉得《芳华》不错,推荐你可以去看下。
这样的场景相信我们会经常遇到,当我们不知道要看哪部电影时,会咨询一下身边的朋友,从他们那里得到一些意见。当我们在咨询别人时,往往会有自己的判断,Thinkgamer喜欢文艺片,他不会去征求喜欢动画片的Jake,但是他会去咨询同样喜欢文艺片的Susan。
基于上边的描述,我们可以总结出UserCF的算法过程:
- 计算用户相似度
- 寻找给定用户最相近的K个用户
- 将K个用户喜欢的且给定用户没有行为的物品推荐给给定用户
简单的讲就是:给用户推荐“和他兴趣相投的其他用户”喜欢的物品。
上图所示是一个基于用户的协同过滤推荐的例子,用户A和用户C同时喜欢电影A和电影C,用户C还喜欢电影D,因此将用户A没有表达喜好的电影D推荐给用户A。
针对上述过程,可以分为以下步骤:
构建用户物品评分表
假设用户与物品所表达的喜好程度(即评分),如下表所示:
用户 | 物品a | 物品b | 物品c | 物品d | 物品e |
---|---|---|---|---|---|
A | 3.0 | 4.0 | 0 | 3.5 | 0 |
B | 4.0 | 0 | 4.5 | 0 | 3.5 |
C | 0 | 3.5 | 0 | 0 | 3 |
D | 0 | 4 | 0 | 3.5 | 3 |
相似度计算
计算用户之间相似度的方法有很多,这里选用的是余弦相似度,如下:
针对用户u和v,上述公式中的参数如下。
- N(u):用户u有过评分的物品集合;
- N(v):用户v有过评分的物品集合;
- Wuv:用户u和用户v的余弦相似度。
结合上表,可以分别求得用户C和其他三个用户的相似度,见下面三公式:
计算推荐结果
用户C进行评分的物品是b和e,接下来计算用户C对物品a、c、d的偏好程度,见下面三公式:
完整代码可参考《推荐系统开发实战》
算法复杂度优化
但是上面的计算存在一个问题——需要计算每一对用户的相似度。代码实现对应的时间复杂度为O(|U|*|U|),U为用户个数。
在实际生产环境中,很多用户之间并没有交集,也就是并没有对同一样物品产生过行为,所以很多情况下分子为0,这样的稀疏数据就没有计算的必要。
上面的代码实现将时间浪费在计算这种用户之间的相似度上,所以这里可以进行优化:
(1)计算出的用户对(u,v);
(2)对其除以分母得到u和v的相似度。
针对以上优化思路,需要两步:
(1)建立物品到用户的倒排表T,表示该物品被哪些用户产生过行为;
(2)根据倒查表T,建立用户相似度矩阵W:
- 在T中,对于每个物品i,设其对应的用户为j、k,
- 在W中,更新对应位置的元素值,W[j][k]=W[j][k]+1,W[k][j]=W[k][j]+1。
以此类推,这样在扫描完倒查表T之后,就能得到一个完整的用户相似度矩阵W了。
这里的W对应的是前面介绍的余弦相似度中的分子部分,然后用W除以分母,便能最终得到两个用户的兴趣相似度。
以上表为例,总共有4个用户,那么要建一个4行4列的倒排表,具体建立过程如下:
(1)由用户的评分数据得到每个物品被哪些用户评价过,如图5-6所示。
(2)建立用户相似度矩阵W,如图5-7所示。
得到的相似度矩阵W对应的是计算两两用户相似度的分子部分,然后除以分母得到的便是两两用户的相似度。
还是以C用户为例。从图5-7可知,A、B用户与C用户相似度计算的分子都为1,D用户与C用户相似度计算的分子部分为2。其他用户与C用户的相似度计算如下:
其中各参数说明如下。
- P(u,i):用户u对物品i的感兴趣程度;
- S(u,K):和用户u兴趣最接近的K个用户;
- N(i):对物品i有过行为的用户集合;
- Wuv:用户u和用户v的兴趣相似度;
- rvi:用户v对物品i的兴趣,即用户对物品的评分。
依据上式,分别计算用户C对物品a、c、d的可能评分:
具体的代码实现可参考:《推荐系统开发实战》一书。
惩罚热门物品
如果两个用户都买过《新华字典》,这并不能说明他们兴趣相同,因为绝大多数中国人都买过《新华字典》。
但如果两个用户都买过《机器学习实战》,那可以认为他们的兴趣比较相似,因为只有研究机器学习的人才可能买这本书。
因此,John S. Breese在论文中提出了式(5.4),根据用户行为计算用户的兴趣相似度:
- 分子中的倒数部分,惩罚了用户u和用户v共同兴趣列表中热门物品,减小了热门物品对用户相似度的影响。
- N(i)是对物品i有过行为的用户集合。物品i越热门,N(i)越大。
对此,修改用户相似度的计算方式,具体的代码实现如函数userSimilarityBest()所示。
具体的代码实现可参考:《推荐系统开发实战》一书。
案例实战
在了解完UserCF的算法原理之后,来开发一个电影推荐系统。这里我们选用的MovieLens数据集,该数据集在《实战》一书中的第三章有详细介绍。
搭建一个推荐系统的步骤包括:
- 准备数据
- 选择算法
- 模型训练
- 效果评估
这里不过多进行介绍,欢迎关注小编图书。
注:文中多次提到的《推荐系统开发实战》是小编近期要上的一本图书,预计本月(7月末)可在京东,当当上线,感兴趣的朋友可以进行关注!