对于在线部分来说,一般要经历几个阶段。首先通过召回环节,将给用户推荐的物品降到千以下规模(因为在具备一定规模的公司里,是百万到千万级别,甚至上亿。所以对于每一个用户,如果对于千万级别物品都使用先进的模型挨个进行排序打分,明显速度上是算不过来的,资源投入考虑这么做也不划算);如果召回阶段返回的物品还是太多,可以加入粗排阶段,这个阶段是可选的,粗排可以通过一些简单排序模型进一步减少往后续环节传递的物品;再往后是精排阶段,这里可以使用复杂的模型来对少量物品精准排序(打分),排序阶段核心目标是要精准,因为它处理的物品数据量小,所以可以采用尽可能多的特征,使用比较复杂的模型,一切以精准为目标。对某个用户来说,即使精排推荐结果出来了,一般并不会直接展示给用户,可能还要上一些业务策略,比如去已读,推荐多样化,加入广告等各种业务策略。之后形成最终推荐结果,将结果展示给用户。
对于近线部分来说,主要目的是实时收集用户行为反馈,并选择训练实例,实时抽取拼接特征,并近乎实时地更新在线推荐模型。这样做的好处是用户的最新兴趣能够近乎实时地体现到推荐结果里。
对于离线部分而言,通过对线上用户点击日志的存储和清理,整理离线训练数据,并周期性地更新推荐模型。对于超大规模数据和机器学习模型来说,往往需要高效地分布式机器学习平台来对离线训练进行支持。
(1)基于内容的推荐:根据物品内容(文本信息、属性信息、分类信息等),基于用户以往的喜欢记录,对用户的兴趣爱好进行建模(即用户画像,user profile),以及表达物品的特征(即物品画像,item profile)。然后在物品集合中计算物品画像与用户画像的相似度,选择最相近的N个物品(Top-N)推荐给用户。
基于内容的方法通常会抽取推荐物品的信息进行描述,常用的方法是加权关键词向量,用户画像和物品特征可以表示为。抽取的关键词作为推荐对象的特征,权重可以用TF-IDF、熵、信息增益和互信息等进行计算。例如在新闻等文本相关推荐领域,就可以先进行分词,然后利用TF-IDF计算权重,抽取关键词形成特征,建立加权关键字向量。对于用户画像,则可以使用户所有交互过的物品的加权关键字向量进行加权平均来表示。
优点:
缺点:
(2)基于人口统计信息的推荐:简单根据用户基本信息来发现用户的相关程度,然后推荐,比较简单也比较少用。
比如系统对每个用户有个资料建模,然后根据用户的资料计算互相之间的相似度,比如图中认为A和C相似,推荐系统中称他们为“邻居”。基于这种相似用户,将用户A喜欢的物品A推荐给用户C。
优点:
缺点:
(3)基于规则的推荐:比如基于最多点击、最多用户浏览等,属于大众型的推荐算法,类似的比如“热门推荐排行榜”。目前不是主流。
(4)社会化推荐:基于社交网络,利用用户的社会化关系进行推荐,例如基于信任传播的推荐。
(5)上下文推荐:这类算法会充分利用上下文信息(例如位置、时间、天气、情感等)提高推荐的精度和用户的满意度,常用于移动推荐、音乐推荐等。
(6)基于集成学习和混合推荐:模型融合,通过多个推荐算法的结合,得到一个更好的推荐算法。但是随之算法复杂度也会增加。实际推荐应用中没有单一的协同过滤或者逻辑回归应用广泛。几种比较流行的方法:
(7)基于协同过滤的推荐:最主流、工程领域运用最多的算法,不需要太多特定领域的先验知识,可以通过基于统计的机器学习算法得到较好的推荐效果。工程上容易实现,可以方便应用到产品。
collaborative filtering,简称CF。它是一种方法论,简单来说是利用某兴趣相投、拥有共同经验之群体的喜好来推荐用户感兴趣的信息,个人透过合作的机制给予信息相当程度的回应(如评分),并记录下来以达到过滤的目的进而帮助别人筛选信息。
一般有基于用户、基于项目、基于模型这三种协同过滤。
基于用户user-based,主要考虑的是用户之间的相似性。思想和基于人口统计信息的推荐非常相似,区别是计算相似度的算法不同:基于人口统计只是单纯考虑用户本身特征的相似性;而基于用户的协同过滤使用用户的历史操作记录来评估用户之间的相似度,它的前提假设是认为喜欢的东西类似的用户可能偏好和口味相同。
对于一个等待推荐的用户A,首先找到和他相似的一个用户集,比如这里发现用户C和他的口味相似。然后发现用户C还喜欢物品D,这时将物品D推荐给用户A。
用相似统计的方法得到具有相似爱好或者兴趣的相邻用户。方法步骤:
小结:基于用户的协同过滤推荐算法简单易用,不需要考虑用户属性和物品内容,理论上适用于所有的推荐场景。但该算法容易受到评分稀疏的影响,用户和物品数量膨胀后相似度计算难以扩展,并且不能解决用户冷启动问题,实践中推荐精度较差。
以用户为基础的协同推荐算法随着用户数量的增多,计算的时间就会变长。2001年Sarwar提出了基于物品的协同过滤推荐算法。以物品为基础的协同过滤方法有一个基本的假设“能够引起用户兴趣的项目,必定与其之前评分高的物品相似。”
基于物品的协同过滤在思想上和基于内容的协同过滤有相似之处,基于物品采用的是计算物品之间的相似度,根据用户的历史偏好,将相似物品推荐给用户。而基于内容的推荐仅仅考虑物品本身内容相似性,而没有考虑用户历史偏好。
比如用户A和用户B都喜欢物品A和物品C,推测物品A和C相似,于是将物品C推荐给喜欢物品A的用户C。
基于物品的协同过滤在思想上也与基于用户的协同过滤有相似之处。区别在于一个是基于用户历史偏好评价物品相关性,一个是基于用户历史偏好评价用户相关性。而本身基于物品其实也是亚马逊在基于用户的机制上进行改进的。
方法步骤:
小结:不用考虑用户之间的差别,所以精度较差。对于物品来说,它们的相似性较为稳定,因此可以离线完成工作量最大的相似性计算步骤,从而降低了在线计算量,也可将离线计算和在线推荐进行分离,方便系统设计。并且易于生成推荐解释,用户可信度高。但基于物品的协同过滤缺少用户之间的关系体现,实际上脱离了集体智慧。也易受到数据稀疏性的影响,难以解决用户冷启动问题。
如何对基于用户和基于物品的策略进行选择?
在一些站点上,物品的数量比较固定,且远远小于用户的数量,基于物品的策略比基于用户的策略实时性更好一些。而在一些新闻推荐系统中,也许新闻的个数大于用户的个数,而且更新速度快,所以相似度不够稳定,这时采用基于用户的策略可能更好一些。所以其实具体采用哪种策略和具体应用场景是很有关系的。
它们都是以记忆为基础(memory-based)的协同过滤技术,共有的特点是数据稀疏,难以处理大数据量影响即时结果。因此发展出基于模型的协同过滤技术。
面对稀疏数据,基于模型的协同过滤先用历史数据得到一个模型,再用此模型进行预测。
通过用机器学习的思想来建模,主流方法有:关联算法,聚类算法,分类算法,回归算法,矩阵分解,神经网络,图模型以及隐语义模型来解决。
关联规则是反映一个事物与其他事物之间的相互依存性和关联性,常用于实体商店或在线电商的推荐系统;通过对顾客的购买记录数据库进行关联规则挖掘,最终目的是发现顾客群体的购买习惯的内在共性。
关联分析中的关键概念:支持度、置信度与提升度。
常见的关联算法有:Apriori,FP Tree,PrefixSpan。
基于聚类的协同过滤,将用户和物品基于一定的距离度量来进行聚类。基于用户聚类,通过一定的距离度量方式分成不同的目标人群,将同样目标人群评分高的物品推荐给目标用户。基于物品聚类,将用户评分高物品的相似同类物品推荐给用户。
常用聚类算法:K-means,BIRCH,DBSCAN,谱聚类。
可以根据用户评分,将问题变为分类问题。比如设置一个评分阈值,评分高于阈值就是推荐,低于阈值就是不推荐,将问题变为了一个二分类问题。比如最广泛使用的逻辑回归。不使用支持向量机的原因是逻辑回归的解释性更强,每个物品是否推荐都有一个明确的概率放在这里,同时可以对数据做特征工程来调优。目前用逻辑回归做协同过滤已经非常成熟。
常用的分类推荐算法有:逻辑回归,朴素贝叶斯
评分可以是一个连续值,通过回归模型可以得到目标用户对商品的预测打分。
常用的回归推荐算法有:Ridge回归(线性回归的L2正则化),回归树(CART回归树),支持向量回归。
传统的SVD要求矩阵不能有缺失数据,必须是稠密的,而用户物品评分矩阵是有一个很典型的稀疏矩阵。
目前的矩阵分解推荐算法主要是SVD的一些变种,比如FunkSVD,BiasSVD和SVD++。这些算法和传统SVD最大区别是不再要求将矩阵分解为的形式,而是变为两个低秩矩阵的乘积形式。
目前FM(分解机,Factorization Machine)和张量分解(Tensor Factorization)也开始逐渐流行。
FunkSVD(隐含语义模型 Latent Factor Model)
传统的SVD方法不支持对稀疏矩阵进行分解,因此需要对稀疏评分矩阵进行填充。利用总体平均值进行填充,由于SVD的算法复杂度为O(n^3), 面对大规模数据时效率低很难应用于实际生产。Funk-SVD(LFM)通过降维的方法将用户的兴趣爱好补全,降维后矩阵的列对应着用户和物品潜在关联的维度,而每一维度表示一个隐含的特征,这类特征是抽象的,可能无法直观地解释。LFM模型利用矩阵分解技术,将用户兴趣(评分)矩阵R分解成用户隐含特征矩阵P和物品隐含特征矩阵Q,即,对于R中的每个值,数据集应该包含所有的user和他们有过行为的(也就是喜欢)的item。所有的这些item构成了一个item全集。对于每个user来说,我们把他有过行为的item称为正样本,规定兴趣度RUI=1,此外我们还需要从item全集中随机抽样,选取与正样本数量相当的样本作为负样本,规定兴趣度为RUI=0。因此,兴趣的取值范围为[0,1]。我们是已知的,所以我们训练的目标是得到一个合适的P/Q,这其中P/Q中隐特征的个数需要我们进行设置。接下来就可以初始化P/Q的值,训练过程使得P*QT与R越来越接近,优化方法可以使用梯度下降法,加入正则化来避免过拟合。
所以可将损失函数定义为:
这里不缺失代表的就RUI不为0的项,所以实际上我们在训练的时候只是利用到了正样本。
加入正则化项,防止过拟合,需要反复进行实验获取。
这其实就隐含着机器学习常用方法论:只要隐因子在估计已知评分时足够准,那么辅以一些正则化保证泛化能力之后它在未知评分上的预测也能满足精度要求。
接下来使用梯度下降法对损失函数进行优化:
其中,则学习迭代公式:
学习率α在学习过程中需多次实验。
假设我们的原始矩阵是
设置隐变量的个数为3,得到P和Q
将P和Q相乘
于是就将原始没有评分的项预测出了结果。
在Funk-SVD(LFM)的基础上,通过优化损失函数或将用户历史评分信息、时间信息等加入分解过程,可以得到更加优化的模型。例如将隐式兴趣加入LFM可以得到SVD++模型,将时间信息融入到LFM模型可以得到Time-SVD模型,而优化损失函数可以得到ListRank-MF模型。
FunkSVD加入偏置
实际上,很多性质是用户或者物品独有的。比如某个用户非常严苛,不论对什么物品给出的分数都很低,这仅仅和用户自身有关系。又比如某个物品很精美,所有用户都会给出较高的评分,这仅仅与物品自身有关。所以需要考虑用户和物品自身的属性。评分预测的公式也需要修正。假设整个评分矩阵的平均分为σ,用户u和物品i的偏置分别为和。
假设原始评分公式为
那么此时的评分计算方法就变为:
最终误差函数也将偏置加入正则项:
SVD++算法
对于实际的应用场景中,经常有这样一种情况:用户点击查看了某一个物品,但是最终没有给出评分。
实际上,对于用户点击查看物品这个行为,排除误操作的情况,在其余的情况下可以认为用户被物品的描述,例如贴图或者文字描述等所吸引。这些信息我们称之为隐式反馈。实际上,一个推荐系统中有明确评分的数据是很少的,这类隐式数据占了大头。
因此可以在刚刚加入偏置的基础上再加入隐式兴趣
损失函数也要加入隐式兴趣的正则项
对偶算法
可以看到上述都是基于用户角度(P矩阵)来考虑问题。同样可以基于物品的角度(Q矩阵)来考虑问题。
同样需要在损失函数中加入隐式兴趣的正则项。
实际运用中,可以将原始svd++的结果与对偶算法得到的结果进行融合,使得预测更加准确。然而相比物品的数目,用户的数目往往高出几个量级,因此对偶算法在储存空间和运算时间的开销都将远高于原始svd++,需要权衡效率与准确度之间的关系。
矩阵分解有如下优点:
能将高维的矩阵映射成两个低维矩阵的乘积,很好地解决了数据稀疏的问题;
具体实现和求解都很简洁,预测的精度也比较好;
模型的可扩展性也非常优秀,其基本思想也能广泛运用于各种场景中。
矩阵分解的缺点则有:
可解释性很差,其隐空间中的维度无法与现实中的概念对应起来;
训练速度慢,不过可以通过离线训练来弥补这个缺点;
实际推荐场景中往往只关心topn结果的准确性,此时考察全局的均方差显然是不准确的。
目前比较主流的是两层的限制玻尔兹曼机(RBM)。以及用深度学习的方法来做协同过滤是未来一个趋势,目前基于CNN和RNN的推荐算法非常火爆。
将用户相似度放入图模型去考虑,常用的是SimRank系列算法和马尔科夫模型(基于马尔科夫链的传导性来找出普通距离度量难以找出的相似性)算法。
主要基于NLP,涉及到对用户行为的语义分析来做评分推荐,主要方法有隐性语义分析LSA和隐含狄利克雷分布LDA。
写到这里,发现如果全部写一遍总结,真的可以写本书了。。。ORZ。。。