目录
- 缘起
- 矩阵分解
- 为什么要矩阵分解
- 1 基础的SVD算法
- 2 增加偏置信息
- 3 增加历史行为
- 4 考虑时间因素
- 总结
我们先前聊过推荐系统中的经典问题,其中有一类就是评分预测。平心而论,评分预测问题只是很典型,其实并不大众。毕竟在实际的应用中,评分数据很难收集到;与之相对的另一类问题是行为预测,却处处可见。
缘起
评分预测问题之所以小众却十分重要,这一点得益于十几年前Netflix Prize的那一百万美元的悬赏效应。
悬榜:凡是能在他们现有的推荐系统基础上,把均方根误差下降10%的人,可以瓜分100万美元。Netflix放出的数据正是评分数据,推荐系统的问题模式也是评分预测,评价标准是均方根误差。在这一百万美元的加持下,催生了很多优秀的推荐算法。其中最为著名的当属矩阵分解模型,而最最著名的模型就是SVD以及其各种变体。
今天,我就和你细聊一下矩阵分解,SVD及其最有名的变种算法。
矩阵分解
为什么要矩阵分解
矩阵分解确实可以解决一些近邻模型无法解决的问题。
近邻模型的问题:
1、物品之间存在相关性,信息量并不随着向量味道增加而线性增加;
2、矩阵元素稀疏,计算结果不稳定,增减一个向量维度,导致近邻结果差异很大的情况存在。
上述两个问题,在矩阵分解中可以得到解决。矩阵分解,就是把原来的大矩阵,近似分解成两个小矩阵的乘积,在实际土建计算时,不再使用大矩阵,而是使用分解得到的两个小矩阵。
具体来说,假如用户物品的评分矩阵A是m乘以n维,即一共有m个用户,n个物品。我们选一个很小的数k,这个k比m和n都小很多,比如小两个数量级这样,通过 一套算法得到两个矩阵U和V,矩阵U的维度是m乘以k,矩阵V的维度是n乘以k;
A m × n ≈ U m × k ∗ V n × k T A_{m\times{n}} \approx U_{m\times{k}} * V_{n\times{k}}^{T} Am×n≈Um×k∗Vn×kT
类似这样的矩阵分解,还有一个更常见的名字SVD;
1 基础的SVD算法
SVD全称奇异值分解,属于线性代数的知识,然而在推荐算法中实际使用的并不是正统的奇异值分解,而是一个伪奇异值分解;
今天我介绍的SVD是由Netflix Prize中取得骄人成绩的Yehuda Koren提出的矩阵分解推荐算法。
首先介绍基础的SVD算法,然后是考虑偏置信息,接着是超越评分矩阵增加多种输入,最后是增加时间因素。矩阵分解,就是把用户和物品都映射到一个k维空间中,这个k维空间不是我们直接看到的,也不一定具有非常好的可解释性,每一个维度也没有名字,所以常常叫做隐因子。
每一个物品都得到一个向量q,每一个用户也都得到一个向量p。对于物品,与它对应的向量q中的元素,有正有负,代表着这个物品背后隐藏一些用户关注的因素。
对于用户,与它相对应的向量p中的元素,有正有负,代表着这个用户在若干因素上的喜好。物品被关注的因素和用户偏好的因素,它们的数量和意义是一致的,就是
我们在矩阵分解之处人为指定的k。
举例,用户u的向量是pu,物品i的向量是qi,那么,要计算物品i推荐给用户u的推荐分数,只需计算点积即可。
r u i ^ = p u ∗ q i T \hat{r_{ui}} = p_u * q_i^{T} rui^=pu∗qiT
看上去很简单,难点在于如何得到每一个用户,每一个物品的k维向量。这是一个机器学习问题,按照机器学习的框架,一般需考虑两个核心要素;
1、损失函数
2、优化算法
SVD的损失函数是这样定义的:
这个损失函数由两部分构成,加号前一部分控制模型的偏差,加号后一部分控制模型的方差;
前一部分就是:用分解后的矩阵预测分数,要和实际的用户评分之间误差越小越好。
后一部分就是:得到的隐因子向量要越简单越好,以控制模型的方差。
整个SVD的学习过程是:
1、准备好用户物品的评分矩阵,每一条评分数据看做一条训练样本;
2、给分解后的U矩阵和V矩阵随机初始化元素值;
3、用U和V计算预测后的分数;
4、计算预测的分数和实际的分数误差;
5、按照梯度下降的方向更新U和V中的元素值;
6、重复步骤3到5,直到达到停止条件。
得到分解后的矩阵之后,实质上就是得到了每个用户和每个物品的隐因子向量,有了这个向量,再做推荐计算就简单多了;
2 增加偏置信息
你已经了解基础的SVD了。现在我们考虑一下实际情况,试想一下:有一些用户会给出偏高的评分,比如标准宽松的用户;有一些物品也会收到偏高的评分,比如 一些目标观众为铁粉的电影,最终导致的就是平台的全局评分就偏高。
所以,原来的SVD就有了第一个变种:把偏置信息抽出来的SVD。
一个用户给一个物品的评分会由四部分组成:
r u i ^ = u + b i + b u + p u ∗ q i T \hat{r_{ui}} =u +b_i +b_u+p_u *q_i^{T} rui^=u+bi+bu+pu∗qiT
从左至右分别代表:全局平均值、物品的评分偏置、用户的评分偏置、用户和物品之间的兴趣偏好。
举例:假如一个电影评分网站全局平均分是3分,《肖申克的救赎》的平均分比全局平均分要高1分,你是一个对电影比较严格的人,你一般打分比平均分都要低0.5分 ,所以前三项从左向右分别为:3,1,-0.5,如果简单就靠这三项,可以计算出你会给《肖申克的救赎》打的分值为3.5分。
增加了偏置信息的SVD模型目标函数稍有改变:
和基础的SVD相比,增加了两个参数:用户偏置和物品偏置。
3 增加历史行为
探讨完增加偏置信息的SVD后,接着再思考一个问题:有的用户评分比较少。事实上:相比沉默的大多数,主动点评电影或者美食的用户毕竟还是少数。
换句话说,显示反馈比隐式反馈少,那么能不能利用隐式反馈来弥补这一点呢?另外,再考虑多一点,对于用户的个人属性,比如性别等,能否也加入到模型中来弥补冷启动的不足呢?
以上考虑是可行的,在SVD中结合用户的隐式反馈行为和属性,这套模型叫做SVD++.
先说隐式反馈如何加入,方法是:除了假设评分矩阵中的物品有一个隐因子向量外,用户有过行为的物品集合也都有一个隐因子向量,维度是一样的。把用户操作过的物品
隐因子向量加起来,用来表达用户的兴趣偏好。
类似的,用户属性,对每一个特征也假设都存在一个同样维度的隐因子向量,一个用户的所有属性对应的隐因子向量相加,也代表了他的一些偏好。
综合两者,SVD++的目标函数中,只需要把推荐分数预测部分稍作修改,原来的用户向量增加了隐式反馈向量和用户属性向量:
其中 N u N_u Nu为用户u所产生行为的物品集合; y j y_j yj为隐藏的、对于商品j的个人偏好设置(相当于每种产生行为的商品都有一个偏好 y j y_j yj),是一个我们要学习的参数。并且 y j y_j yj是一个向量,维度数等于隐因子维度数,每一个分量代表对该商品的某一因子成分的偏好程度,也就是说对 y j y_j yj求和,实际上是将所有产生行为的商品对应的隐因子分量值进行分别求和,最后得到的求和后的向量,相当于是用户对这些隐因子的偏好程度。 ∣ N u ∣ ( − 1 2 ) \begin{vmatrix} N_u\end{vmatrix}^{(-\frac{1}{2})} Nu (−21) 是一个规范化因子。
4 考虑时间因素
在时间长度上看,人是善变的,或美其名曰,人是进步的。因此,在SVD中考虑时间因素也变得顺理成章。
在SVD中考虑时间因素,有几种做法:
1、对评分按照时间加权,让久远的评分更趋近平均值;
2、对评分时间划分区间,不同的时间区间分别学习出隐因子向量,使用时按照区间使用对应的隐因子向量来计算;
3、对特殊的期间,如节日、周末等训练对应的隐因子向量。
总结
至此,我们介绍了在Netflix Prize比赛中最为出众的模型:SVD及其一些典型的改进。改进方案分别是:
1、考虑偏置信息;
2、考虑隐式反馈和用户属性
3、考虑时间因素