互联网大厂推荐算法实战:零基础解析—第一章 推荐系统简介

第一章 推荐系统简介

        本书是一本讲究推荐算法、推荐模型的书。也是可以让我们初学者可以从零开始快速入门的一本书,下面我们一起来学习推荐系统(Recommender System)。

        首先我们需要认识到,推荐模型是现代推荐系统的核心(红色代表重点),但是它也知识推荐系统中的一个模块,而非推荐系统的全部。为了让模型能够正常运行、发挥作用,推荐系统中需要一下众多模块协同工作:

  • 日志系统收集用户反馈,为系统推荐提供原始数据;
  • 大数据系统、流失计算系统从原始数据中提取信息,将它们加工成模型所需的形式;
  • 在线学习系统及时更新模型;
  • 监控系统让我们观察模型运行是否正常,并且能够自动报警;
  • A/B实验系统评估模型效果,并且能够动态配置,改变推荐系统的运行方式
  • ......

        同理,参与完成推荐系统的也并非只有算法工程师,还需要前端、后段、产品、运营、用户增长等多个团队的通力配合。 总之,一个完整的推荐模型所涉及的知识、技术,要远多于推荐模型/算法,也复杂得多。鉴于本书的读者应该以算法同行居多,作者在本书的开篇就强调以上观点,目的在于提醒读者,在工作中不要只把目光停留在模型、算法这“一亩三分地”,而是一定要具备全局视角,从整个推荐系统的角度来考虑问题。这里面有很多名词大家可能不理解,没关系我们在后面慢慢学

        了解了推荐系统与推荐模型的关系以后,本章将从如下4个部分进行介绍:

  • 1.1节介绍推荐系统的缘起与意义,使得读者更好的把握互联网技术的发展脉络【简单说】;
  • 1.2节通过一个极简版的推荐系统描述推荐系统的运行机理,揭开它的神秘面纱;
  • 1.3节从功能和数据两个方面介绍推荐系统的架构。
  • 1.4节讲述搜、推、广三折区别和联系。              

1.1 推荐系统的意义

        【由于我们重点还是快速入门,所以这种介绍性的部分可能只简单说说,大家如果感兴趣全文可以后台仔细聊。】

        推荐系统的作用就是在信息过载的情况下,主动在人与信息之间建立高效的连接。

1.2 推荐系统是如何运行的

        为了搞清楚这个问题,我们假想一个最简化的推荐系统。和所有推荐系统一样,这个极简版的推荐系统有如下两个角色:

  • 用户(User:蓝色代表重要的名词):推荐系统要服务的对象。但是接下来我们会看到,用户也是推荐系统的重要贡献者。用户的一举一动为推荐系统的“茁壮成长”提供了源源不断的“养料”。用户通过“大拇指投票”帮助推荐系统分辨出内容、信息的真假优劣。
  • 物料(Item):用于统称要被推荐的信息、内容。不同场景下,物料会有不同的内涵。比如,电商推荐中,物料就是物品;内容推荐中,物料就是一篇文章、一首歌、一个视频;社交推荐中,物料就是另一个人。

        建立推荐系统分为以下8个步骤:

  1. 给物料打标签。⽐如对于⼀个视频“⾖瓣评分9.3, 最恐怖的喜剧电影——楚门的世界”, 我们给它打上“电影、 喜剧、 真⼈秀、 ⾦·凯瑞”这样的标签。 打标签⼯作既可以由⼈⼯完成(⽐如上传视频时由作者提供),也可以由内容理解算法根据封⾯、标题等⾃动完成。
  2. 建立倒排索引,将所有物料组织起来。倒排索引类似一个HashMap,其中键是标签,值是一个列表,包含被打上这个标签的所有视频。
    # 这里开始举例子看
    # 假设我们有以下视频和它们的标签:
    倒排索引={
        "喜剧": [视频A, 视频B],
        "足球": [视频C,视频D,视频E]
    }
  3. 推荐系统接收到一个用户的推荐请求。推荐系统根据从请求提取出的用户ID,从数据库中检索出该用户的兴趣爱好。在本例中,我们用一种非常简单的方式表示用户的兴趣爱好。假设该用户过去看过10个视频,其中7个带有“喜剧”的标签,3个带有“足球”的标签,那么提取出来的该用户的兴趣爱好就是{“喜剧”:0.7,“足球”:0.3},其中键表示用户感兴趣的标签,值表示用户对这个标签的喜爱程度。
    用户兴趣爱好={
        “喜剧”:0.7
        “足球”:0.3
    }
  4. 拿用户感兴趣的每个标签去倒排索引中检索。假设“喜剧”这个标签对应的倒排链中包含A、B两个视频,“足球”标签对应的倒排链中包含C、D、E、三个视频。汇总起来,推荐系统为该用户找到了5个它可能感兴趣的视频。这个过程叫做召回(Retrieval),查询倒排索引知识其中的一种实现方式。
    推荐视频 = [视频A, 视频B, 视频C, 视频D, 视频E]
    
  5. 推荐系统会猜测用户对这5个视频的喜爱程度,采按照喜爱程度降序排列,将用户最可能喜欢的视频排在最显眼的第一位,让用户一眼就能看到。这个过程叫作排序(Ranking)。至于如何猜测用户的喜爱程度,在这个极简版的推荐系统中,我们不使用模型,而是拍脑袋想出一条简单规则:
                                       Score(u,g,v)=Like(u,g)*Q(v)                       公式(1-1)
    该公式中各关键参数的含义如下。
               u表示发出请求的用户
               g表示用户u喜欢的一个标签
               v表示在步骤(4)中根据标签g从倒排索引中提取出的一个视频
               Like(u,g)表示用户u对标签g的喜爱程度。比如在本例中Like(u,“喜剧”)=0.7
               Q(v)表示视频v的质量,可以由v的各种后验消费指标来表示,比如咋本例中用点击率          
            (CTR)
    来表示视频的质量。
               Score(u,g,v)表示推荐系统猜测的用户u对视频v的喜爱程度的得分。
          公式(1-1)虽然简单,但还是具备一定的个性化能力,并非只是按照物料的质量排序。给5个视频都打完分后,推荐系统将它们根据得分按照讲叙排列,假设排序结果是[B,C,A,D,E]。
  6. 假设App前端界面一次只能显示4个视频。推荐系统对排序结果进行截断,只保留前4个视频,返回给用户
  7. 用户按照[B,C,A,D]的顺序看到了4个视频,点击并观看了视频B。用户行为,即“用户u点击视频B,A/C/D曝光未点击”,被记录进日志,发送给推荐系统。
  8. 推荐系统接收到了用户反馈,即“视频B符合我品味,不喜欢视频A、C和D”,并据此更新自己的“知识储备”,表现在以下两方面。

        更新用户的兴趣爱好。之前用户u点击了10个视频,其中7个是关于“喜剧”的,3个是关于“足球”的。现在推荐系统得知,用户u点击了带“喜剧”标签的视频B,那么他的统计数据变成了共点击11个视频,其中8个关于“喜剧”,3个关于“足球”。下次再从数据库中提取出的用户u的兴趣就变成了{“喜剧”:8/11,“足球”:3/11},“喜剧”标签权重上升,“足球”标签权重下降。下次再给该用户推荐时,推荐系统中多推一些“喜剧”内容,少推一些“足球”的内容。

        更新视频质量。视频B多了一次被点击的正向记录,相当于多了一个人背书,Q(B)因此而升高,反之视频A/C/D的质量会有所下降。根据排序公式(1-1),未来在给别的用户未见,视频B更有可能得到高分,被推荐出去。

        至此,一次推荐就完成了。

        真实的推荐系统肯定要比以上这个极简版的复杂更多。

  • 真实的推荐系统在排序时,不可能只考虑两个因素,而是要考虑来自用户、物料、上下文等上百个因素。包含上百个输入变量的公式就不太可能靠人拍脑袋想了,此时就需要借助机器学习技术自动拟合出用户反馈(比如点击)与这上百个因素之间的关系。推荐系统从此登场。
  • 真实的推荐系统所包含的步骤缓解也绝不只有召回和排序两个。召回之后,还要经过去重、粗排。排序之后的物料列表也不会直接呈现给用户,而是还要经过重排再调整一次顺序。
  • 上面的极简版推荐系统存在冷启动问题。

1.3 推荐系统架构

        推荐系统架构可细分为功能架构与数据架构。

1.3.1 功能架构

        推荐系统的目标是在庞大的候选集中为用户找出与他兴趣相符的物料。为了实现这一目标,理论上我们可以像如下这样操作。

  • 离线训练出一个精度很高的模型F,输入一个用户u和物料t,输出二者的匹配度s,即s=F(u,t)。
  • 在线服务时,对每个用户请求,我们将该用户与每个候选物料都运行一遍模型F,以得到用户与每个候选物料的匹配度,再将匹配度高的若干物料返回即可。

        以上操作只能停留在理论上,现实中时万万行不通的。原因在于大型APP有几百万、上千万的候选物料,一次请求就要进行百万级的模型运算,时间开销太大,根本无法满足线上服务的实时性要求。

        为了应为海量的候选集,现代大型推荐系统都采用有“召回-->粗排-->精排-->重排”四个环节组成的分级推荐链路,如图1-1所示。在推荐链路中越靠前的环节,其面对的候选集越大,因此需要采用技术越简单、精度稍逊、速度较快的算法,以牺牲部分精度来换取速度,推荐链路中越靠后的环节,其面对的候选集越小,有条件采用技术较复杂、精度较高、速度较慢的算法。以牺牲部分速度来换取精度。

                                                         图1-1 推荐系统的四个环节

1. 召回

        召回是推荐系统的第一个环节,面对的数据集一般要达到百万级规模。所以召回模块的第一要务就是“快”,所以精度就可能不大行了。

        召回模块主要依赖“离线计算+在线缓存”模式来实现对上百万规模候选集的快速筛选。上百万的候选物料在离线状态下就已处理好,处理结果被存入数据库并建立好索引,比如极简版推荐系统中提到的倒排索引。在线召回时,只需花费在索引中的索引时间,时间开销非常小。

        为了弥补精度的不足,召回模块一般采用多路召回的方式,数量弥补质量。每条召回路只关注用户信息或物料信息的一个侧面,比如有的只负责召回当下最火爆的内容,有的只根据用户喜欢的标签进行召回等等。。。

2. 精排

        精排是4个环节中的VIP,任务就是从上游层层海选出来的千级规模的比较符合用户兴趣的物料中,精选细选出几十个最合用户品味的物料。

        精排的设计重点是提升预测精度。所以不同于召回、粗排的不允许用户信息与物料信息交叉,精排模型的发力重点就是让物料信息与用户信息充分地交叉,为此业界在精排引入了更多的交叉特征,使用了更复杂的交叉结构。

3. 粗排

        前面说,召回的精度不足,所以用数量弥补质量,倾向于召回更多物料,送往下游。而精排位了提升预测精度,不断加大模型复杂度,而牺牲了模型的吞吐能力。物料前后⼀增⼀减的结果是, 如果让召回直接对接精排, 笨重的精排⾯对召回送来的越来越多的候选物料, 肯定会吃不消。 为了解决这⼀⽭盾, 粗排应运⽽⽣, 它接在召回后⾯, ⼀般将召回的10000个结果再过滤掉90%, 只保留最具潜⼒的1000个,再交给精排重点考察。

4. 重排

        精排时,相似内容(比如相同话题、相同标签)会被精排模型打上相近的得分,从而在结果集中排在相近的位置。如果将这样的排序结果直接呈现给用户,用户连看几条相似内容会很疲劳,从而损害用户体验。所以,精排结果还需要经过重排。与前三个环节不同,重排的主要目的不是过滤和筛选,而是调整精排结果的顺序,将相似内容打散,以保证用户在一屏之内看到的推荐结果丰富而多样。

1.3.2 数据架构

        推荐系统中的模块按照数据产生、计算、存储的不同方式进行划分,也就是推荐系统的数据架构。

        举个例子,为了让模型了解每个视频的受欢迎程度,我们计算每个视频的CTR作为特征。这个任务看起来稀松平常, 不就是数出每个视频的曝光数、 点击数, 再相除就可以了吗? 其实实践起来远没有那么简单,有以下3⽅⾯的难点。

■为了保证统计结果的有效性, 我们需要将统计窗⼜拉得⼤⼀些, ⽐如统计过去⼀周每个视频的曝光数、 点击数。 但是⼤型互联⽹系统每天产⽣的⽇志量以TB计, 要回溯的历史越长, 所涉及的计算量也就越⼤
时间上还⾮常紧张。 线上预测时, 从接收到⽤户请求到返回推荐结果的总耗时要严格限制在⼏⼗毫秒, ⽽且其中的⼤部分时间还被好⼏次模型调⽤占了,留给所有特征的准备时间不会超过10毫秒。
■ 以上所说的回溯历史指的是回溯已经存储在Hadoop分布式⽂件系统(Hadoop Distributed File
System, HDFS)
上的那部分⽇志,也就是所谓的冷数据(Cold Data)。 但受HDFS只⽀持批量读写的性质所限, 还有许多⽤户⾏为未来得及组成⽤户⽇ 志, 或者未来得及落盘在HDFS上,这就是所谓的热数据(HotData)。 ⽐如我们在下午3点想获得最新的指标数据, 但是HDFS上的⽇志只保存到截⾄下午1点, 因⽽即使计算出来也是2⼩时前的过时数据,这2⼩时的缺⼜如何填补呢?

        为了应对互联网大数据系统的复杂性,Lambda架构应运而生。目前各互联网大厂的推荐系统基本上都是按照Lambda架构或其变形架构搭建出来的。胡萝一些称谓上的差异,Lambda的技术精髓可以由以下4点来概括,如图1-2所示。

■将数据请求拆解为分别针对冷、热数据的两个⼦请求。
■针对冷数据的⼦请求,由离线层批量完成计算,其结果由近线层缓存并提供快速查询。
■针对热数据的⼦请求,由在线层基于流式算法进⾏处理。
■汇总从冷、热数据分别获得的⼦结果,得到最终的计算结果。

                                                                图1-2 Lambda架构示意

回到计算每个视频的CTR这个例子上来,我们可以将这个数据请求拆解为如下两个子请求

■在冷数据上计算代表⼀个视频V长期、稳定的受欢迎程度的 CTR ^{cold}_V
■在热数据上计算代表⼀个视频V短期、当前的受欢迎程度的 CTR^{hot}_V。                                                                

1. 离线层

        为了计算CTR ^{cold}_V,我们启动一个小时级的定时任务,每个小时都向前回溯一周的用户行为日志,统计这个时间窗口内每个视频V的曝光率与点击率,在将点击数除以曝光数就得到了CTR ^{cold}_V。为了加速,我们可以定时启动另一个小时级的批量任务,统计每个小时内每个视频的曝光率、点击率,并保存结果。有了这些小时级结果的加持,要统计一周的CTR,只需要汇总168(24*7)个中间结果就行了,而无须从头分析统计每条用户日志,计算效率大为提高。另外,这些小时级的中间结果也能够被其他上层计算任务所复用,避免重复计算。

# 举个例子
原文:为了计算CTR_cold,我们启动一个小时级的定时任务,
每个小时都向前回溯一周的用户行为日志,统计这个时间窗口内每个视频V的曝光率与点击率,
在将点击数除以曝光数就得到了CTR_cold。

假设现在是7月29日12:00,定时任务会回溯到7月22日12:00到7月29日12:00之间的用户行为日志。
统计每个视频在这段时间内的曝光率和点击率,例如:
    视频A: 曝光次数100次,点击次数10次,CTR_cold = 10/100 = 0.10
    视频B: 曝光次数200次,点击次数30次,CTR_cold = 30/200 = 0.15

原文:为了加速,我们可以定时启动另一个小时级的批量任务,
统计每个小时内每个视频的曝光率、点击率,并保存结果。


假设现在是7月29日12:00,定时任务会统计7月29日11:00到7月29日12:00之间的视频数据。例如:
    视频A: 该小时内曝光次数10次,点击次数1次
    视频B: 该小时内曝光次数20次,点击次数3次

原文:有了这些小时级结果的加持,要统计一周的CTR,只需要汇总168(24*7)个
中间结果就行了,而无须从头分析统计每条用户日志,计算效率大为提高。

假设我们已经保存了过去一周每个小时的视频曝光率和点击率结果。
现在只需汇总这些小时级结果即可。例如,汇总视频A的每小时结果:
    7月22日12:00到7月29日12:00,每小时曝光率:[10, 8, 15, ..., 12](总和为100)
    7月22日12:00到7月29日12:00,每小时点击率:[1, 0, 3, ..., 2](总和为10)
通过汇总,我们得到视频A在这一周的曝光次数为100次,点击次数为10次,CTR_cold = 10/100 = 0.10。

        以上这些定时扫描日志的批量计算任务就构成了Lambda架构中的离线层。技术上批量计算任务可以评价Hadoop、Spark、Flink等大数据框架来完成,而多个任务之间的协同可以由Airfolw来完成。

2. 近线层

        离线层计算完毕之后,所有视频过去一周的CTR还停留在HDRS上。而HDFS是一种擅长批量读写,但随机读写效率极低的存储介质,不利于线上快速读取。为了提高查询速度,我们将离线批量计算的结果导入Cassandra、Redis这样的键-值(Key-Value,KV)型数据库。这些起缓存、加速访问作用的KV数据库就构成了Lambda架构中的近线层。

        回到视频CTR这个例子中,KV数据库存储离线计算好的该视频过去一周的CTR,线上服务以每个视频的ID作为键,在其中快速检索。

3. 在线层

        前面讲,离线批量计算智能处理已经落盘在HDFS上的冷数据。但是因为HDFS只支持批量读写,所有用户行为从发生到被记录到HDFS上,其间存在着小时级的时延。

        在线层正是为了弥补这个缺口。这一层凭借Storm、Flink等流式计算框架,对接用户的行为数据流,不等数据落地,就直接对它们进行分析计算,计算结果也缓存在Redis这样的支持随机读写的数据库中,方便线上查询。大数据的就不介绍了。

1.4 搜推广的区别与联系

1.4.1 相同点

        从本质上说, 推⼴搜都是针对⽤户需求找到最匹配的信息。 只不过⽤户需求的表达⽅式决定了是推荐还是搜索, 信息服务的对象决定了是推荐搜索还是⼴告。 技术细节将在后⽂中详细介绍。 这⾥先列出推⼴搜的⼀些相同点。
■在功能架构上,推⼴搜都遵循“先由召回模块粗筛,再由排序模块精挑细选”。
■在数据架构上,推⼴搜都遵循Lambda架构。
■因为从业务本质到系统架构都⾼度相似, 所以很多算法、 模型在“推⼴搜”3个领域都是通⽤的。 在⼀个领域中发表的论⽂很容易在其他两个领域复现。 同时,由于所掌握的技术栈也是相同的, ⼀个领域的⼯程师也很容易转向其他两个领域。
■推⼴搜都需要⾼度的个性化。 ⼤家对个性化推荐已经习以为常了, 事实上⼴告对个性化的需求更⾼。 毕竟如果推荐结果不符合⽤户兴趣, 只会有损⽤户体验, ⽽如果⼴告不满⾜⽤户需求的话, 浪费的可是真⾦⽩银。 搜索也不能仅满⾜于返回的⽂档包含搜索关键词。 ⽐如不同⽤户搜索“苹果价格”, 显⽰的结果肯定是不同的, ⾄于显⽰的是⽔果价格还是⼿机价格, 就取决于搜索系统对⽤户画像的掌握与利⽤。

1.4.2 推荐与搜索

        推荐与搜索两种场景的最大差异在于用户表达其意图的方式不同。搜索中,用户通过输入查询语句显式表达其意图,如公式(1-2)所示
                                                                F_{search}(t|q,u)                                                        (1-2)

其中,u表示当前用户,q表示用户输入的查询语句,t表示某一个候选物料。F_search表示搜索模型,衡量物料t对用户u输入的查询q的匹配程度。

        注意,用户信息u也是公式的输入条件。不同用户输入相同的查询语句q,得到的结果是不一样的,这正是个性化搜索的体现。

        而推荐中,用户无须显式表达其意图。推荐系统通过自己的长期观察,猜测用户意图,完成推荐,如公式(1-3)所示

                                                                F_{recommend}(t|u)                                                        (1-3)

其中,F_recommend表示推荐模型。

1.4.3 搜推与广告

        搜推是为了留住用户来产生流量,所以所服务的目标比较简单,就是为了给用户提供最佳使用体验。而广告是为了将流量变现,所以要兼顾用户、广告主、平台三方的利益,参与方更多、更复杂,优化起来难度更高。

      

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值