2.2 召回、粗排、精排——级联漏斗
把表现好的物料的曝光进一步提高是推荐模型的基本能力,也是基本要求。把表现差的物料的曝光提高也可能是好模型,但表现好的物料的曝光没提高,就说明有很多问题。
在初始阶段,物料之间哪个能最快得到精排的认可,哪个就有可能在冷启动阶段占据压倒性优势。
召回区分主路和旁路,主路的作用是个性化+服务后链路,而旁路的作用是查缺补漏。
推荐系统的前几个操作可能就决定了整个推荐系统的走向,在初期一定要三思而后行。
前面说过,整个推荐系统的链路是一个大漏斗,前面召回的入口最多,最后精排仅仅输出一点点。接下来对漏斗的连接部分做更细致的分析,包括精排、粗排、召回的学习目标、评价标准分别是什么等。
虽然整个链路的推理过程是从前往后的,但是进行迭代改进的时候却往往是倒着往前的。(读者可以回答出此处的原因吗?)假如想添加某种特征,那么先由精排验证有效,然后粗排再添加。召回可以不按照这个规则走,因为召回在很多时候是觉得上面的队列里缺少哪一方面的东西,才多这一路的。
以CTR预估为例,精排学习目标的范围一般是所有存在曝光的样本。有曝光但没有点击的是负样本,有曝光也有点击的就是正样本。在其他目标中可以以此类推:如CVR预估,点击了但没转化的是负样本,点击了也转化的就是正样本。
精排模型输出的结果,线下可以由曲面下面积(Area Under the Curve,AUC)进行评估。在“Optimized Cost per Click in Taobao Display Advertising”[1]中,阿里巴巴的推荐算法工程师们提出了另一个评价指标——Group AUC(GAUC),如下:
式中,w代表的是曝光数或点击数;p的原意是对展示的位置进行区分,简化的版本可以只对用户进行区分。GAUC的计算过程就是对每一个用户按照曝光进行加权及归一化处理,活跃度高的用户对它的影响更大。
线上目标则根据具体业务有所不同,如在短视频平台上,参考的就是累计观看时长,广告参考的是收入,而在电商平台上参考的是商品交易总额(Gross Merchandise Volume,GMV)。线上提升是由线下的一个一个模型提升带来的,如在广告场景下,既要提升CTR,又要提升CVR,也要改善出价机制;在推荐场景下,既要提升对观看时长的预估,又要提升用户正、负反馈(如点赞、关注这些目标)的预估。
精排在训练时,把每次展现都当作一条样本,建模成分类任务,按照“点击”或“不点击”做二分类。在一个CTR预估模型中,正样本可能是非常稀疏的。对模型来说,当遇到正样本时,它必须把结果归因到当前的用户和物料上,也就是说,相比于没有点击的样本,某物料更容易得到模型的认可。那么在接下来的预估中,该物料自然得到更多的青睐,排序更加靠前。这个过程提升了其获得曝光的能力,也是推荐系统的一个基本性质:正反馈的能力,指的是对于一开始表现较好的物料,它们的排序更靠前,曝光会进一步提升。这里的“表现”指的是展现后的各种数据指标,有时候也用“后验”来表示。注意“一开始”这三个字,所谓的“一开始”表明该物料不一定是一个真正好的素材,而这会引发下面的问题(同时这里留一个思考题,正反馈会无限地持续下去吗?答案在决策篇,在专门讲物料的生命周期中揭晓)。
问题一:真值不够置信。推荐系统需要足够多的曝光数据才能评价一个物料的质量是否好,但是推荐系统整体的曝光机会往往是有限的。给A的曝光多必然意味着给B的曝光少,因此有很多物料会在没有得到充分曝光的情况下被淘汰。有的物料可能质量是不错的,但是在一开始因为随机,或者精排模型预估不准,导致最初的量没起来。此时有其他物料迅速吸引了精排的倾向,这个不幸运的物料就只能慢慢被淘汰。物料展示过程中的干扰因素如图2-3所示。
上述的问题不仅平台知道,广告主们也知道。因此优化素材的同时,也会进行大量的重试,即同样的素材内容,换一个ID再来一遍[3]。当大量的广告主这样做了之后,平台资源就会被极大地浪费,因此平台也会想出各种策略来阻止这件事情。
图2-3 物料展示过程中的干扰因素
问题二:自激。从上面的叙述中可以看出精排学习的目标特点是正、负样本都来自已经曝光的样本,而曝光与否是谁决定的呢?是精排自己决定的。这就造成了“自己学自己”的问题,学习的目标本来就是自己产生的,那么在自己原本的大方向上就有可能错到底。设想有A、B两个候选,实际上B是一个更优秀的素材,因为推荐系统随机性或精排的缺陷,A获得了更多的曝光量,而B只获得了很少的曝光量,且B恰好在这几个曝光量中都没获得什么正反馈,那么接下来B就会处于劣势。根据我们上面说的正反馈特性,A的曝光会越来越高,正向的点击数据越来越多,而B被淘汰掉。这个情况如果不断恶化,推荐系统可能会陷入局部最优中出不来,也就是我们说的“自激”:它认为A好,所以给了A更好的条件,而A自然获得了更好的反馈,又再一次验证了推荐系统的“正确性”,最终它在A比B好的错误路线上越走越远。
有什么办法可以防止上面的情况呢?一般来说有两种方法:第一种是策略的干涉,有的策略会强制一定的探索量,如上面B的曝光不能低于100,这样会缓解一些学习错误的问题。虽然还有个别物料的排序会学错,但整体上发生错误的概率会变低;第二种做法是开辟随机流量,即有一定比例的请求不通过任何模型预估,直接随机展示,观察CTR。开辟随机流量的结果一方面可以认为是完全真实、完全无偏差的训练样本,另一方面也可以对照当前模型的效果。
讲完了精排部分,我们再来讲粗排部分。粗排的学习目标是精排的输出结果。在比较简单的方案中,粗排也可以直接学习后验数据。学习精排输出的原因是粗排决定不了输出,而后验是精排控制的,粗排只能参考链路中它的下一个环节。粗排只是精排的一个影子,就像上面提到的,要不是精排不能评估所有样本,也不会需要粗排,因此粗排只要和精排保持步调一致就完成了它的大部分任务。如果粗排排序高,精排排序也高,那么粗排就很好地实现了“帮助精排缓冲”的目的;反之,如果粗排排序低,精排反而排得高,那么两个链路之间就会存在冲突。
粗排需要两个或一组样本进行学习。假如精排的队列中有100个排好序的样本,我们可以在前10个里面取出一个A作为好样本,再从后10个里面取出一个B作为坏样本。粗排的目标就是让自己也认为A好于B。越是这样,它就和精排越像,就越能帮精排分担压力。此时就不是一个分类任务了,而是学习排序(Learning to Rank)的一种方法,Pair-wise的学习,目标是让上面的A和B之间的差距尽可能大[4]。这里先提一下Pair-wise的学习过程如何实现。我们把两个样本记为x1和x2,做差之后代入一个二元交叉熵损失函数(Binary Cross Entropy loss fuction,BCE):
式中,y表示标签。若A优于B,y=1,此时该损失函数会驱使A的得分高于B,反之y=0。σ是Sigmoid函数。注意在这样的设计下,可能把没有曝光的样本纳入训练范围。粗排的入口比精排大,训练样本也比它多。粗排学习过程的示意图如图2-4所示。
图2-4 粗排学习过程的示意图
既然粗排学习的目标是精排的输出,那么对粗排的评估自然就是其学精排学得像不像,在线下可以有两种指标来评估:第一种是归一化折损累积增益(N ormalized Discounted Cumulative Gain,NDCG),它是一种评价两个排序相似度的指标,就是把精排输出的样本让粗排预测一遍,看看粗排输出的排序结果和精排有多像;第二种是召回率,或者重叠率(也可以用交并比等),即精排输出的前K(也叫Top-K)有多少在粗排输出的前K里面,也用来评价两个模型的输出像不像。相比之下,NDCG是一种更细致的指标。我们可以认为NDCG不仅刻画了Top-K的召回,也刻画了Top K-1、K-2等的召回。
召回稍微有些复杂,因为召回是多路的,而且区分主路和旁路。首先要解释主路和旁路的差别,主路的意义和粗排类似,可以看成一个入口更大,但模型更加简单的粗排,为粗排分担压力;但是旁路却不是这样的,旁路出现的时机往往是在主路存在某种机制上的问题,而单靠现在的模型很难解决的时候。举个例子,主路召回学得不错,但是它可能由于某种原因,特别讨厌影视剧片段这一类内容,导致这类视频无法上升到粗排上(可以说存在某种不好的偏差),那么整个推荐系统推不出影视剧片段就是一个问题。从多路召回的角度来讲,我们可能需要单加一路专门召回影视剧片段,并且规定:主路召回只能出3000个,这一路新加的固定出500个,两边合并起来进入粗排。这个例子是出现旁路的一个动机。增加旁路召回的动机过程如图2-5所示。
图2-5 增加旁路召回的动机过程
在上面的图中,梯形的大小表示透出率(即展现的物料中有多少是该路召回提供的)的大小。
那么召回都有哪些种类呢?第一种召回是非个性化的,如对于新用户,我们要确保用最高质量的视频把他们留住,那么我们可以划一个精品池出来,根据某种热度排序,作为一路召回。做法就是,当新用户每次发出请求时,我们都把这些精品池的内容当作结果送给粗排。这样的召回做起来最容易,用数据库技术就可以完成。
第二种召回是item to item,简称i2i,item就是物料。严格意义上应该叫user to item to item(u2i2i),指的是用用户的历史交互物料来找相似的物料,如把用户过去点赞过的视频拿出来,去找在画面、背景音乐或者用户行为结构上相似的视频,等于认为用户还会喜欢看同样类型的视频。这种召回,既可以从内容上建立相似关系(利用深度学习),也可以用现在比较火的图计算来构建关系。这种召回的负担比较小,图像上物料间的相似完全可以离线计算,甚至相似关系不会随着时间变化。
第三种召回是user to item(u2i),即纯粹从用户和物料的关系出发。双塔就是一个典型的u2i。当用户的请求过来时,双塔先计算出用户的表示嵌入,然后去一个事先存好的物料表示嵌入的空间,寻找最相似的一批拿出来。由于要实时计算用户特征,它的负担要大于前面两者,但这种召回的个性化程度最高,实践中的效果也是非常好的。一般情况下,个性化程度最高的双塔都会成为主路。它的学习目标可以类比粗排和精排的关系去学习召回和粗排的关系,而基于图计算和图像相似度的召回,则有各自的学习目标。
对主路召回的评价可以采用类似粗排的方式,以粗排的排序计算NDCG,或者Top-K重叠率。但是旁路召回在线下是难以评估的,如果采用一样的方式评估旁路,旁路的作用岂不是和主路差不多?那么旁路就没有意义,不如把改进点加到主路里面去。在实践中,旁路召回虽然在线下也会计算自己的AUC、NDCG等指标,但往往都只是作为一个参考,还是要靠线上试验来验证这路召回是不是有用。
在线上,除了A、B需要看效果,还有一个指标是召回需要注意的:透出率,指的是在最终展示的效果中,有多少比例是由这一路召回提供的。如果新建了一路召回,其透出率能达到30%,A、B效果也比较好,那么我们可以说这一路召回补充了原来推荐系统的一些不足。反过来,如果透出率只有1%、2%左右,那么不管A、B效果是涨还是跌,都很难说其效果和这一路召回有关系,似乎也没有新加的必要。
多个召回之间的结果在融合时要进行去重,可能有多路返回同样的候选,此时要去掉冗余的部分。但是,去重的步骤是需要经过设计的,有以下几种方法来进行融合。
(1)先来后到:按照人为设计,或者业务经验来指定一个顺序,先取哪一路,再取哪一路。后面取时如果发现结果在前面已经有了,就去重。
(2)按照每一路的得分平均:比如第一路输出YA=0.6,YB=0.4;第二路输出YB=0.6,YC=0.4。那么由于B出现了两次,B就需要平均一下,最后得到YA=0.6,YB=0.5,YC=0.4。
(3)投票:和上面的例子类似,由于B出现了两次,所以我们认为B获得了两个方面的认可,因此它的排序是最靠前的。
假设有三路召回A、B、C,在当前时空,业务部署的顺序是A—B—C;在另一个平行时空,业务的部署顺序是C—B—A。有个问题:在其他变量都不变的情况下,最终业务的收益是一样的吗?
笔者个人的理解是,几乎不会一样。先部署的召回会影响整个推荐系统,后来的部署不管是何种方案,都要在不利于自己的情况下“客场作战”。举一个极端的例子,A是一个特别喜欢短视频的召回,第一版实现的是它。结果A上线以后,不喜欢短视频的用户全都离开了。在迭代的过程中可能就会想到,是不是可以加一路B来专门召回长一点的视频。这时候上线B无法获得正反馈,因为喜欢长视频的用户已经不在这里了。这是部署顺序给整个推荐系统带来后效性的一个极端例子。如果我们一开始换一种做法,先上一路没什么明显偏差的召回C,然后把A、B都当作补充的旁路加进去,效果有可能更好。
因此在最初的时候,操作一定要小心,否则会给迭代带来很大的后续负担,如上面的例子就是为初期的不正确决定买单。这个问题虽然在粗排、精排时也会出现,但是在实践中召回这里更容易出现,因为召回的某些方法实现很快,很可能一看有收益就推上去了。
以上讲的漏斗都基于物料筛选的角度,而从生产者的角度看,存在这么一个漏斗。生产者的漏斗获利的程度受到入口大小和漏斗形状的影响如图2-6所示。
图2-6 生产者的漏斗获利的程度受到入口大小和漏斗形状的影响
一开始是吸引所面向的人群,然后一部分用户会点击,点击的一部分会转化,可能后面会有深度转化等,最终目的是获利。这里要说明一下,深度转化是相对于某些行业才有的,如电商行业的转化就是发生了购买行为,那么已经获利了就不需要后面的环节了;而对于游戏行业,转化一般指的是下载,用户后续付费购买增值服务是深度转化,此时才算真正获利。
图2-6所示的漏斗中有两个因素决定最终获利的大小:一个是入口的规模,另一个是梯形的斜率。其实在图中,梯形的斜率就可以表示CTR和CVR的大小。如果产品很好,这两个指标很高,那么留下来的用户就越多,越能获利。但是CTR、CVR这些东西很难优化(虽然大品牌都有专门的团队来负责)。更多的生产者选择了更简单的变量:赛道决定漏斗入口大小。
可以用文章平台作为一个例子:一般来说,评论是一个很稀疏的行为,假设每10个点赞有1个评论(这样评论率就是10%,这是一个非常高的比例),每10个浏览有1个点赞。如果想要获得100个评论,就至少需要10000个感兴趣的读者。此时文章的内容就决定了门槛高低和漏斗入口大小。假如是科技类内容,想找到10000个读者很难,但如果是新闻就很简单,所以这就形成了自媒体的一个现象:选择低门槛。他们往往选择美妆、篮球这样的领域进行创作。因为漏斗的入口足够大,哪个女生不想好看呢?观看篮球又不需要上场去打,也不需要思考,门槛也很低。入口足够大,才能保证在链路的最后还有用户剩下来。