本文暂时分为三部分:
(一)基于Spark MLlib平台和基于模型的协同过滤算法的电影推荐系统(一)
→ 协同过滤算法概述&&基于模型的协同过滤的算法思想
(二)基于Spark MLlib平台和基于模型的协同过滤算法的电影推荐系统(二)
→ 代码实现
(三)基于Spark MLlib平台和基于模型的协同过滤算法的电影推荐系统(二)
→作业里的拓展
本文基于Spark MLlib平台实现一个向用户推荐电影的简单应用。其中,主要包括三部分内容:
一、协同过滤算法概述三、实时推荐架构分析
关于协同过滤的一个最经典的例子就是看电影,有时候不知道哪一部电影是我们喜欢的或者评分比较高的,那么通常的做法就是问问周围的朋友,看看最近有什么好的电影推荐。在问的时候,都习惯于问跟自己口味差不多的朋友,这也是协同过滤的核心思想:在海量数据中挖掘出小部分与你品味类似的用户,在协同过滤中,这些用户成为邻居,然后根据他们喜欢的东西组织成一个排序的目录推荐给你。
所以就有如下两个核心问题:
(1)如何确定一个用户是否与你有相似的品味?
(2)如何将邻居们的喜好组织成一个排序目录?
协同过滤算法的出现标志着推荐系统的产生,协同过滤算法包括:
1)基于用户(UserCF)的协同过滤算法
2)基于商品(ItemCF)的协同过滤算法
3)基于模型(ModelCF)的协同过滤算法
1、基于用户(UserCF)---基于用户相似性
基于用户的协同过滤,通过不同用户对物品的评分来评测用户之间的相似性,基于用户之间的相似性做出推荐。举个例子:
如图,有三个用户A、B、C,四个物品A、B、C、D,需要向用户A推荐物品。
这里,由于用户A和用户C都买过物品A和物品C,所以,我们认为用户A和用户C非常相似,同时,用户C又买过物品D,那么就需要给A用户推荐物品D。
计算上,将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,找到K邻居后,根据邻居的相似度权重以及他们对物品的偏好,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表作为推荐。
【可参考一个参加完阿里大数据竞赛的人写的《基于用户的协同过滤(UserCollaborativeFilter)C++实现》的文章
举个例子:
如图,有三个用户A、B、C和三件物品A、B、C,需要向用户C推荐物品。介绍完基于用户的协同过滤和基于物品的协同过滤,现在进入正题,介绍基于模型的协同过滤算法:
基于模型(ModelCF)有三种:
1)最近邻模型:基于距离的协同过滤算法
2)矩阵分解模型:基于矩阵分解的模型 Latent Factor Mode(SVD)
3)图模型:社会网络图模型(Graph)
关于1)和3),本文不赘述,但附上一篇还凑活的链接
【基于邻域的算法是推荐系统中最基本的算法 可参考《推荐系统实践--基于用户的协同过滤算法》 网址为:http://www.tuicool.com/articles/6vqyYfR】
下面开始对 “ 2)矩阵分解模型:基于矩阵分解的模型 Latent Factor Mode(SVD)”的讲解:
基于模型的协同过滤推荐就是基于样本的用户喜好信息,训练一个推荐模型,然后根据实时的用户喜好的信息进行预测,计算推荐。
算法如图:Spark MLlib当前支持基于模型的协同过滤,其中用户和商品通过一小组隐性因子进行表达,并且这些因子也用于预测缺失的元素。
MLlib使用交替最小二乘法(ALS)来学习这些隐性因子。
(关于模型和算法结构 这部分待补充)
补充:
ALS算法
1含义
在现实中用户-物品-评分矩阵是及其大的,用户消费有限,对单个用户来说,消费的物品的非常有限的,产生的评分也是比较少的,这样就造成了用户-物品矩阵有大量的空值。
假定用户的兴趣只受少数因素的影响,所以用户-物品矩阵可以分解为用户的特征向量矩阵和物品的特征向量矩阵(降维了)。用户的特征向量距离表示用户的兴趣(U),物品的特征向量矩阵代表用户的特点(V),合起来(内积)表示用户对物品的特点的兴趣,也就是喜好程度。
M=U*V
2协同过滤矩阵分解算法
2.1奇异值分解(SVD)
矩阵的奇异值分解是最简单的一种矩阵分解算法,主要是在U*V中间加了个一个奇异值矩阵,公式如下:
M=U*(奇异值矩阵)*(V的共轭)
奇异值矩阵是对角矩阵,奇异值分解的缺点(没试过不知道,书上说的),1不允许分解矩阵有null值,需要进行填分,2如果填分,又有两个问题:1增加数据量,增加算法复杂度,2简单粗暴的填分方式会导致数据失真,如果将null值设置为0,那么会导致过度学习问题。
奇异值分解方式,感觉用的不多,我自己接触的话。
2.2正则化矩阵分解
加入正则化是为了解决稀疏矩阵可能过学习问题,评价矩阵分解是RMSE,通过最小化RMSE来学习用户特征矩阵U和物品特征矩阵V,在RMSE函数中加入了正则化项减少过拟合,公式如下,公式都是书上写的哈,这里截图:
K表示评分记录(u用户对I物品的评分),Ru,i表示用户u对物品i的真实评分,诶梦达表示正则化系数,诶梦达后面的表示防止过拟合的正则化项。
加入正则化的含义可以理解为,修改rmse,不要其太大或者太小。
假设用户特征矩阵为Umt,物品评分矩阵为Vtn,其中t特征<
2.3带偏置的矩阵分解(说的很有道理,但是比较难评估)
理论就不说了,举个例子,u1对v1的评分为4表示u1对v1这个物品非常喜欢,u2对v1的评分为4表示u1对v1一般喜欢,对用用户来说,即使他们对同一物品的评分相同,但是表示他们的喜好程度并不是一样的。同理对于物品来说也是一样。把这种独立于用户和独立于物品的影响因素成为偏置,偏置一共有3个部分组成。
1训练集中所有评分记录的全局平均,表示训练集中总体评分情况,一般是一个常数。
2用户偏置bu,独立于物品特征因素,表示用户特定的打分习惯。
3物品偏置bi,表示独立于用户特征因素,举个列子,好片子一般总体评分偏高,烂片一般评分偏低,偏置就是表示这种特征。
以上的所有偏置对用户对物品喜好无关,得到的预测评分公式如下:
按照这种思路,其实还要很多其他优化,比如加入时间因素,社会流行因素等。
Spark使用的是带正则化矩阵分解,优化函数的方式选用的是交叉最小二乘法ALS