产品, 数据, 术→技巧

推荐系统之协同过滤

钱魏Way · · 464 次浏览

推荐算法具有非常多的应用场景和商业价值,因此对推荐算法值得好好研究。推荐算法种类很多,但是目前应用最广泛的应该是协同过滤类别的推荐算法,本文就对协同过滤类别的推荐算法做一个概括总结。

推荐算法概述

概括来说,可以分为以下5种:

  • 基于内容的推荐:这一类一般依赖于自然语言处理NLP的一些知识,通过挖掘文本的TF-IDF特征向量,来得到用户的偏好,进而做推荐。这类推荐算法可以找到用户独特的小众喜好,而且还有较好的解释性。
  • 协同过滤推荐:优点是不需要太多特定领域的知识,可以通过基于统计的机器学习算法来得到较好的推荐效果。工程上容易实现,可以方便应用到产品中。目前绝大多数实际应用的推荐算法都是协同过滤推荐算法。
  • 混合推荐:这个类似机器学习中的集成学习通过多个推荐算法的结合,得到一个更好的推荐算法。比如通过建立多个推荐算法的模型,最后用投票法决定最终的推荐结果。混合推荐理论上不会比单一任何一种推荐算法差,但是使用混合推荐,算法复杂度就提高了,在实际应用中有使用,但是并没有单一的算法广泛。
  • 基于规则的推荐:这类算法常见的比如基于最多用户点击,最多用户浏览等,属于大众型的推荐方法,在目前的大数据时代并不主流。
  • 基于人口统计信息的推荐:这一类是最简单的推荐算法了,它只是简单的根据系统用户的基本信息发现用户的相关程度,然后进行推荐,目前在大型系统中已经较少使用。

协同过滤简介

协同过滤,从字面上理解,包括协同和过滤两个操作。

  • 协同就是利用群体的行为来做决策(推荐),生物上有协同进化的说法,通过协同的作用,让群体逐步进化到更适应环境的状态。对于推荐系统来说,通过用户的持续协同作用,最终给用户的推荐会越来越准。
  • 过滤就是从可行的决策(推荐)方案(标的物)中将用户喜欢的方案(标的物)找(过滤)出来的过程。

具体来说,协同过滤的思路是通过群体的行为来找到某种相似性(用户之间的相似性或者标的物之间的相似性),通过该相似性来为用户做决策和推荐。

现实生活中有很多协同过滤的案例及思想体现,人类在寻找配偶时希望相亲对象“门当户对”,其实也是一种协同过滤思想的反映,”门当户对“实际上是建立了相亲男女的一种“相似度”(家庭背景、出身、生活习惯、为人处世、消费观、价值观等各个维度的相似性),给自己找一个门当户对的伴侣就是一种“过滤”,当双方”门当户对“时,各方面的习惯及价值观会更相似,未来幸福的概率也会更大。

协同过滤利用了两个非常朴素的自然哲学思想:“群体的智慧”和“相似的物体具备相似的性质”,群体的智慧从数学上讲应该满足一定的统计学规律,是一种朝向平衡稳定态发展的动态过程,越相似的物体化学及物理组成越一致,当然表现的外在特性会更相似。虽然这两个思想很简单,也很容易理解,但是正因为思想很朴素,价值反而非常大。协同过滤算法原理很简单,但是效果很不错,而且也非常容易工程实现。

协同过滤的类型

基于项目(Item-based)的协同过滤

基于协同过滤的两种推荐算法,核心思想是很朴素的“物以类聚、人以群分”的思想。所谓物以类聚,就是计算出每个标的物最相似的标的物列表,我们就可以为用户推荐用户喜欢的标的物相似的标的物,这就是基于物品(标的物)的协同过滤。所谓人以群分,就是我们可以将与该用户相似的用户喜欢过的标的物推荐给该用户(而该用户未曾操作过),这就是基于用户的协同过滤。

协同过滤的核心是怎么计算标的物之间的相似度以及用户之间的相似度。我们可以采用非常朴素的思想来计算相似度。我们将用户对标的物的评分(或者隐式反馈,如点击、收藏等)构建如下用户行为矩阵,矩阵的某个元素代表某个用户对某个标的物的评分(如果是隐式反馈,值为 1),如果某个用户对某个标的物未产生行为,值为 0。其中行向量代表某个用户对所有标的物的评分向量,列向量代表所有用户对某个标的物的评分向量。有了行向量和列向量,我们就可以计算用户与用户之间、标的物与标的物之间的相似度了。具体来说,行向量之间的相似度就是用户之间的相似度,列向量之间的相似度就是标的物之间的相似度。

2003年,亚马逊发表了一篇论文,阐述了他们如何用物品协同过滤算法(Item-to-Item Collaborative Filtering),搭建他们“看了又看”功能。如下图:

这个协同过滤推荐是如何做计算出来的呢?为了简单化,假设某图书销售平台总共有6本书销售,有6个用户购买。

数据:用户的评分数据,分值1-5分。每个用户对图书的评分如下图矩阵所示。

学习算法:前面说到Item CF的定义是,相似的物品可能被同个用户喜欢。反过来讲,就是被同个用户喜欢的物品是相似商品。如上图中,图书1和图书2两本书,被用户A同时喜欢,这两本书具有相似性。而图书5和图书6,没有被同个用户同时喜欢,不具有相似性。

如果用余弦相似度计算图书1和图书2的相似度,也叫做cosine距离, 用同样的方式,可以算出图书1跟其他五本图书相似度分别为0.27, 0 .79,0.32,0.99和0。对每两本书计算完这个相似度后,就可以获得全部图书的相似矩阵。

一个平台不仅仅有6本图书6个用户,我们再扩展到一般的情况。计算物品的相似度,实际是计算每两个物品评分向量的cosine距离,评分向量的每一维,代表了一个用户,下图中,表格的第一行代表了所有用户对物品A的评分。当有100万个用户时,也就是计算每两个100万维向量的距离。这样就导致计算量很大,而且很多平台不仅仅只有100万用户,因而这个低效的计算方式需要改进。

预测决策:有了评分矩阵之后,预测决策一般有两种场景。

一种是根据相似度排序推荐最近邻物品。类似于“看了还看”,“买了还买”场景。在这里的例子中,我们知道图书1和其他图书的相似度排序分别是图书5,图书3,图书4和图书2。当用户点击了图书1时,就可以按照相似顺序从高到低推荐。

第二种是根据相似度预测评分推荐物品。如何决策要不要给用户B推荐图书2,图书4和图书6呢?如下图,通过用户B对图书1的评分 * 未知图书与图书1的相似度来预测用户B对剩下图书的评分。如图书2的预测评分 =  图书1的评分5分 * 图书1和图书2的相似度0.27 ,从而用户B对图书2的评分是:5*0.27=1.35。同样方式计算出其他图书的评分预测。

从上面的结果来看,用户B对其他图书评分比较低,这几本图书推荐的可能性大大减少。

基于用户(User-based)的协同过滤

用户协同过滤(UserCF)的计算方式跟物品协同过滤(ItemCF)的计算方式类似。不同的是由计算两两物品的相似度,转换成计算两两用户的相似度。如下图所示:

评分了相同图书的用户为相似用户,他们的相似度同样也用cosine相似度公式来计算。计算完相似度后,就可以根据用户间的相似性,预测用户对未评分图书进行评分预测。

但是在亚马逊上,由于用户评分的稀疏性(很多用户压根不评分),没有评分的用户无法跟其他用户计算相似性,从而导致很多用户之间没有相似度。所以2001年的时候,亚马逊选择物品协同过滤算法来做推荐,并发表了论文。这个论文也导致大家一度认为物品协同过滤优于用户协同过滤。

基于模型的协同过滤

基于模型的协同过滤作为目前最主流的协同过滤类型。我们的问题是这样的m个物品,n个用户的数据,只有部分用户和部分数据之间是有评分数据的,其它部分评分是空白,此时我们要用已有的部分稀疏数据来预测那些空白的物品和数据之间的评分关系,找到最高评分的物品推荐给用户。对于这个问题,用机器学习的思想来建模解决,主流的方法可以分为:用关联算法,聚类算法,分类算法,回归算法,矩阵分解,神经网络,图模型以及隐语义模型来解决。

  • 用关联算法做协同过滤。一般我们可以找出用户购买的所有物品数据里频繁出现的项集活序列,来做频繁集挖掘,找到满足支持度阈值的关联物品的频繁N项集或者序列。如果用户购买了频繁N项集或者序列里的部分物品,那么我们可以将频繁项集或序列里的其他物品按一定的评分准则推荐给用户,这个评分准则可以包括支持度,置信度和提升度等。常用的关联推荐算法有AprioriFP Tree和PrefixSpan。
  • 用聚类算法做协同过滤。用聚类算法做协同过滤就和前面的基于用户或者项目的协同过滤有些类似了。我们可以按照用户或者按照物品基于一定的距离度量来进行聚类。如果基于用户聚类,则可以将用户按照一定距离度量方式分成不同的目标人群,将同样目标人群评分高的物品推荐给目标用户。基于物品聚类的话,则是将用户评分高物品的相似同类物品推荐给用户。常用的聚类推荐算法有K-Means, BIRCH, DBSCAN谱聚类
  • 用分类算法做协同过滤。如果我们根据用户评分的高低,将分数分成几段的话,则这个问题变成分类问题。比如最直接的,设置一份评分阈值,评分高于阈值的就是推荐,评分低于阈值就是不推荐,我们将问题变成了一个二分类问题。虽然分类问题的算法多如牛毛,但是目前使用最广泛的是逻辑回归。为啥是逻辑回归而不是看起来更加高大上的比如支持向量机呢?因为逻辑回归的解释性比较强,每个物品是否推荐我们都有一个明确的概率放在这,同时可以对数据的特征做工程化,得到调优的目的。常见的分类推荐算法有逻辑回归和朴素贝叶斯,两者的特点是解释性很强。
  • 用回归算法做协同过滤。用回归算法做协同过滤比分类算法看起来更加的自然。我们的评分可以是一个连续的值而不是离散的值,通过回归模型我们可以得到目标用户对某商品的预测打分。常用的回归推荐算法有Ridge回归回归树支持向量回归
  • 用矩阵分解做协同过滤。用矩阵分解做协同过滤是目前使用也很广泛的一种方法。由于传统的奇异值分解SVD要求矩阵不能有缺失数据,必须是稠密的,而我们的用户物品评分矩阵是一个很典型的稀疏矩阵,直接使用传统的SVD到协同过滤是比较复杂的。目前主流的矩阵分解推荐算法主要是SVD的一些变种,比如FunkSVD,BiasSVD和SVD++。
  • 用神经网络做协同过滤。用神经网络乃至深度学习做协同过滤应该是以后的一个趋势。目前比较主流的用两层神经网络来做推荐算法的是限制玻尔兹曼机(RBM)。在目前的Netflix算法比赛中, RBM算法的表现很牛。当然如果用深层的神经网络来做协同过滤应该会更好,大厂商用深度学习的方法来做协同过滤应该是将来的一个趋势。
  • 用图模型做协同过滤。用图模型做协同过滤,则将用户之间的相似度放到了一个图模型里面去考虑,常用的算法是SimRank系列算法和马尔科夫模型算法。对于SimRank系列算法,它的基本思想是被相似对象引用的两个对象也具有相似性。算法思想有点类似于大名鼎鼎的PageRank。而马尔科夫模型算法当然是基于马尔科夫链了,它的基本思想是基于传导性来找出普通距离度量算法难以找出的相似性。
  • 用隐语义模型做协同过滤。隐语义模型主要是基于NLP的,涉及到对用户行为的语义分析来做评分推荐,主要方法有隐性语义分析LSA隐含狄利克雷分布LDA

协同过滤存在的问题

协同过滤的主要优点是:

  • 算法原理简单、思想朴素
  • 算法易于分布式实现、易于处理海量数据集
  • 算法整体效果很不错
  • 能够为用户推荐出多样性、新颖性的标的物
  • 协同过滤算法只需要用户的行为信息,不依赖用户及标的物的其他信息

但同时也存在一些问题。

数据稀疏问题

对于现代的互联网产品,用户基数大,标的物数量多(特别是新闻、UGC 短视频类产品),一般用户只对很少量的标的物产生操作行为,这时用户操作行为矩阵是非常稀疏的,太稀疏的行为矩阵计算出的标的物相似度往往不够精准,最终影响推荐结果的精准度。

协同过滤的精度主要取决于用户数据的多少。如果一个系统有很多用户的历史数据,他就能更好的对用户的喜欢做出预测。所以,目前推荐系统做的最好的都是那些有着很大量用户数据的公司,比如Google, Yahoo, Netflix, Amazon等等。

冷启动问题

协同过滤算法依赖用户的行为来为用户做推荐,如果用户行为少(比如新用户、新上线的产品或者用户规模不大的产品),这时就很难发挥协同过滤算法的优势和价值,甚至根本无法为用户做推荐。这时可以采用基于内容的推荐算法作为补充。

另外,对于新入库的标的物,由于只有很少的用户操作行为,这时相当于用户行为矩阵中该标的物对应的列基本都是零,这时无法计算出该标的物的相似标的物,同时,该标的物也不很难出现在其他标的物的相似列表中,因此无法将该标的物推荐出去。这时,可以采用人工的策略将该标的物在一定的位置曝光,或者强行以一定的比例或者概率加入推荐列表中,通过收集该标的物的行为(让用户行为矩阵中该标的物对应的列有更多的非零元素)解决该标的物无法被推荐出去的问题。

新用户问题/新产品问题

这个问题和数据稀疏问题有一些相似性,指如何对新用户做出推荐。当一个新用户进入一个站点时,我们对他的兴趣爱好还一无所知,这时如何做出推荐是一个很重要的问题。一般在这个时候,我们只是向用户推荐那些普遍反映比较好的物品,也就是说,推荐完全是基于物品的。对于新的产品,同样存在如上的问题。

有很多产品的标的物是有时效性的(比如新闻类 APP),并且标的物是快速增长的(比如短视频类 APP)。对于有时效性的标的物,在具体推荐时需要考虑到时效性。可以在计算相似性时只计算在时效范围内的标的物作为相似列表,在进行推荐时过滤掉不在时效范围内的标的物。对于标的物快速增长的情况,最好用近实时的协同过滤,以应对当天新增的标的物无法被推荐出去的问题。

长尾问题(长尾用户/长尾商品)

新用户问题还有一个变种就是长尾问题,在Amazon中,不是所有的用户都对很多书给出了评分,很多用户只给少数的书给出了评分,这些用户就处在一个长尾中,如何处理那些不太表露自己兴趣的用户,也是推荐系统的一个主要问题。除此之外,图书的长尾也是一个不可忽视的问题。

不断变化的用户喜好

用户的兴趣不是永远不变的,随着年龄和阅历的变化,用户的行为会发生变化。协同过滤其实还应该加入一个时间因子。今天自己浏览amazon时是会有特定意图的,明天或许会有另一个特定意图。举个典型的例子:有可能某天我会上amazon为自己买本书,但第二天我到amazon的原因可能是要为姐姐找一份生日礼物。对于用户喜好,推荐系统也可能错误的标注。

隐性喜好难处理

在现在的推荐系统中,用户的喜欢是通过用户对某些物品进行评分获得的。这种获得用户兴趣的方法是一种很直接的方法。但在实际的互联网中,用户有很多隐性的方法表露他们的喜欢。比如用户的文字评论,我们可以通过自然语言处理从用户的评论中获得用户的兴趣;或者是用户的浏览行为,比如用户长时间的浏览一个物品,或者用户经常浏览一个物品,或者用户购买了一个物品,这些行为都可以作为模式识别系统中的特征。

偏激的用户和另类的产品

世界上有一些用户是很偏激的。他们和大多数人的观点是相反的。对于这种用户,现有的推荐系统做出的预测往往是很差的。如何处理偏激的用户,是推荐系统中的一个重要问题。和偏激用户相对应的,是颠覆性的产品。比如一些古怪(特别)的电影会有一些问题,有一些电影观众对它又爱又恨,这种类型的电影是很难去做推荐的,因为用户对它们会有各种反映而且无法预计。

马太效应的影响

在互联网中,物品实在是太多了,而推荐系统只能推荐有限的物品。被推荐系统所推荐的物品将会越来越热门,这就导致了大量很好的物品可能会被推荐系统所淹没。解决这个问题的主要方法是增加推荐系统的多样性,比如一个推荐系统发现一个用户非常喜欢吃德芙巧克力,那么他给这个用户推荐10个产品,不需要都是德芙巧克力,也可以推荐别的一些巧克力,或者一些和巧克力相似的甜品。在推荐时,不仅要推荐用户喜欢的东西,而且要通过推荐让用户喜欢一些东西,有的时候,用户自己也不知道他喜欢什么,通过推荐系统,他可能会发现一些新东西他比较喜欢。

推荐系统的作弊行为

只要涉及到经济利益,就有人作弊。搜索引擎作弊是一个被研究了很久的问题,因为在搜索引擎中,自己的网站排名越高,就能获得越多的经济利益。在推荐系统中也是如此,比如在淘宝中,如果一个卖家的物品经常被推荐,他就可能获得很多经济利益。很多电子商务的推荐系统都遭受到了作弊的干扰,一些人通过一些技术手段,对自己卖的物品给出非常高的评分,这就是一种作弊行为。作弊行为相当于人为的向系统中注入了噪声。目前解决作弊的算法主要是基于信任度和信用的。现在很多电子商务网站都引入了信用系统。如何设计信用系统和推荐系统更好的融合,是一个重要的研究问题。

协同过滤应用实践

协同过滤算法虽然简单,但是在实际业务中,为了让它有较好的效果,最终对业务产生较大的价值,我们在使用该算法时需要注意如下问题。

是采用基于用户的协同过滤还是采用基于标的物的协同过滤

在互联网产品中一般会采用基于标的物的协同过滤,因为对于互联网产品来说,用户相对于标的物变化更大,用户是增长较快的,标的物增长相对较慢(这也不是绝对的,像新闻、短视频类应用标的物也是增速巨大的),利用基于标的物的协同过滤算法效果更稳定。

对时间加权

一般来说,用户的兴趣是随着时间变化的,越是久远的行为对用户当前的兴趣贡献越小,基于该思考,我们可以对用户的行为矩阵做时间加权处理。将用户评分加上一个时间惩罚因子,对久远的行为进行一定的惩罚,可行的惩罚方案可以采用指数衰减的方式。例如,我们可以采用如下的公式来对时间做衰减,我们可以选择一个时间作为基准值,比如当前时间,下式中的 n 是标的物操作时间与基准时间相差的天数(n=0 时,w(0)=1)。

$$w(n)=0.5+0.5^{(1+0.02 * n)}$$

关于用户对标的物的评分

在真实业务场景中,用户不一定对标的物评分,可能只有操作行为。这时可以采用隐式反馈的方式来做协同过滤,虽然隐式反馈的效果可能会差一些。但同时,我们是可以通过一些方法和技巧来间接获得隐式反馈的评分的,主要有如下两类方法,通过这两类方法获得评分,是非常直观的,效果肯定比隐式反馈直接用 0 或者 1 好。

虽然很多时候用户的反馈是隐式的,但用户的操作行为是多样化的,有浏览、点击、点赞、购买、收藏、分享、评论等等,我们可以基于用户在这些隐式行为中的投入度(投入的时间成本、资金成本、社交压力等,投入成本越大给定越高的分数)对这些行为人为打分,比如浏览给 1 分,点赞给 2 分,转发给 4 分等等。这样我们就可以针对用户不同的行为生成差异化的评分。

对于像音乐、视频、文章等,我们可以记录用户在消费这些标的物上所花的时间来计算评分。拿视频来说,如果一个电影总时长是 100 分钟,如果用户看了 60 分钟就退出了,那么我们就可以给用户打 6 分(10 分制,因为用户看了 60%,所以打 6 分)。

相似度计算

我们在前面讲解协同过滤算法时需要计算两个向量的相似度,本文前面采用的是 cosine 余弦相似度。其实,计算两个向量相似度的方式非常多,cosine 余弦是被证明在很多场景效果都不错的一个算法,但并不是所有场景 cosine 余弦都是最好的,需要针对不同场景做尝试和对比。在这里,我们简单罗列一些常用的相似度计算的方法,供大家参考。

冷启动问题

前面在讲协同过滤算法的缺点时讲到协同过滤算法会存在严重的冷启动问题,主要表现在如下 3 个方面:

  • 用户冷启动。所谓用户冷启动就是新用户没有太多的行为,我们无法为他计算个性化推荐。这时可行的推荐策略是为这类用户推荐热门标的物、通过人工编排筛选出的标的物。或者用户只有很少的行为,协同过滤效果也不好,这时可以采用基于内容的推荐算法补充。
  • 标的物冷启动。所谓标的物冷启动就是新的标的物加入系统,没有用户操作行为,这时协同过滤算法也无法将该标的物推荐给用户。可行的解决方案有三个:
    • 首先,这类标的物可以通过人工曝光到比较好的推荐位(如首页)上,在尽短的时间内获得足够多的用户行为,这样就可以“启动”协同过滤算法了。这里有个比较大的问题是,如果该标的物不是主流的标的物、不够热门的话,放在好的位子不光占用资源同时对用户体验还不好。
    • 其次,在推荐算法上做一些策略,可以将这类新的标的物以一定的概率混杂在用户的推荐列表中,让这些标的物有足够多的曝光,在曝光过程中收集用户行为,同时该方法也可以提升用户推荐的多样性。
    • 最后,这类标的物也可以通过基于内容的推荐算法来分发出去,作者在第 5 章中已经讲过内容推荐,这里不再赘述。
  • 系统冷启动。所谓系统冷启动,就是该产品是一个新开发不久的产品,还在发展用户初期阶段,这时协同过滤算法基本无法起作用,最好采用基于内容的推荐算法或者直接利用编辑编排一些多样性的优质内容作为推荐备选推荐集。等用户规模、用户行为足够多后再启用协同过滤算法。

协同过滤的一些新方向

推荐算法的变革也在进行中,就算是最火爆的基于逻辑回归推荐算法也在面临被取代。

  • 基于集成学习的方法和混合推荐:这个和混合推荐也靠在一起了。由于集成学习的成熟,在推荐算法上也有较好的表现。一个可能取代逻辑回归的算法是GBDT。
  • 基于矩阵分解的方法:矩阵分解,由于方法简单,一直受到青睐。目前开始渐渐流行的矩阵分解方法有分解机(Factorization Machine)和张量分解(Tensor Factorization)。
  • 基于深度学习的方法:目前两层的神经网络RBM都已经有非常好的推荐算法效果,而随着深度学习和多层神经网络的兴起,以后可能推荐算法就是深度学习的天下了?目前看最火爆的是基于CNN和RNN的推荐算法。

参考链接:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注