负样本为王:评Facebook的向量化召回算法

2022-01-11  本文已影响0人  JackHorse

转自https://zhuanlan.zhihu.com/p/165064102,阅读使用
有人的地方就会有江湖,就会有鄙视链存在,推荐系统中也不例外。排序、召回,尽管只是革命分工不同,但是我感觉待遇还是相差蛮大的

总之,我感觉,排序更受关注,很多问题被研究得更透彻。而召回,尽管"召回不存,排序焉附",地位相当重要,但是受关注少,有好多基本问题还没有研究清楚。比如接下来,我们要谈到的,诸如“拿什么样的样本训练召回模型”这样的基本问题,很多人还存在误区,习惯性照搬排序的方法,适得其反

在这种情况下,2020年Facebook最新的论文《Embedding-based Retrieval in Facebook Search》(EBR)更显难能可贵,值得每个做召回算法的同行仔细阅读。正所谓“实践出真知”,文中涉及的部分问题,哪怕你有推荐算法经验但只做过排序(比如一年前的我),都压根不会意识到,更不能给出解决方案。而在你实践过召回算法,特别是向量化召回之后,方能感觉到这篇文章切中召回工作中的痛点,“对症下药”。

所以,今天我将解读一下Facebook EBR这篇经典论文。论文解读不是简单的翻译(这年头,谁还看不懂个英文呢?),而是结合自己的亲身实践,把论文中一笔带过的地方讲透,补充论文中忽略的细节,列举针对相同问题业界其他的解决方案,算是论文原文的一个补充。

简述Facebook EBR模型

这篇论文非常全面,涵盖了一个召回从样本筛选、特征工程、模型设计、离线评估、在线Serving的全流程。但在我看来,并非每部分都是重点。论文中的某些作法就是召回算法的标配。在详细论文EBR的重点之前,我还是将这个模型简单描述一下。

重中之重是"筛选(负)样本"

简单描述之后,才进入本文的华彩段落,即Training Data Mining。单单Mining一个词,感觉就比Sample Filtering高大上了许多,也让你感觉到这件工作的艰巨,远不是“过滤脏数据”那么简单。本文最精彩的部分就是对样本的筛选。如果说排序是特征的艺术,那么召回就是样本的艺术,特别是负样本的艺术。样本选择错了,那么上述的模型设计、特征工程,只能是南辕北辙,做得越卖力,错得越离谱。本文在“样本筛选”上的贡献有三:

本文的另外两个贡献也算是“样本筛选”的引申:

为什么不能(只)拿"曝光未点击"做负样本

我曾经做过Youtube召回,当时就特别不理解为什么Youtube不用“曝光未点击”做负样本,而是拿抽样结果做负样本。而且这样做的还不仅仅Youtube一家,Microsoft的DSSM中的负样本也是随机抽取来的。两篇文章都没说明这样选择负样本的原因。

当时,我只有排序方面的经验,而排序是非常讲究所谓的“真负”样本的,即必须拿“曝光未点击”的样本做负样本。为此,还有所谓above click的作法,即只拿点击文章以上的未点击文章做负样本。所以,排序思维根深蒂固的我,觉得拿“曝光未点击”做负样本,简直是天经地义,何况还那么有诱惑力

所以,当我第一次实践Youtube算法时,直接拿“曝光未点击”样本做负样本,训练出来的模型,离线AUC达到0.7+,做为一个特征简化的召回模型,已经算是非常高了,但是线上表现一塌糊涂。离线评测时,发现召回的物料与用户画像、用户点击历史,完全没有相关性。而当我抱着“照着论文画瓢”拿随机采样的样本做负样本,线上结果却非常好。

何也???其实,是因为我自以为是的做法,违反了机器学习的一条基本原则,就是离线训练数据的分布,应该与线上实际应用的数据,保持一致

以前,我们谈到召回与排序的不同,往往只强调速度,即因为召回的候选集更大,所以要求速度更快,所以模型可以简单一些。这是只知其一。另一个方面,起码之前是我没有深刻意识到的,就是

所以,要求喂入召回模型的样本,既要让模型见过<user,doc>最匹配的,也要让模型见过<user,doc>最不靠谱的,才能让模型达到"开眼界、见世面"的目的,从而在“大是大非”上不犯错误。

就好比:一个老学究,一辈子待在象牙塔中,查古籍,访高人,能够一眼看出一件文物是“西周”的还是“东周”的。但是这样的老学究,到了潘家园,却很可能打眼,看不出一件文物是“上周”的。为什么?他一辈子只见过“老的”和“更老的”,“新的”?被象牙塔那阅人无数的门卫给屏蔽了,他压根就没见过

拿随机采样做负样本

所以文章中描述的基本版本就是拿点击样本做正样本,拿随机采样做负样本。因为线上召回时,候选库里大多数的物料是与用户八杆子打不着的,随机抽样能够很好地模拟这一分布。

但是文章中没有说明随机抽样的概率,千万不要以为是在整个候选库里等概率抽样

NLP背景的同学看以上两个采样公式是不是有点眼熟?没错,它们就是word2vec中所采用的采样公式。没错,word2vec也可以看成一个召回问题,由center word在整个词典中召回context word。

但是,使用随机采样做负样本,也有其缺点,即与d_+相比,d_-与user太不匹配了。这样训练出来的模型,只能学到粗粒度上的差异,却无法感知到细微差别。就好比,一个推荐宠物的算法,能够正确做到向爱狗人士推荐狗,向爱猫人士推荐猫,但是在推荐狗的时候,无法精确感受到用户偏好上的细微差别,将各个犬种一视同仁地推出去。这样的推荐算法,用户也不会买账。

挖掘Hard Negative增强样本

将<user,doc>的匹配度分成三个档次

如何选取hard negative,业界有不同的做法。Airbnb在《Real-time Personalization using Embeddings for Search Ranking at Airbnb》一文中的做法,就是根据业务逻辑来选取hard negative

当业务逻辑没有那么明显的信号时,就只能依靠模型自己来挖掘。这也是本文与百度Mobius的作法,二者的作法极其相似,都是用上一版本的召回模型筛选出"没那么相似"的<user,doc>对,作为额外负样本,训练下一版本召回模型

可能有人还有疑问,这样选择出来的hard negative已经被当前模型判断为“没那么相似”了,那拿它们作为负样本训练模型,还能提供额外信息吗?能起到改善模型的作用吗?

不过需要特别强调的是,hard negative并非要替代easy negative,而是easy negative的补充。在数量上,负样本还是以easy negative为主,文章中经验是将比例维持在easy:hard=100:1。毕竟线上召回时,库里绝大多数的物料是与用户八杆子打不着的easy negative,保证easy negative的数量优势,才能hold住模型的及格线。

不同难度的模型相互融合

上一节只是从“样本增强”的角度来利用hard negative。还有一种思路,就是用不同难度的negative训练不同难度的模型,再做多模型的融合。

并行融合

不同难度的模型独立打分,最终取Top K的分数依据是多模型打分的加权和(各模型的权重是超参,需要手工调整):S_w(q,d)=\sum_{i=1}^n\alpha_icos(V_{q,i},U_{d,i})

但是线上召回时,为了能够使用FAISS,必须将多个模型产出的embedding融合成一个向量。做法也非常简单,将权重乘在user embedding或item embedding一侧,然后将各个模型产出的embedding拼接起来,再喂入FAISS。这样做,能够保证拼接向量之间的cosine,与各单独向量cosine之后的加权和,成正比。

image

easy model肯定是拿随机采样训练出来的模型,这个没有异议。问题是hard model是哪一个?

串行融合

其实就是粗排,候选物料先经过easy model的初筛,再经过hard model的二次筛选,剩余结果再交给下游,更复杂的粗排或是精排。

根据文章中的经验,使用“曝光未点击”作hard negative训练出来的hard model同样没有效果,反而是挖掘出来的hard negative训练出来的hard model做二次筛选更加有效。

全链路优化

这一节切切实实触到了我们召回工作中的痛点,就是新的召回算法,往往不受ranker的待见

但是本文针对这一问题的解决方案有限:

总而言之,各路召回之间的重叠、竞争,召回与排序之间的“相爱相杀”,将会是推荐系统内一个无解的永恒话题。

"曝光未点击"就是鸡肋

最后说一下“曝光未点击”样本。在排序中,“曝光未点击”是要被严格筛选的“真负”样本,对于排序模型的成败,至关重要。而到了召回中,无论是根据我自己的亲身实践还是Facebook的经验,“曝光未点击”样本都是妥妥的鸡肋,“食之无味,弃之可惜”

导致“曝光未点击”成为鸡肋的原因,可能是由于它的两面性:

“曝光未点击”样本的两面性,使它们既不能成为合格的正样本,也不能成为合格的负样本。唉,“大是大非”面前,“骑墙派”总是不受欢迎的

总结

很高兴能看到一篇论文,契合了你之前的实践和经验,不由得生出“英雄所见略同”的慨叹,特别是在“召回”这一重要但是受关注较少的领域。

我给本文起名为"负样本为王",就是想传递这样的观点:如果说排序是特征的艺术,那么召回就是样本的艺术,特别是负样本的艺术。负样本的选择对于召回算法的成败是决定性的,

至于怎么选对样本,Facebook的这篇论文是难得的来自一线实践的经验之谈,值得每个做召回的算法同行认真阅读。

上一篇 下一篇

猜你喜欢

热点阅读