1 背景
在推荐系统中,i2i
类型的召回往往在多路召回中扮演中重要的角色,具有效率高、覆盖广、可解释、易调控等优势。常用的算法一般有swing
,icf
,wbcos
以及item2vec
等,虽然不同算法逻辑不同,实际上构建的倒排结果往往具有一定的重复,并且多路 i2i 在线上并存往往也会带来维护成本高,迭代效率低等问题。那么,ranki2i
是较为通用的将各种 i2i 有效整合到一起的一种方案。
2 算法逻辑
ranki2i
算法承载着两个目标:
- 合并分散的 i2i 召回;
- 提高 i2i 召回效率。
为了完成上述 2 个目标,相应的转化成以下两个方案:
- 构建一个 i2i 预估模型;
- 对所有的 i2i 候选 pair 对进行预估构建截断倒排结果。
2.1 样本
因为最终是构建 i2i 的预估模型,那么重点的数据来源便是 i2i 后验数据,主要有以下 2 种:
- 推荐中已有的 i2i 行为日志数据(线上已有 i2i 类召回);
- 相关推荐等场景的 i2i 行为日志(线上无 i2i 召回)。
一般第 1 类样本更重要,效果要更好,这也符合训练和预估任务一致性的要求。
但无论哪一种,我们都可以从对应日志中提取 user-trigger_item-target_item-label
结构的归因样本。也即某个用户看过某个 trigger_item 后,对于其相关的 target_item 的偏好结果 label 是什么。
如此便有了 ranki2i 正样本(曝光点击)和负样本(曝光未点击),但是和其他召回模型类似,只使用曝光的数据来构建样本往往是有偏的。对于负样本我们还需要大量的负采样,一般可以是全局负采样或 in-batch 负采样,具体 hard neg 和 easy neg 占比需要通过实验来调整。
样本除了归因表之外,另一个要素便是特征体系,由于线上是 i2i 召回,那么主要就是构建 item 特征体系,只要是 item 维度的即可,一般可以从以下几个方面着手:
- 统计类特征:曝光pv、点击pv、ctr、cvr、price等;
- 属性类特征:类目id,品牌id,适用人群,颜色等;
- 上下文特征:召回 channel(swing 等),召回分数(i2i 算法 score)等;
- 多模态特征:item 的 nlp 文本向量,图片的 cv 预训练向量等。
2.2 模型
因为 i2i 线上往往是使用用户的行为序列中的 item 作为 trigger 去倒排中召回 item。那么结合上述的样本结构,我们就需要构建一个由 trigger_item vs target_item
组成的 pair 对样本,模型结构可以选择双塔模型
,两边的特征体系往往一模一样,仅仅是为了训练出用户一般在看了某个 trigger_item 后最有可能还看哪些 target_item。
所以模型的结构往往比较简单:
input
:trigger_item 和 target_item 的 features;forward
:input 在 concat 后喂入 NN 即可;loss
:构建 ctr loss,多目标的话也可构建多头网络。
2.3 预估倒排
在 ranki2i
样本和模型中,主要为了提高 i2i 的效率,那如何将模型的能力转为 i2i 的效果,并起到对分散的各路 i2i 进行合并的作用呢?
一个比较自然的想法:为了确保分散的各路 i2i 候选集都有参与的机会,那么就将 swing 等所有 i2i 的倒排合并去重后,对所有的 pair 对应用上述 i2i 模型进行预估,然后根据预估结果(ctr预估分或各个多目标分)倒序排列后截断。
如此便得到了融合的 i2i 倒排,由于以下2点,往往此路 i2i 能够替换所有分散的 i2i 的效果:
- 基于场景内真实 i2i 样本数据训练得到;
- 将所有 i2i 倒排融合后进行排序的结果。
2.4 其他调优
在实际应用中,一般效率上是有比较明显的效果。并且能够降低 i2i 线上的复杂度,提高优化效率,否则 i2i 分散在多路中,提升效果难以撬动整体。
针对 ranki2i 本身依然有不少调优策略,这里简单列举几个博主自己实践中的经验:
- 模型需要增量更新一段时间,尽可能覆盖 pair 对;
- 负采样上,尽量达到曝光负样本的量级;
- 预估长尾 pair 对由于训练不充分(甚至没出现过),需要考虑置信度,比如长度阶段后需要进一步分数截断,或者类目调权。
- 在线召回的策略迭代就和单路的差不多,例如拆分长短兴趣召回等。