矩阵分解模型
导读
最近在研究”基于时序行为的协同过滤算法“中重点提到了矩阵分解模型,因此总结下最近比较火的算法:矩阵分解模型。
经过kddcup和netflix比赛的多人多次检验,矩阵分解可以带来更好的结果,而且可以充分地考虑各种因素的影响,有非常好的扩展性,因为要考虑多种因素的综合作用,往往需要构造cost function来将矩阵分解问题转化为优化问题,根据要考虑的因素为优化问题添加constraints,然后通过迭代的方法进行矩阵分解,原来评分矩阵中的missing vlaue可以通过分解后得到的矩阵求的。
本文将简单介绍下最近学习到的矩阵分解方法。
1. PureSvd
开始学习机器学习算法时,觉得这种方法很神奇很数学,而且应用比较广泛。但读了Yehuda大神的paper之后,觉得这种方法还ok了。
其实,矩阵分解的核心是将一个非常稀疏的评分矩阵分解为两个矩阵,一个表示user的特性,一个表示item的特性,将两个矩阵中各取一行和一列向量做内积就可以得到对应评分。
那么如何将一个矩阵分解为两个矩阵就是唯一的问题了。
说到这里大家就可能想起了在线代和数值分析中学到的各种矩阵分解方法,QR,Jordan,三角分解,SVD。。。
这里说说svd分解。
svd是将一个任意实矩阵分解为三个矩阵U,S,V,其中,U,V是两个正交矩阵,称为左右奇异矩阵,S是个对角阵,称为奇异值矩阵。
其实svd分解的问题可以化解为特征值分解的问题。
评分矩阵A(m*n)=U(m*k)*S(k*k)*V\'(k*n)
令B(m*m)=A(m*n)*A\'(n*m)
B矩阵就是一个方阵,可以利用各种简单的方法将B进行特征值分解:
Bv=av,
v是方阵B的特征向量,a是特征向量v对应的特征值。
所以奇异值s=sqrt(a),
左奇异向量u=A*v/s
同样的方法可以求得右奇异向量。
这样我们就得到了svd分解后的三个矩阵。(你可以自己写个c程序计算,当然也可以用matlab算算得到)
分解后的三个矩阵都有着各自的意义,
U:每一行表示一个user的特征。
V:每一列表示一个item的特征。
S:表示对应的user和item的相关性。
所以可以考虑用U和V将S吸收进来,形成两个矩阵分别表示user的矩阵和item的矩阵。
得到这个以后后面的事情就好办了。
为什么说这个方法猥琐呢?
因为我觉得,这种方法有着矩阵分解算法的表,却可以非常简单地完成矩阵的分解,然后填充稀疏的评分矩阵。
但它考虑的因素太少了,不过对于简单的推荐系统,这种方法还是非常有意义的,容易实现,而且结果也不会太差。
2. Latent Factor Model
这是真正的矩阵分解算法,经过实践检验,具有非常高的准确性和易扩展性。
正如上面提到的,实现推荐系统结果的目标是将那个稀疏的评分矩阵分解成两个矩阵,一个表示user的feature,一个表示item的feature,然后做内积得到预测。
当然要实现满足一定约束条件的矩阵分解,可不像上面的PureSVD那样容易,需要构造一个优化问题,用一些复杂的算法求解优化问题。而这些优化问题往往是NP问题,只有局部最优解。
首先构造一个优化目标函数,
考虑到最后的评价指标是预测分值和实际分值之间的误差的平方(RMSE),所以构造的目标函数也是误差的平方的函数。
为什么这样的算法可以得到更优的结果呢?因为算法可以很容易地扩展很多的feature进来,更加出色地考虑了多种影响推荐效果的实实在在的因素。
- Biases
因为有的用户总是会打出比别人高的分,或者说有的用户他的评价尺度比较宽松;同样有的item总是被打高分。这是一个普遍存在的问题,所以在构造目标函数的时候需要增加几项:所有评分的平均值miu,user的偏见分数bu,item的偏见分数bi。
比如:求用户x对电影y的打分,
所有评分电影的评分的平均分是miu=3.5,
电影y比所有评分电影平均分高bi=0.5
但是用户x是个比较严格的用户,评分总是相对偏低,所以bu=-0.3
所以用户x对电影y的打分为3.7
- Implicit feedback
用户在使用web应用的时候,会产生大量的行为,充分挖掘这部分的价值,将会很好地提升推荐的效果。
利用用户的隐式反馈,相当于充分的利用了评分矩阵中的missing value的价值,用户在页面的停留时间,检索,浏览,点击等等各种行为都可以建模,内含到目标函数中。
这里,可以将简单地用一个Boolean来描述一种行为有还是没有。
不过在使用的时候,需要进行归一化处理。
- User-associated attributes
基于用户的社会化属性进行推荐也是一种很基本的推荐,当然也可以考虑到目标函数中。
- Temporal dynamics
用户的兴趣包括长期和短期,动态地考虑一段时间内用户的兴趣是很有必要的。
上面的几个因素中随着时间变化的有,user的bias项bu=bu(t),item的bias项bi=bi(t),以及user的factor向量pu=pu(t),这里可以忽略item的factor向量的变化,因为item是比较稳定的。
- Confidence level
因为在处理上述的因素的时候,很多都是比较主观的,所以需要给每个因素添加一个置信权重,以平衡整个结果。
通过构造出这个目标函数,然后添加相应的约束条件,接下来的问题就是求解这个优化问题。
通常比较好的方法是Stochastic gradient desent。
3. NMF(非负矩阵分解)
很多人用这种方法是因为他们觉得只有一个非负的值对于实际的例子才会有意义。
考虑到svd或者latent factor model会得到负的值,所以这种方法的物理意义比较明确。
同样的道理,NMF也是将评分矩阵的转置矩阵分解成两个矩阵。
不同的是这两个矩阵有着和上面的矩阵不同的物理意义。
其中一个是基矩阵W,另一个是投影矩阵H,即R\'(n*m)=W(n*r)*H(r*m)
W:每一列包含一个基向量,这组基向量构成一个r维的空间。
H:每一列则近似为原始数据对应的列向量在该r维空间的投影。
做这个分解的方法也是构造一个目标函数和一些约束条件,然后用梯度下降的算法来计算得到一个局部最优解。
这种方法的思路大概是这样的:
- 将评分矩阵转置然后分解成两个矩阵W和H。
- 根据基矩阵W,可以计算得到目标用户评分向量a对基矩阵W的投影向量h。
- 计算投影向量h与投影矩阵H各行之间的欧式距离,将其中距离最小的前k个用户组成目标用户a的最近邻集合。
- 然后用皮尔逊相关法将最近邻集合中的数据进行加权计算,然后排序进行推荐。
可以看出来,这种方法的思路和上面的两种还是很不相同的,主要还是在计算目标用户的最近邻集合,主要思想还是knn,只是在中间用了矩阵分解的方法降维降低了计算的时间复杂度。
小结
矩阵分解在研究生学习的时候感觉既没用又麻烦,尤其是线代里面做矩阵的分解计算。现在看来,矩阵分解非常有意义!
参考资料
Yehuda的神作 http://ccnt.zju.edu.cn:8080/smart/files/20120915-3.pdf
上海交大在2012年kddcup获奖方法的paper以及他们的开源系统 http://svdfeature.apexlab.org/wiki/Main_Page