在推荐系统中一般会分为召回和排序两个阶段:
召回
召回的目标是从千万级甚至亿级的候选中召回几千个item,召回一般由多路组成,每一路会有不同的侧重点(优化目标),如在广告中成熟期广告和冷启动广告分为两路召回(如果广告比较多,还可能分冷热广告分别召回)。在推荐系统,不同路可能代表了不同的优化目标,如喜欢、关注、观看时长、评论这些都可以分不同的路召回。
目前召回常用的方法有:协同过滤、FM、FFM、图模型、双塔模型、还有YouTube在2017年论文中提出的DNN模型、字节的Deep Retrieval算法等
在工业届,常常会用FM、双塔模型等先学习user embedding、和 item embedding,然后用ball tree、fast ball tree 等近似最近邻算法进行检索,加快效率
排序
排序阶段就是把召回的结果进行排序,把top k(k 一般都是个位数)结果作为推荐系统最终的输出。
排序阶段常用的算法:LR -> FM -> deepFM等
为什么要把排序分为精排和粗排?
把排序阶段分为粗排和精排,其实就是生成环境中成本和结果的一个平衡。进入排序阶段的候选集一般确实只有几千个,但是对于抖音、YouTube这种量级的应用来说,他们request是非常多的,依然不能上太复杂的模型和特征。
因此把排序分为粗排和精排:
粗排漏斗一般是: 几千 -> 几百
精排漏斗一般是:几百 -> 几个
这样精排可以把模型和特征做到极致,可以达到非常高的精度
召回和粗排的差别在哪里?
1. 建模目标不同
召回是漏斗的最上游,可以说是决定了推荐系统的上限
召回的目标是召回用户可能感兴趣的 item,会考虑多方面的因素
粗排是对召回的结果进行排序,top k 送入精排,常用的有两种建模方式:
1. 独立建模,如在在广告推荐中,粗排也是优化ecpm,在推荐中也是优化Finish、Staytime等
2. 对齐精排,用 leaning to rank 等方法去学习精排的序
2. 正负样本的选择不同
如果说召回决定了推荐系统的上线的话,那么可以说样本的构造决定了模型的上限
先看召回阶段:
正样本一般选择用户有正反馈的样本,如ctr中用户点击了的作为正样本,like中用户点了喜欢的作为正样本
但是负样本该怎么选呢?
最简单的方法就是把send给用户后,用户没有正反馈的样本作为负样本。但是这样会带来一个问题,那就是召回模型在training和serving面临的样本分布是不一样的,违反了机器学习的基本原则。
具体的来说就是,真正被send给用户的item只占所有item非常小的一部分,召回模型在serving时会面临很多它以前从来没有见过的样本,召回模型在这些样本上会很难区分
怎么解决这个问题呢?
通常的方法就是从召回的池子中进行随机采样,具体做法待补充
再来看粗排:
粗排的基本目标一般是对其精排,所以可以把精排的top k 个样本作为正样本,然后从精排中其它样本中随机采样,作为负样本
粗排对其精排本身没有太大问题,但是这里也有一个ee(exploit-explore)问题,如果粗排完全对其精排的话,可能会导致模型探索不足,为了缓解这个问题,我们可以适当补充一些进入召回但是没有进精排的样本作为负样本