在推荐系统中一般会分为召回和排序两个阶段:

召回

召回的目标是从千万级甚至亿级的候选中召回几千个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)问题,如果粗排完全对其精排的话,可能会导致模型探索不足,为了缓解这个问题,我们可以适当补充一些进入召回但是没有进精排的样本作为负样本