召回模型中的负样本构造

阿泽的学习笔记

共 2870字,需浏览 6分钟

 · 2021-12-23


最近工作在集中做召回模型,对整个数据流、业务、模型都有了一些新的认识,打算慢慢整理一下,本文先聊聊召回中负样本选取的问题。

1. 简述召回

1.1 召回负样本和精排有什么区别

召回/粗排/精排我就不多介绍了,但是可能很多人并不知道不同阶段训练样本有什么差别。对于CTR目标最通用的做法:

  • 精排:正样本-真实点击   负样本-真实未点击

  • 粗排:根据模型不同有不同的方法,比如使用蒸馏的话和精排样本一致,非蒸馏也可以用级联样本等,不作此文重点。

  • 召回:正样本-真实点击  负样本-真实未点击+负采样

可以看到召回是要做采样的,其原因是:离线训练数据要和线上分布尽可能一致,虽然曝光未点击肯定是负样本,但是还有很多视频未曝光,同时因为推荐系统bias的存在可能某些样本你永远学不到,负采样的目的就是尽量符合线上真实分布,要让模型“见见世面“。

1.2 召回怎么traning和serving

一般来说工业界都是多路召回,现在主流比较偏好向量化召回。至于怎么生成向量有很多种方法,比如FM/双塔等,本质都是线上做近邻索引,因为也不是本文的重点,直接甩几个链接简单说下

  • 遍历计算相似度太慢,所以会使用近邻查找算法,彼此之间各有优劣向量召回—近邻快速查找算法总结

  • FM/FFM公式里有bias项,在serving的时候也不是单纯的 uemb * g_emb,serving时可以做一些简化聊聊向量化召回的一些工程经验

  • NN双塔召回和FM相比有优势和劣势,主要优势在于更容易添加特征和修改模型结构,泛化更好,但是可解释性和资源占用会差一些,对架构有要求。

  • 因为做了负采样,所以预估的auc会偏高,负采样的正负例先验概率之比多了一个r因子,根据数据流正负例拼接的方法是窗口or其他,训练时sample_logit需要做一些改改动,可以自己推一下公式。

1.3 如何评估召回的效果

最好肯定是线上ab,但是ps资源和线上流量都有限,最近我也一直在思考怎么离线评估召回,提一些我的想法:

  • 首先auc高并不代表召回的好,实际上好的召回可能auc低一些,但是会召回出更符合真实分布的内容,实际工作中auc当作参考就好。

  • 拿Top K召回结果与用户实际点击做交集并计算precision/recall,感觉现在大多都是用的这个方法,但是我总感觉极端条件下N路召回全都100%准确率召回率,那其实5路变成1路就好了,而且完全在拟合精排,又陷入了无探索的困境,因为召回的结果未被用户点击,未必说明用户不喜欢,而可能是由于该召回结果压根没有给用户曝光过。

  • 召回diff率。其实我现在还比较喜欢拿这个来预估要不要上线,因为diff高才有bagging一路召回的价值(当然还有是否保送,精排是否能排出来的问题)

  • 人肉debug:最近搞了一个模型,自己经常会拿组里同学的uid来打印召回结果,然后人肉评估一下靠不靠谱。虽然有点蠢,但是确实能帮我验证模型/机制做没做对,也能有个摸底的效果。

1.4 一些工程上的东西

  • 一般打正label会有回流延迟,所有非正标签要等待一个时间窗口,由此会出现两个问题,一是可能窗口外正例损失掉了,二是实时性有损,所以有时候正样本也会发一次负例。

  • 负样本应该选客户端负例,而不是服务端负例,比如服务端返回了5条视频但是可能只有2条被看到,则剩下三条实际上没曝光

  • 用户最后一次点击位置之后的展现可以考虑去掉,因为用户可能压根没看

  • 尽量使用线上模型预测时的特征,而不是离线回溯,因为可能导致某些实时特征和统计特征出现偏差

2. 一些常用的采样方法

其实总结下来还是提高负例难度,在网上简单搜了下没找到比较通用的学术落地paper(如果有的话可以留言一下)。随后看了看公司其他产品线的工作,感觉有一些业务逻辑采样的方式还挺有效的,以及一些样本拼接和模型traing/ANN的改造也能解决特定的召回问题,不过这部分就不能放外网了,以下是能在公网搜到且我觉得靠谱的三种方法。

2.1 随机负采样

应该是最简单的一种实现方式,当然工程中实现起来也有一些要注意的地方,比如之前mentor让我看采样代码我才发现一些小细节。

但整体来说,随机负采样能够解决本文最开始提到的“开开眼”,但是由于高热/人群偏差等,纯随机还是不太好,有较大的bias,且负例不够难,只能学到粗粒度上差异,对小众不友好。

理想情况下,比较强的正/负例让模型学到正向特殊性,菜一些的正/负例让模型见见世面,菜的容易搞,强的怎么弄呢?可以有一些易实现的采样思路:

  • 热门物料做正样本时,要降采样,防止所有人的召回结果都集中于少数热门物料

  • 当热门物料做负样本时,要适当过采样,增加负样本难度

2.2 业务逻辑选取负样本

Airbnb在《Real-time Personalization using Embeddings for Search Ranking at Airbnb》一文中的做法。

  • 增加与正样本同城的房间作为负样本,增强了正负样本在地域上的相似性,加大了模型的学习难度

  • 增加“被房主拒绝”作为负样本,增强了正负样本在“匹配用户兴趣爱好”上的相似性,加大了模型的学习难度

2.3 用上一版召回中后段的样本作为额外负样本

来源是百度Mobius和facebook的[Embedding-based Retrieval in Facebook Search],我感觉make sense,毕竟粗排也有级联样本训得,有没有效可以之后试试。

3. 召回搞完后,后续链路要做什么

新的召回即使效果不错,但也未必能排出来,主要原因是排序模型是在已有召回算法筛选过的数据的基础上训练出来的。我在实际工作中也遇到了类似情况,明明召回很准,但是排出来的都是靠后比较菜的,所以优化召回后,也要对排序、融合公式等进行调整才能最大化召回的收益,但是每上一个召回都再调精排和融合公式,还要大流量看AA才能生效,感觉周期太长成本太高。

我比较粗浅的想法是:

  • 粗排保送一下看看线上消费核心指标和其他路召回的对比,如果核心不错可以放流量看aa是否有放大

  • 先强插或者定坑看一下效果,与保送目的一致,区别在于粗排保送不能保证精排一定可排出,强插是一定保证可展现的。

  • 如果排序模型本身就可以引入召回的信息,比如DMR模型把match和rank融合到一起,可能会效果不错。因为我也发现了一些case让我觉得引入召回还是比较有必要的,之前在阿里实习的组里这样的模型也确实有收益——阿里1688的论文中把排序引入到精排的一个特征中,以辅助网络的形式训练【Deep Match to Rank Model for Personalized Click-Through Rate Prediction】,而在淘宝直播中则是最后在loss叠加深度排序模型在淘宝直播的演进与应用

浏览 100
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报