某个选修课的论文,这里贴过来,之所以贴过来,是因为我认为自己写的确实非常有意义,网上对这个东西确实没有很系统的中文介绍,我自己也是看了许多论文自己也动手做了很多很多实践才领悟的。
这个只是概论,以后有时间再加上具体的模型、算法。
-----------------------------------------------------------------------------
总的来说,推荐系统的目标可以分为预测评分和物品推荐两种,目前对前者的研究也更多,因为前者更适合建复杂的模型,所以这里只讨论预测评分的情况。现在主流推荐方法可分为协调过滤和基于内容的推荐,前者是重点,先说后者,基于内容推荐就是说,你过去曾经买过什么东西、看过什么电影,我就给你推荐一样的东西或者类似的东西,显然这样的模型太简单,只用这样简单的推荐肯定达不到最好的效果,所以我们需要有协调过滤。
协同过滤可以分为两种模型,一种叫KNN,用户最近邻模型,一种是Matrix Factorization,矩阵分解模型。KNN又有两种基本做法:一是找出与用户u最类似的K个用户,譬如如果我们想要预测u对电影i的评分,我们可以找出其他K个对电影i评过分的用户,然后分别计算他们与用户u的相似性,然后把他们对i的评分进行加权以后,作为用户u对i的评分。计算用户之间的相似性有很多方法,最常用的是余弦相似系数和皮尔森相似系数,都是将每一个用户的评分情况作为一个向量以后计算两个向量之间的余弦夹角或皮尔森系数。其中皮尔森系数其实就是一种减掉了平均值的方法,理论上更能贴近实际情况,更可靠。这是基于用户的推荐,基于物品的推荐也是一个道理,譬如我们要预测用户u对物品i的评分,我们找出用户u评过分的其他K个的物品,用同样的办法加权后得到u对i的预测值。
一般来说,KNN模型中基于用户和基于物品都要同时考虑,有人专门做过这个研究,参考论文:[Tag-aware Recommender Systems by Fusion of Collaborative Filtering Algorithms]
他的做法是把两者的结果分别乘一个加权系数以后相加,然后用机器学习的算法学习出两个系数的合适的值。
KNN的做法比较简单也很容易想到,所以自然需要一种更复杂的办法来改进系统。Matrix Factorization的想法来自于SVD,即奇异值分解(singular value decomposition)。在线性代数中我们知道,描述一个普通的矩阵呢的重要特可以通过特征值分解、奇异值分解等,其中特征值分解有点局限——只能用于方阵。但奇异值的计算是一个难题,是一个O(N^3)的算法。在单机的情况下当然是没问题的,matlab在一秒钟内就可以算出1000 * 1000的矩阵的所有奇异值,但是当矩阵的规模增长的时候,计算的复杂度呈3次方增长,就需要并行计算参与了。Google的吴军老师在数学之美系列谈到SVD的时候,说起Google实现了SVD的并行化算法,说这是对人类的一个贡献,但是也没有给出具体的计算规模。
其实SVD还是可以用并行的方式去实现的,在解大规模的矩阵的时候,一般使用迭代的方法,当矩阵的规模很大(比如说上亿)的时候,迭代的次数也可能会上亿次,如果使用Map-Reduce框架去解,则每次Map-Reduce完成的时候,都会涉及到写文件、读文件的操作。个人猜测Google云计算体系中除了Map-Reduce以外应该还有类似于MPI的计算模型,也就是节点之间是保持通信,数据是常驻在内存中的,这种计算模型比Map-Reduce在解决迭代次数非常多的时候,要快了很多倍。Lanczos迭代就是一种解对称方阵部分特征值的方法,是将一个对称的方程化为一个三对角矩阵再进行求解。按网上的一些文献来看,Google应该是用这种方法去做的奇异值分解的。SVD在MF中的具体应用可以参考这篇论文:[A Guide to Singular Value Decomposition]
在具体的Matrix Factorization中,奇异值不是直接计算出来的,一般都是通过随机梯度下降学习出来的。现在看矩阵分解分解的意义,尽管这个东西其实是不可解释的。假如有u个用户和i个物品,这样评分矩阵就是一个u*i的矩阵,假设经过分解之后,有u*f和i*f这样两个矩阵,就是说分解出来了一个长度为f的向量,拿电影来打比方,譬如用户有三个:张三、李四、王二,电影也有三个:《拯救大兵瑞恩》、《了不起的盖茨比》、《霍比特人》、这样分解出来的向量可能具有的意义就是:二战、斯皮尔伯格、小资、三角恋、奇幻、中世纪,这样f就为6,u*f的矩阵就是表示用户对这些标签的感冒程度,i*f的矩阵则表示电影对这些标签的拥有程度,譬如u*f中张三的那一行是(0.9,0.5,0.2,0.2,0.4,0.3),我们就可以知道张三最喜欢战争片,而不太喜欢小资爱情片,假如这时候有一部新的电影new movie的向量为(0.4,0.3,0.5,0.6,0.7,0.5),那么张三对这个new movie的评分就可以预测为两个向量的内积。
在很多论文中,分解出来的向量的信息被称为latent factor,前面的KNN模型就没有考虑到latent factor的影响,这也是KNN和Matrix Factorization模型最重要的区别。
除此之外,实际的推荐系统中还会考虑到偏见的影响,又称为基准偏移量。譬如有的用户很苛刻,倾向于给电影评分评低1分。有的电影口碑不好,譬如《小时代》,就容易被人故意评低几分。所以我们需要建立两个向量,一个存放每个用户的偏见分数,一个存放每个电影的偏见分数。这样就消除了偏见的影响。举个例子,譬如所有电影的评分的均值是3.5分(5分是满分),电影《小时代》倾向于被人评低2分,而用户小花评分不负责,总是评分多出均值1.5分,那我们对小花对《小时代》的评分预测就是3.5-2+1.5=2.5分。在实际算法中,两个偏移矩阵也是通过随机梯度下降的方法学习出。
到此,协同过滤的方法已经有三种了:矩阵分解、用户最近邻、基准偏移,模型都是不止一种的,都是多种结合以后产生推荐结果。一般的系统中前两者结合的效果就很不错了,也有的研究结合了三张方法,参见[when SVD++ meets neighbor]
新兴的模型:
新兴的模型其实也是建立在矩阵分解的基础上的,只不过是增加了更多的信息量。现在推荐系统已经无法再在基础模型上做文章,所以只能想办法利用更多的信息。譬如推荐的时候通过考虑用户的职业、用户给自己贴的标签、电影的标签等,调查显示80%的用户不介意公开不敏感信息。于是就有人把标签也考虑进了系统中,参见论文:[Tag-aware Recommender Systems by Fusion of Collaborative Filtering Algorithms]。
还有就是进行物品推荐时,不止是给用户推荐物品,而且也顺带上用户的简介、用户可能感兴趣的电影的演员,等等办法。
物品推荐的模型和评分预测的模型有些不同了,很多用到了朴素贝叶斯个性化排序或改进的朴素贝叶斯个性化排序,这里不再赘述,可参加论文:[BPR: Bayesian Personalized Ranking from Implicit Feedback]