浅谈推荐系统

太长不读版:由推荐系统带来的推荐服务基本上已经渗透到我们生活的方方面面,本文作为浅谈推荐系统的基础篇,主要从下面几个维度介绍推荐系统的相关知识:

  • 什么是推荐系统

  • 推荐系统在商业中的地位

  • 推荐系统、搜索引擎及广告的关系

  • 推荐系统的关键元素

  • 推荐系统相关的算法

篇幅较长,可能大部分道友比较关心算法部分,所以重点罗列了推荐系统算法思维演进史,每类算法理论点到即止,没有提供详细细节,但给出了相关阅读资料。全篇没有一个数学公式一行代码,初学者容易理解,有一定推荐系统相关知识的道友也可以起到一个系统化认识的作用。所属内容来自近期学习笔记,所提观点纯属抛砖引玉,如有疑问,欢迎大家积极讨论以及给出高见。

什么是推荐系统

按照维基百科的定义:推荐系统是一种信息过滤系统,用于预测用户对物品的评分或偏好。这个定义不是很好理解,因为它用“怎么做”来定义“是什么”,我们可以换个角度来理解:

  1. 它能做什么?

它可以把那些最终会在用户和物品之间产生的连接找出来。世间的万事万物都有连接,人与人之间的社会连接促进了社交产品的诞生,人与商品之间的消费连接造就了无数的电商产品,人和资讯越来越多的阅读连接促使了各类信息流产品的出现。

  1. 它需要什么?

推荐系统需要已经存在的连接,去预测未来的连接。比如电商平台会根据你买过什么,浏览过什么这些人和商品之间的连接来预测你还可能会买什么,又比如你在使用今日头条时每一次点击,每一次阅读都是连接,根据已有过去的点击、浏览行为来预测你感兴趣的内容。

  1. 它是怎么做的呢?

维基百科的定义已经解释了:预测用户评分和偏好,他们对应了推荐系统背后相关算法和技术的两大类别,还有更抽象的分类:机器推荐和人工推荐,也是我们常说的个性化推荐和编辑推荐。

  1. 它解决的是什么问题?

信息过载和长尾问题(长尾理论)。随着信息技术和互联网的发展,人们逐渐从信息匮乏的时代走入了信息过载的时代。消费者想从大量信息(物品)中找到自己感兴趣的信息,信息生产者想让自己生产的信息脱颖而出从而得到关注都是一件很难的问题,推荐系统的任务就是连接用户和信息(物品)。同时推荐系统要解决的另一个问题是需要发掘用户的行为,找到用户的个性化需求,从而将长尾商品准确的推荐给需要它的用户,同时帮助用户发现那些他们感兴趣但是很难发现的商品。

在信息过载的推动下,推荐系统成为了各大互联网公司攻城略地开疆拓土的必备良器。然而构建一个成熟的推荐系统并不是一件容易的事情,因为从技术上讲,它需要将数据、架构、算法、人机交互等环节有机的结合起来,需要用到数据挖掘技术、信息检索技术、计算统计学等悠久学科的相关知识。

从商业角度看推荐系统

在商业社会中,有一种亘古不变的关系:供求关系,供求关系的背后是交换。无论是实体经济还是虚拟经济,都是基于这个原理。供求关系动态变化,当供给小于需求时,就产生了稀缺,有了稀缺,就有了商业。

推荐系统处理的是信息,它的主要作用是在信息生产方和信息消费方搭建起桥梁,从而建立连接。

在信息经济中,看上去供求方是信息生产者,需求方是注意力提供者(信息消费者)。推荐系统可以服务于不同类型的产品(资讯,社交,电商,游戏),尽管它们最终得到真金白银的手段不一样,也就是所谓的商业模式各有不同,但是它们都有一个关键步骤就是:获得用户的注意力。

用户产生行为就是付出注意力的表现,比如信息流产品都是在看谁家的用户数多,阅读时间长,这些都是白花花的注意力。信息经济其实也就是注意力经济,而推荐系统就是留住注意力的重要手段之一。

那么注意力又是什么?它不是真的物理力,不属于四种宇宙基本力,而是一种决策可能性。比如用户为一个广告倾注了注意力,那么就有可能去点击广告,如果这个注意力非常强烈,还会继续消费广告中的商品,如果注意力足够持久,那么就会参与到整个商业链条上的各个经济活动。

但是注意力有个特点:总量有限。随着信息越来越丰富,注意力越来越稀缺。在门户时代的时候,信息稀缺,注意力丰富,是用户主动去寻找信息。到了搜索时代,虽然信息变得很丰富,但是在搜索引擎等工具的帮助下,这些信息并不会侵蚀用户的注意力,所以还是用户在主动寻找信息。但是在移动互联网普及之后,信息已经泛滥的非常严重,丰富的注意力被信息源以推荐的方式逐渐侵蚀,注意力从丰富变成稀缺。也是成了各大产商必争的生命源泉。

注意力本身有价值高低之分。资讯阅读类注意力量大,但是便宜,电商、游戏类注意力贵重,但数量上不如资讯阅读类。在某种程度上讲,行业里被粗略称呼的用户价值,实际上就是注意力价值。

在推荐系统的帮助下,注意力变成了稀缺方,信息源在打着灯笼到处寻找注意力,其实商品不再是信息,商品就是注意力,信息源变成了这些注意力的消费方。有限的注意力在推荐系统的帮助下,聚到了平台上,平台方需要像电力一样把这些注意力储存起来,储存起来的注意力就是平台方最有价值的资产。注意力的存在会导致平台上的内容被消耗,被消耗的内容又为平台带来收益,平台方通过经营平台内容维持注意力的体积从而达到商业运转的目的。

推荐系统与搜索引擎及广告的关系

在数字世界中,信息过载是必然的,应对信息过载的重担先后交给了搜索和推荐两兄弟。

要从浩航无边的知识海洋中获取想要的信息,针对“已知的未知”需求,首选的工具就是搜索引擎;而“未知的已知”和“未知的未知”则需要推荐系统去解决,介于两者之间,还有一种商业化解决信息触达问题方案,就是广告系统。从搜索广告到精准营销广告,逐渐形成了一个把广告当成一种有用的信息去找到最需要它的人的理念。

他们三者有共同之处,也有不同之处。搜索,推荐和广告本质上都在解决信息过载的问题,各自解决的手段、目标不相同,各自诞生在产品生命周期不同阶段,以至于系统实现也不尽相同。

搜索更关注内容消费者,搜索要解决的是精确快速找到想要的结果,最重要的目标是降低延迟和提高相关性。推荐系统不同于搜索引擎,用户使用搜索时目标明确,而使用推荐系统往往总会漫无目的。搜索和推荐都是为人找信息,而广告是为信息找人。

推荐系统的关键元素

大多数人在日常生活中,遇到推荐系统的高质量服务时,或者说被推荐的比较准确时,第一反应就是这个背后使用的什么样的算法,认为算法是推荐系统最核心的东西,只有最牛的算法才知道我现在在想什么我需要什么。但是算法只是关键元素之一,而且占的分量不大,关键元素有:

  • UI和UE

  • 数据

  • 领域知识

  • 算法

他们的权重大致为40%,30%,20%,10%。在这个看脸就成功了一半的时代,如果要构建一个成熟复杂的推荐系统,最新优化的一定是产品的UI和UE。用户对产品的体验,视觉是否符合目标用户的审美,交互逻辑是否简单明了,这些因素都会决定用户是否会持续使用产品。只有用户留下来了,才有推荐系统的用武之地。

数据和UI、UE同等重要,是推荐系统的基石。强大的推荐系统如果给用户的第一感觉不是使用了什么样的算法,那么就要是我在什么时候暴露了什么数据。前面已经提到了推荐系统就是要从已有的数据中找到存在的连接,再预测可能存在的连接。如果没有充足的数据,那么预测结果的可靠性也就可想而知了。

每一个产品存在于市场上,总有一部分价值是大多数其他产品无法替代的,这部分价值就涉及到了领域知识,比如电商产品有自己的领域知识:普通用户更在意的价格而不是兴趣。音乐产品也就自己的领域知识,比如不要向一个歌手的死忠粉推荐这个歌手的任何一首歌曲,因为作为死忠粉,每一首歌曲他都听过了。但是部分电商产品不一样,买过的商品还有可能再买的情况。

随着信息技术和互联网的发展,用于推荐系统的相关算法也在不断的发生更替,但是时至今日,也没有说哪一种算法非常厉害能解决所有问题,每个算法都有最适合自己的特殊场景,所以成熟的推荐系统并不会仅仅依赖于一两种特定的算法,而是对多种基础算法进行融合,集百家之所长。

推荐系统相关的算法

对于技术人员来讲,或许算法才是大家最感兴趣的部分,但是这里只是简要的概括推荐系统相关算法体系,不会具体到算法细节,因为任何一种算法的细节都可以讲上一天半载。

总的来说常见的推荐系统算法体系可以分为这几类:内容推荐、协同过滤推荐、矩阵分解、模型融合。

1. 内容推荐

内容推荐是推荐系统的孩童时代,但是在今天它依然适用于各个领域。内容推荐有其内容数据比较好获取的优点,在从零开始构建一个推荐系统时起到了非常重要的作用。基于内容的推荐要做到四步:抓取数据、清洗数据、挖掘数据、应用算法。

1.1 抓取数据

数据是整个推荐系统的源泉,所以即使是在用户越来越注重数据隐私的今天,哪怕是上千亿的大厂,都有自己的数据爬取团队不断地从外部和内部抓取数据,他们整天在爬取和反爬取中斗法,就为了多获取或者少流失一点数据,只有当内容具有了多样性,一个推荐系统才有存在的合法性。

1.2 清洗数据

无论是抓来的数据还是自己生产的数据都需要经过清洗,毕竟大家都是借鉴来借鉴去,存在重复的内容是很正常的事情,所以需要去重,在去重的同时,还需要识别垃圾内容、色情内容、政治敏感内容。

1.3 挖掘数据

基于内容的推荐,最重要的不是推荐算法,而是内容挖掘和分析,内容数据尤其是文本数据,只要深入挖掘,就可以挖掘出一些信息供推荐系统使用。内容分析的越深入,能抓住的用户群体就越细致,推荐的转化率就越高。

内容分析的结果主要有两类:一个是用户画像和物品画像的结构化内容库,另一个是分析过程中可能得到的模型,如主题模型、分类器模型、实体识别模型、嵌入模型等,这些模型主要用于实时推荐刚刚加入的新物品,通过对物品内容的实时分析,提取结构化内容,再用于用户画像匹配。

内容挖掘主要会用到自然语言处理(NLP)相关技术,如:

  • 使用IF-IDF和TextRank进行关键词提取;

  • 使用隐式马尔科夫模型(HMM)或者条件随机场(CRF)进行实体识别(序列标注);

  • 在有分类体系的前提下使用SVM或FastText工具对文本进行分类;

  • 使用LDA等无监督算法对文本聚类或从文本中抽取主题模型;

  • 使用Word2Vec、Embedding的方式挖掘出字面意思下的语义信息。

  • 同时可以使用卡法检测(CHI)和信息增益(IG)等方法从众多标签中选出主要的标签。

1.4 相似度计算

基于内容的推荐,最简单的算法就是计算相似性,可以把用户画像和物品画像表示成稀疏的向量,两者之间计算余弦相似度,根据相似度对推荐物品排序,也可以使用信息检索中的相关性计算方法如BM2F算法来做推荐匹配计算。同时在传统机器学习方面,可以结合逻辑回归(Logistic Regression)和梯度提升树(GBDT)训练一个二分类模型,把用户、物品的结构化内容,日志记录的上下文信息(如时间、地点、设备)作为特征,从而预测用户“喜欢”和“不喜欢”的用户行为。随着近几年深度学习的大火大热,同样可以根据用户、物品画像以及上下文信息训练一个类似Deep & Wide的端到端的神经网络预测模型。

2. 协同过滤推荐

当推荐系统度过了只能使用基于内容的推荐结果后,就已经积累的一定的用户行为了,这些行为通常是正向的,也就是或明或暗的表达着用户喜欢的行为。这些行为可以表示成用户和物品的关系矩阵,而近邻推荐主要基于这个关系矩阵来计算用户之间、物品之间的相似度从而达到推荐的目的。

协同过滤是推荐系统算法里面最著名的算法,协同过滤通常分为两类:基于记忆的协同过滤(Memory-Based)和基于模型的协同过滤(Model-Based),基于记忆的协同过滤又可以分为基于用户的协同过滤(User-Based)和基于物品的协同过滤(Item-Based)

2.1 原理

基于用户的协同过滤就是根据历史用户行为,通过计算用户相似度的方式,找到和目标用户的相似用户群体,然后将相似用户群体消费过的、喜欢的物品推荐给目标用户。

基于物品的协同过滤也是根据历史用户行为,不过计算的是物品之间的相似度,先找到一批和用户消费过的物品的相似物品,然将这些相似物品推荐给用户。

相对于基于用户的协同过滤,基于物品的协同过滤在物品数远远小于用户数的时候比较适用,同时物品之间的相似度比较静态,它们的变化速度远远没有用户口味变化快。

2.2 存储

在实践过程中,我们往往会先构建用户和物品的关系矩阵,然而这个矩阵是非常稀疏的,所以在大数据量存储的时候可以选择典型的稀疏矩阵存储方式CSR或者COO。

2.3 改进

协同过滤可能会带来马太效应,所以会有一些常见的改进方法。

基于用户的协同过滤主要改进在用户对物品的喜好程度上,比如惩罚对热门物品的喜好程度,增加喜好程度的时间衰减等方法;

基于物品的改进主要有物品中心化和用户中心化,即先分别减去物品、用户分数的均值,再进行相似度计算。

2.4 输出

协同过滤推荐有两类输出:相似用户、物品列表,基于用户、物品的推荐结果。

推荐结果也有两种表现形式:第一种是TopK推荐,形式上有点类似“猜你喜欢”,也就是先降序排序用户对物品加权求和后的预测评分,然后选取前K个物品推荐给用户;另外一种是相关推荐,也就是我们经常看到的“看了又看”,“买了又买”的推荐结果。

2.5 相似度计算

相似度计算是协同过滤算法的核心部分,针对不同问题会选择不同的相似度计算方式,常用到的计算方式有:

  • 适用于分析用户能力模型之间差异的欧式距离;

  • 在文本、物品、用户相似度计算比较常用的余弦相似度;

  • 同时针对余弦相似度对绝对值大小不敏感的问题,还有调整的余弦相似度(Adjusted Cosine Similarity),也就是先计算向量每个维度的均值,然后每个向量在每个维度上减去均值,再计算余弦相似度;

  • 度量两个随机变量是不是同时增减的皮尔逊相关度(Pearson);

  • 适合于布尔值的杰拉德相似度(Jeccard);

2.6 Slope One算法

经典的协同过滤算法,相似度矩阵无法实时更新,整个过程都是离线计算的,同时相似度计算没有考虑相似的置信问题,比如两个物品有且仅被一个用户喜欢了,余弦相似度的结果为1,然而这两个物品可能并不相似。所以有针对此类问题的改进算法,如的Slope One算法等,但是Slope One算法只适用于评分问题。

3. 矩阵分解

推荐系统的经典问题中有一类是评分问题,这类问题只是很典型,但不是很大众,主要原因是评分数据很难收集,与此相对的行为预测问题会更普及一些。

矩阵分解的盛行得益于多年前Netflix Prize那份关于评分预测比赛一百多万美元的奖赏。话说2006年10月2号那天,影视界的土财主Netflix广发英雄帖召集四海八荒各路豪杰,在已有推荐系统的基础上降低电影评分预测的均方根误差,只要误差降低了10%的大侠,就可以瓜分100万美刀,消息一出,群贤毕至。评分预测问题在一百万美刀的加持上,催生出了无数的推荐算法,最为著名的就是矩阵分解系列算法,其中最著名的是SVD及各种变体。

3.1 SVD

在矩阵分解算法出现之前,推荐领域的算法主要还是以近邻推荐为主,但是近邻推荐有几个问题:一是物品之间的相关性,信息量不会随着物品向量的维度而线性增加,二是关系矩阵元素稀疏,增加和减少一个向量维度,导致结果的差异性很大。横空出世的矩阵分解可以解决上面的问题,直观上来讲,就是把原来一个很大的关系矩阵,近似的分解为两个分别代表用户和物品矩阵的乘积,推荐的时候不再使用大的矩阵,而直接使用分解之后的小矩阵。一个矩阵由代表用户偏好的用户隐因子向量组成,另一个矩阵由代表物品语义主题的隐因子向量组成,矩阵的奇异值分解(SVD)就是最基本的分解算法之一。

3.2 增加偏置信息

基础的SVD没有考虑用户和物品的偏置信息,会使得在一些现实情景下整个平台的评分会很高。比如标准宽松的用户常常会给出偏高的分值,同时一些电影的铁粉也会对追随的电影,无论质量高低,都打较高的分值。所以在基础的SVD基础上,出现了第一个变种:将用户、物品偏置信息抽出来的SVD,和基本的SVD相比,它要多学习两个参数:用户偏置和物品偏置。

3.3 增加隐式信息和用户属性

在增加完偏置之后,还有另外一个问题需要解决:有的用户评分少,也就是显示反馈比隐式反馈少(通俗来讲,显式反馈是指能明确表达用户喜好的反馈行为,如评分,评分越高表示用户越喜欢;相反隐式反馈指不能直接表达用户是否喜欢的行为,如点击、阅读,用户点击或者阅读了一个物品,并不能表示用户喜欢这个物品,有可能就是简单的看了一下发现不敢兴趣就离开了,所有我们常常要从其它维度来判断用户是否喜欢这个物品,比如点击的次数、阅读的时长等)。所以后来的SVD++在前面的基础上增加了隐式反馈和用户属性等基本信息,在学习的过程中又多了两个向量:隐式反馈的物品向量,用户属性的特征向量。

3.4 增加时间因素

解决完上面的问题之后,又正视了另外一个问题:人是善变的,一年前的我们和现在我们的偏好可能发生了翻天覆地的变化,那么在SVD中考虑时间因素也变得顺理成章了。在SVD中考虑时间因素主要有这几种做法:对评分按时间加权;对评分按时间段划分区间,不用时间区间分别学习对应的隐因子;对特殊的期间如节假日等训练对应的隐因子。

3.5 ALS

矩阵分解除了上面提到的SVD系列算法之外,还有一种的比较流行的算法:交替最小二乘(ALS),他们的区别是SVD在优化过程中主要使用随机梯度下降(SGD),而交替最小二乘则是利用矩阵的逆矩阵计算方式不断优化目标,交替最小二乘的一个好处是可以参数并行化,而且在不是很稀疏的数据集上,会比随机梯度下降要更快的得到结果。

3.6 WeightedALS

矩阵分解算法是为解决评分问题而生的,而实际上推荐系统更关注的是预测行为,也就是一再强调的隐式反馈。可以使用One-Class的思维将预测评分问题转换成预测行为问题,相对应的有改进后的加权交替最小二乘(WeightedALS),专门解决隐式问题的矩阵分解。

3.7 贝叶斯个性化排序

矩阵分解在推荐系统的地位很高,因为它既有协同过滤的血统,又有机器学习的基因。但是由于它的目标优化函数的定义,它提倡的方法还是让人颇有微词。因为目标是使矩阵分解结果的乘积尽量接近原始矩阵,但是在实际使用的过程中,却是拿这两个矩阵乘积的预测结果来排序。这种针对单个物品的偏好程度进行预测,得到结果后再排序的问题,在排序学习中称为point-wise,与之相对的,有直接预测物品两两之间相对顺序的问题,叫pair-wise。所以贝叶斯学派提出的贝叶斯个性化排序(简称BPR模型)直接预测物品的相对顺序,而非精确的评分。

4. 模型融合

推荐系统在技术实现上一般分为三个阶段:挖掘、召回、排序。

挖掘的工作就是对用户和物品做非常深入的结构化分析,各角度各层面的特征都被呈现出来,并建立好索引,供召回阶段使用,大部分挖掘工作都是离线进行的。

那么召回又是什么呢?因为物品数目太多,每次给用户计算推荐结果的时候,如果对全部物品依次计算将会是一个灾难,取而代之的就是利用各种简单的、复杂的推荐算法从全量的物品中先筛选一部分比较靠谱的。

最后的排序就是对筛选出来的靠谱结果做一个统一的排序,这个排序过程就会涉及到各模型结果的融合。不同的算法只负责推举出候选结果,真正的是否推荐给用户,由另外一个模型说了算,这个就叫做模型的融合。

4.1 模型融合

在推荐系统模型融合阶段,要以产品的目标为导向,比如在信息流推荐中,如果要以提高CTR为目标,那么就可以在推荐一个物品之前,使用逻辑回归预估用户对它的点击率有多大,再根据这个点击率对物品的输出排序。逻辑回归主要的两个任务就是组合特征、学习权重。

特征组合有一个难点就是组合数目非常庞大,而且不是所有组合都有效,只有少数组合有效。权重的学习主要看两个方面:一个是损失函数的最小化,也就是模型的偏差是否足够小;另一个是模型的正则化,也就是模型的方差是否足够小。偏差代表着模型在训练集上的准确性,偏差越小,预测值和真实值也就接近;方差代表着模型的稳定性和泛化能力,方差越小,模型越稳定,泛化能力越好,越能在真实环境适用。偏差和方差的权衡一直是机器学习领域老生常谈的话题。

此外逻辑回归使用随机梯度下降法优化损失函数,随机梯度下降常常被人诟病的是它很难得到稀疏的模型,效果收敛也很慢。幸运的是Google在2013年KDD上发表了一种新的结合了L1正则和L2正则的在线优化算法:FTRL,被广大厂家应用在自己的在线训练平台中。

4.2 逻辑回归和梯度决策树

在逻辑回归中,特征组合能有效表达出数据中的非线性事实,但是发现成本很高,需要花大量的人力和物力,而我们之前提到的梯度提升决策树(GBDT)可以解决这个问题。梯度提升决策树分为两个部分:沿着残差梯度下降的方向构建子模型的集成模型方案(GB)和构建子模型时用到的决策树(DT)。在定义损失函数时,把逻辑回归中的误差平方和换成适合分类的损失函数,例如对数损失函数。业界往往在模型融合的时候把逻辑回归和梯度决策树结合起来使用,GBDT的任务就是产生高阶特征组合,从而取代逻辑回归中的手工组合特征的工作。

4.3 因子分解机模型

前面提到特征组合是一个很庞大的工程,在组合二阶特征时,两两组合会导致特征灾难,同时大多数特征组合都不会产生效果,由于对应样本的限制,没办法学习到对应组合特征的权重,所有只能放弃。而另一类算法模型能够解决这个问题:因子分解机模型(FM, Factorization Machine)。FM也常被拿来做模型融合。FM模型最直接的观点就是每一个特征学习一个隐因子向量,在特征组合的时候将两两特征的隐因子向量做一个向量内积,作为两者组合的权重,取代了前面去学习组合特征后的权重的方法。一定程度上讲,前面提到的SVD系列的矩阵分解法只是FM中的特例,在特定条件下,可以使用FM推导出SVD系列的算法。

4.4 Field-aware Factorization Machine

在特征数目比较多时,有时候对两个特征的隐因子做内积计算也是一件比较耗费时间的事情,那么我们可以通过先对特征聚类的方法将特征聚类成几个类簇,每个类簇有自己的隐因子向量,在内积计算的时候,只需要选取当前特征和对应特征所在类簇进行内积就行了,使用这种方法可以大大的减轻计算量。这种改进被称为Field-aware Factorization Machine,简称FFM。

4.5 Deep & Wide

类似逻辑回归这样的广义线性模型主要采用特征海洋战术来做模型融合,不断的挖掘新特征、挖掘特征组合模型、寻找新的离散特征分散方法。这种单模型加特征的方式有很多好处:模型简单,训练和预测计算复杂度相对低;工程师们挖掘特征工程可以并行化;线性模型的可解释性相对非线性模型好。

特征工程让线性模型表现为一个比较宽的模型,能在训练集上得到不错的性能,但是泛化能力稍有欠缺。在深度学习大行其道的今天,深度学习的泛化能力强于线性模型。所以前面提到的Deep & Wide模型结合两者的优点,将宽度和深度模型结合起来进行模型融合。宽度模型就是我们前面提到的广义线性回归模型,如Logistic Regression等,而深度模型指的的多层的前馈神经网络。

深度模型对原始的高维稀疏类别型特征,先进行嵌入学习,转换为稠密、低维的实值型向量,转换后的向量维度通常在10-100这个范围。这里的嵌入学习,就是先随机初始化嵌入向量,再直接扔到整个前馈网络中,用目标函数来优化学习。最后在融合的时候,由逻辑回归作为最终输出单元,深模型最后一个隐藏层作为特征接入逻辑回归,宽模型的原始特征与之一起接入逻辑回归,然后端到端的训练参数。

4.6 MAB

前面提到了融合阶段会基于召回阶段各推荐算法产生的推荐结果进行排序,从另外一个角度来看,这其实是一个选择哪个算法输出的结果作为最终结果的问题,针对不同的业务场景,制定不一样的融合策略。选择问题往往是现实生活中最头疼的问题之一,而Bandit算法就是为选择而生。

Bandit算法来源于人们喜闻乐见的赌博学,它描述的是一个赌徒去赌场摇老虎机的故事,不同的老虎机外表一模一样,但是吐钱的概率不一样,在不知道每台老虎机吐钱的概率分布分别是什么的情况下,怎么最大化收益。这个问题又被称为多臂赌博机问题(Multi-armed bandit problem, K-armed bandit problem, MAB)简称MAB问题。只要是关于选择的问题,都可以简化成MAB问题。

推荐系统里面有两个顽疾,一个是冷启动,另一个是探索利用问题,后者又称为Exploit-Explore问题。Bandit算法都可以对着两个问题对阵下药。冷启动问题是指针对于新加入的用户、物品或者推荐系统刚启动时,没有足够的历史数据,就无法进行准确的预测。而Exploit-Explore问题描述的是两个方向的权衡问题,以用户的兴趣为例,利用(Exploit)指的是要充分利用我们挖掘到的用户的兴趣,而探索(Explore)指的是用户的兴趣会随时间发生变化,在利用的同时,我们应该继续探索挖掘新的用户兴趣,不要故步自封,坐吃山空。

另外需要指出的是Bandit 算法并不是指一个算法,而是一类算法。Bandit算法的思想是:看看选择会带来多少遗憾,遗憾越少越好。在 MAB问题里,用来量化选择好坏的指标就是累计遗憾。常见的Bandit算法有:汤普森采样算法、UCB(Upper Confidence Bound)算法、Epsilon贪婪算法。

基本的Bandit算法没有使用候选臂的特征信息,特征是机器学习的核心要素,是机器学习泛化的依赖元素,于是乎Yahoo的科学家们在2010年基于UCB提出了LinUCB算法,和传统的UCB相比,最大的改进就是加入了特征信息。

前面提到了协同过滤是推荐系统里面最经典的算法,因为它利用的全体的智慧,但是它无法捕捉到用户的兴趣变化,而且容易造成马太效应,也就是典型的Exploit过了头,而Bandit提倡走一步看一步,不断Explore行的东西,将两者结合起来,就有了COFIBA算法。

5. 其它算法

5.1 排行榜算法(热门推荐算法)

前面已经提到了推荐系统有一个顽疾,冷启动,一个新用户来了,推荐系统对他一无所知,这个时候可以尝试给他推荐最热门的东西,等积累一定的数据之后,再选择其它的个性化推荐方案。然而排行榜算法不仅仅是计算卖的最好的或者阅读量最多那么简单。最简单的排行榜,就是直接统计某种指标,按照大小去排序。在社交网站上,按照点赞数、转发数、评论数去排序,这是一种最常见、最朴素的排行榜。这些做法不是很靠谱,因为很容易被攻击,也就是被刷榜;并且马太效应一致存在,除非强制替换,否则榜上永远都是那些信息;同时这样的计算不能反应排行榜随时间的变化。所以在算法设计的时候,需要考虑到时间因素,可以用热力学定律来定义每个物品,即排行榜里的每个物品都是炙手可热具有一定温度的,随着时间的推移一定会耗散到周围,温度就会下降。

5.2 用户标签的加权采样

在数据挖掘完成后,我们一般会为用户计算兴趣标签,如果计算的标签太多的话,每次召回候选集的时候,计算的复杂度会很大,如果能给每个标签设定对应的权重,这个时候可以使用简单的加权采样法,每次召回的时候不使用全部的用户标签,而是按照权重采样一部分标签来使用,这样做有很多好处:减少了计算复杂度;可以保留更多的标签;每次召回计算时还能有所变化,添加了随机性,有利于模型泛化。

加权采样有两种方式,一是知道全部样本个数,每次采样时遍历所有的标签,来依次决定每个标签输出的概率;另外一种就是不知道数据集有多大,获取的数据是数据流,对应的就是流采样,又叫蓄水池采样,就是可以在模型融合之后加一层蓄水池抽样,或者在召回阶段加一层蓄水池采样,这样在不影响整个推荐流程和转化概率的前提下,降低计算复杂度,提升推荐多样性。

同时在线阶段要使用用户的反馈行为做实时推荐,对于不同的用户,活跃程度不同,产生的反馈行为数量不同,也可以用蓄水池采样,为每个用户取出固定数量的行为用于更新推荐结果。蓄水池采样的做法是假设一批数据有n个,先直接获取K个样本保留,然后从K+1个样本起,每个样本以k/n的概率替换保留的K个样本中的一个。

5.3 去重算法

在推荐系统中,去重是刚需,主要用在两个地方:一是内容源去重,二是不重复给用户推荐。前面已经提到由于“相互借鉴”的原因,我们获取的数据很大程度上存在重复值,所以需要对内容做重复性检测。直观的思路是分词,然后提取关键词,再两两计算词向量之间的距离,距离小于一定阈值后就判定为重复。但是对应海量的内容,两两比较简直是一个灾难。内容去重在搜索引擎时代就已经是一个刚需了,所以可以复用搜索引擎的做法,Google在2007年的时候公开了他们的内容重复检测算法Simhash,这个算法简单有效,甚至造就了今天的信息流推荐产品。

Simhash核心思想也是为每个内容生成一个整数来表示指纹,然后用这个指纹去做重复或者相似的检测。当然这个指纹肯定不像MD5那样的指纹计算那么简单,常常会用Jenkins算法把每个词哈希成一个多位二进制的整数,然后不同词之间再做加减运算获得内容的指纹,获取到内容的指纹之后,可以两两计算汉明距离,比较二进制位不同个数,然后再和阈值比较得到是否相同的结论。

除了内容重复检测,还有一个需求是防止已经推荐的内容被重复推荐。和上述内容去重相比,最大的不同是过滤对象不同,Simhash过滤的是内容本身,而这里一般指的是内容的ID,在数据量不是太多的情况下,可以为每个内容建立一个UUID,然后用专门的数据库来保存,还可以为它建上索引来保证查询时的高效性。但是数据巨大时,对于存储的消耗又是一个问题,有一个比较老但是比较有用的做法是布隆过滤器Bloomfilter,布隆过滤器的原理也要用到哈希函数。它包含两部分:一个很长的二进制位向量,和一系列哈希函数。Bloomfilter 也并不是百分之百保证的,有很小的概率把原本不存在集合中的模式串判断为存在,但是这个小概率是可以承受的。

5.4 深度学习算法:

近几年,深度学习的圣火燎原般地燃烧到各个领域,推荐也不例外,大厂商们不断地在将神经网络融入到推荐服务的路上上下而求索。

携程不断演进的AutoEncode系列算法,将用户和物品关系矩阵中每一行或者每一列作为网络的输入和输出,训练用户和物品的编码器,同时在后续的改进版本中把噪声、用户属性、物品属性信息作为side information以及上下文情景融入到网络中提升模型的性能。

电商巨擘阿里提出了最大堆树模型TDM(Tree-based Deep Match),它将树结构和神经网络结合起来的,在超大数据量下,通过对用户兴趣进行层次切分和逐层圈选,避免了直接在全量候选集上的超大计算,它采用将大问题切割成多个小问题递归求解的方式实现全库检索,从而提升结果的新颖比例并保持了召回效果。同时在广告领域,借助类似注意力(Attention)模型新增网络结构DIN(Deep Interest Network),对用户的历史数据和待估算的物品进行部分匹配、计算权重(匹配度越高的历史数据就对结果的影响越大)。

社交网络广告领域,领英提出的Audience Expansion for Online Social Network Advertising尝试解决如何定位目标受众和原始受众的相似属性的问题。

除此此外,还有些其它的网络结构,Node2Vec,Wide & Deep,Deep Neural Networks for YouTube Recommendations,Convolutional Matrix Factorization for Document Context-Aware Recommendation。

除了各大厂商的研究以外,学术界也研究了各种网络结构,如PNN(Product-based Neural Network), NFM(Neural Factorization Machine), AFM(Attention Factorization Macine), NCF(Neural Collaborative filtering)。具体细节代码可参考 Github代码

5.4 强化学习算法:

把推荐系统当成Agent,获取用户信息和上下文信息(state),将物品推荐(action)给用户,用户及时做出反馈(reward),Agent评估Exploitation Network Q和Exploration Network Q~ 的表现,如果Q效果更好,即推荐的准确,得到了正向的reward,那么保持模型不变,如果 Q~ 的表现更好,则将Q的参数向Q~变化,一段时间后,再根据积累的历史经验对Q模型参数进行更新,这就是DQN在推荐领域的案例。通过这样的方式,将强化学习应用到推荐领域。强化学习特别适合于需要及时捕捉到动态变化的情景。国内大厂阿里京东在这方面颇有建树,详情请参照论文:Deep Reinforcement Learning for List-wise Recommendations, DRN:A Deep reinforcement Learning Framework for News Recommendation。

算法部分就介绍到这里,所涉及到的理念都是一些比较浅显的概念,而且所列举的算法都是算法簇里面的冰山一角,如果想要了解更多的话,还得继续往后面深挖才行,当然那也不是基础篇的内容了。

下面是一些参考资料,有兴趣的话可以了解一下,欢迎补充。

推荐阅读更多精彩内容