《推荐系统开发实战》之从搭建一个电影推荐系统开始学推荐系统开发实战

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://thinkgamer.blog.csdn.net/article/details/93927941

转载请注明出处: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的算法过程:

  1. 计算用户相似度
  2. 寻找给定用户最相近的K个用户
  3. 将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和其他三个用户的相似度,见下面三公式:

从计算结果来看,D用户与C用户相似度最大。 从表中也可以直接看出,用户D和C都在b和e物品上进行了评分,用户A、B和C也都在b物品上进行了评分。

计算推荐结果

用户C进行评分的物品是b和e,接下来计算用户C对物品a、c、d的偏好程度,见下面三公式:

从上面的计算可以得到,在用户C没有进行评分的物品中倒序排列为a→c→e。这样就可以根据需要取前 K个物品推荐给C用户。

完整代码可参考《推荐系统开发实战》

算法复杂度优化

但是上面的计算存在一个问题——需要计算每一对用户的相似度。代码实现对应的时间复杂度为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数据集,该数据集在《实战》一书中的第三章有详细介绍。

搭建一个推荐系统的步骤包括:

  • 准备数据
  • 选择算法
  • 模型训练
  • 效果评估

这里不过多进行介绍,欢迎关注小编图书。


打开微信扫一扫,关注微信公众号【搜索与推荐Wiki】

注:文中多次提到的《推荐系统开发实战》是小编近期要上的一本图书,预计本月(7月末)可在京东,当当上线,感兴趣的朋友可以进行关注!

没有更多推荐了,返回首页