📑 本页目录(点开跳转)
召回算法
⏱ 30 分钟 | ⭐ 和《推荐算法》教程可对照着看
🎯 一句话
推荐类赛题的第一关是召回——从几十万甚至上百万候选里,先捞出几百个「可能相关」的。这一章的方法你在[《推荐算法》教程](../推荐算法/index.html)里大多学过,差别在于竞赛场景更看重「多路召回的组合」和「召回率上限」,因为召回没捞到的东西,后面排序再强也救不回来。
一、推荐系统架构
| 层级 |
功能 |
特点 |
| 召回层 |
从海量候选中筛选千级别候选集 |
速度快、覆盖广、精度低 |
| 粗排层 |
对召回结果初步排序,筛选百级别 |
平衡速度和精度 |
| 精排层 |
对候选精细排序 |
精度高、特征丰富 |
| 重排层 |
多样性/新颖性/业务规则调整 |
最终展示 |
| 竞赛特点 |
说明 |
| 召回阶段决定上限,排序阶段决定逼近程度 |
|
| 召回不足 → 排序再好也无法推荐未召回的物品 |
|
| 竞赛中通常直接做召回+精排,省略粗排和重排 |
|
二、协同过滤
ItemCF(基于物品的协同过滤)
| 维度 |
说明 |
| 核心思想 |
推荐与用户历史交互物品相似的物品 |
| 相似度计算 |
cos(A,B) = |
| N(A) |
喜欢物品A的用户集合 |
| 推荐逻辑 |
对用户历史交互物品,找相似物品,按相似度加权排序 |
| 优势 |
物品相似度可离线计算,在线推荐快 |
| 适用 |
物品数远小于用户数、物品相对稳定的场景(电商) |
| ItemCF改进 |
说明 |
| 惩罚活跃用户 |
活跃用户对物品相似度贡献降低:1/log(1+ |
| 时间衰减 |
近期交互权重更高 |
| 类别过滤 |
只推荐与历史物品同类别的物品 |
UserCF(基于用户的协同过滤)
| 维度 |
说明 |
| 核心思想 |
推荐与目标用户相似用户喜欢的物品 |
| 相似度计算 |
cos(A,B) = |
| N(A) |
用户A交互过的物品集合 |
| 推荐逻辑 |
找相似用户 → 取相似用户喜欢但目标用户未交互的物品 |
| 优势 |
可发现惊喜推荐(用户未意识到的兴趣) |
| 适用 |
用户数远小于物品数、用户兴趣稳定的场景(新闻) |
| ItemCF vs UserCF |
ItemCF |
UserCF |
| 推荐依据 |
物品相似度 |
用户相似度 |
| 推荐特点 |
稳定、可解释 |
惊喜、多样性 |
| 在线计算 |
快(离线算好) |
慢(需在线算) |
| 适用场景 |
电商、长尾物品少 |
新闻、用户兴趣变化快 |
三、图嵌入方法
DeepWalk
| 维度 |
说明 |
| 核心思想 |
将用户-物品交互图转为序列,用Word2Vec学习节点向量 |
| 步骤1:随机游走 |
从每个节点出发,随机选择邻居游走,生成多条路径序列 |
| 步骤2:Skip-Gram |
对路径序列用Skip-Gram训练,学习每个节点的向量表示 |
| 步骤3:相似度检索 |
用学到的向量做最近邻检索,找相似物品/用户 |
| 优势 |
可同时学习用户和物品向量,捕捉图结构信息 |
| 劣势 |
随机游走可能偏向高度数节点 |
其他图方法
| 方法 |
改进点 |
| Node2Vec |
BFS+DFS混合游走策略,平衡同质性和结构等价性 |
| LINE |
保留一阶(直接邻居)和二阶(共同邻居)相似度 |
| EGES |
阿里出品,融合多种side information的图嵌入 |
四、深度学习召回
YouTube DNN
| 维度 |
说明 |
| 结构 |
双塔模型:用户塔(用户特征→向量) + 物品塔(物品特征→向量) |
| 训练 |
Softmax分类(正样本为用户点击物品,负样本采样) |
| 推理 |
用户向量与物品向量内积,取Top-K |
| 优势 |
可融合丰富特征,在线推理快(向量检索) |
| 关键 |
负采样策略、特征工程 |
DSSM(Deep Structured Semantic Model)
| 维度 |
说明 |
| 结构 |
双塔:Query塔 + Doc塔,内积计算相似度 |
| 训练 |
Triplet Loss / InfoNCE Loss |
| 优势 |
两塔独立计算,可离线建索引 |
| 劣势 |
两塔交互晚(仅最后内积),特征交叉不充分 |
五、多兴趣召回
动机
| 问题 |
说明 |
| 单向量瓶颈 |
一个用户用一个向量表示,难以表达多兴趣 |
| 示例 |
用户同时喜欢手机和衣服,单向量只能折中 |
| 解决方案 |
用多个向量表示用户不同兴趣 |
MIND(Multi-Interest Network)
| 维度 |
说明 |
| 核心思想 |
用动态路由机制从用户行为序列中提取多个兴趣向量 |
| 动态路由 |
行为序列 → Capsule网络 → K个兴趣胶囊(向量) |
| K值 |
兴趣数量,通常4~8 |
| 训练 |
Label-aware Attention:每个兴趣向量与目标物品算注意力,取最相关兴趣 |
| 推理 |
用K个兴趣向量分别检索,合并去重 |
ComiRec
| 维度 |
说明 |
| 核心思想 |
与MIND类似,但用Attention机制提取多兴趣 |
| 优势 |
Attention比动态路由更直观、更易训练 |
| 两种变体 |
ComiRec-Att(注意力) / ComiRec-DR(动态路由) |
多兴趣召回实践
| 要点 |
说明 |
| 兴趣数量K |
过小无法覆盖多兴趣,过大引入噪声 |
| 检索合并 |
每个兴趣向量取Top-N,合并后取Top-K |
| 与单兴趣对比 |
多兴趣在长尾物品上提升显著 |
| 竞赛价值 |
Top-K推荐赛题中的关键上分点 |
六、向量检索
| 方法 |
原理 |
适用场景 |
| 暴力搜索 |
遍历所有向量计算距离 |
向量数少(<10万) |
| FAISS-IVF |
聚类后只搜索最近簇 |
通用场景 |
| FAISS-HNSW |
层次导航小世界图 |
高召回率需求 |
| Annoy |
随机投影树 |
Spotify开源,适合中等规模 |
七、竞赛实战要点
| 要点 |
说明 |
| 多路召回 |
ItemCF + UserCF + DeepWalk + 双塔DNN,多路合并 |
| 召回数量 |
每路召回100~500,合并后1000~3000送入排序 |
| 负采样 |
随机负采样 + 热门物品负采样(热门物品做负样本增加难度) |
| 特征工程 |
用户画像、物品属性、交叉统计特征 |
| 冷启动 |
新用户/新物品用内容特征做召回,不依赖交互历史 |
八、序列感知召回
SASRec(Self-Attentive Sequential Recommendation)
| 维度 |
说明 |
| 核心思想 |
用Self-Attention建模用户行为序列,捕捉长距离依赖 |
| 与RNN区别 |
并行计算,不受梯度消失影响,可捕捉长距离依赖 |
| 位置编码 |
可学习的位置嵌入,保留行为顺序信息 |
| 训练 |
BERT式双向或GPT式单向,推荐通常用单向(只看历史) |
| 推理 |
用户序列编码为向量,与物品向量内积检索 |
| 竞赛价值 |
序列推荐赛题中的强baseline |
NextItNet
| 维度 |
说明 |
| 核心思想 |
用空洞卷积(Dilated CNN)建模用户行为序列 |
| 空洞卷积 |
感受野指数级增长,少量层即可覆盖长序列 |
| 优势 |
比SASRec训练更快(CNN并行),推理更快 |
| 适用场景 |
对推理速度有要求的序列推荐 |
九、图神经网络召回
LightGCN
| 维度 |
说明 |
| 核心思想 |
在用户-物品二部图上做图卷积,学习用户和物品的Embedding |
| 简化 |
去掉GCN中的特征变换和非线性激活,只保留邻域聚合 |
| 优势 |
比NGCF更简单但效果更好,参数更少 |
| 层数 |
通常3~4层,过多过平滑 |
| 竞赛应用 |
推荐系统召回的强baseline |
GNN召回 vs 传统召回
| 维度 |
ItemCF/UserCF |
DeepWalk |
LightGCN |
| 图结构利用 |
一阶邻居 |
随机游走 |
多阶邻居聚合 |
| 特征融合 |
无 |
无 |
可融合side info |
| 冷启动 |
差 |
差 |
较好(有特征时) |
| 训练成本 |
无需训练 |
低 |
中 |
| 召回质量 |
中 |
中 |
高 |
十、召回竞赛实战策略
| 策略 |
说明 |
| 多路召回 |
ItemCF + UserCF + DeepWalk + 双塔DNN + LightGCN,每路召回100~500 |
| 召回数量 |
合并后1000~3000送入排序,过多增加排序负担 |
| 负采样策略 |
随机负采样 + 热门物品负采样(热门物品做负样本增加难度) |
| 冷启动处理 |
新用户用内容特征做召回,新物品用物品属性做召回 |
| 序列召回 |
SASRec/NextItNet对有行为历史的用户效果更好 |
| 图召回 |
LightGCN适合交互数据丰富的场景 |
🔗 这一章连到哪里
✅ 检查点
- 为什么说「召回决定了整条链路的上限」?
- 竞赛里为什么几乎总是用多路召回而不是单路?
- 协同过滤类召回和向量召回各自的强项是什么?
- 评估召回效果该看什么指标?为什么不是 AUC?
- 召回阶段的负样本该怎么采?
👀 答案
- 因为排序只能在召回给的候选里选。如果正确答案根本没进候选池,后面的粗排、精排、重排做得再好也是零。所以竞赛里的第一件事通常是先把召回率(Recall@K)做上去,再去优化排序。
- 因为不同召回路捞到的是不同类型的相关物品:ItemCF 捞「和你看过的相似的」、热门捞「大家都在看的」、向量召回捞「语义相似的」、图召回捞「多跳可达的」。单路召回一定有系统性盲区,多路并集才能把召回率顶上去。⭐ 竞赛里加一路新召回,常常比调排序模型收益大得多。
- 协同过滤:直接利用行为共现,对热门物品和有充足交互的用户效果好,不需要内容特征;向量召回:能利用内容和语义,对冷启动物品和长尾更友好,且能扫全库。两者互补而非替代——这也是它们常常同时出现在多路召回里的原因。
- 看 Recall@K(以及命中率、覆盖率),而不是 AUC。因为召回阶段关心的是「有没有捞到」,不是「排得对不对」——排序是下一阶段的事。⚠️ 用 AUC 评召回会让你优化错方向:一个 AUC 很高但 Recall@200 很低的召回,对整条链路是失败的。
- 必须从全库随机采(可以再加少量困难负样本)。⚠️ 不能用「曝光未点击」当召回的负样本——那是精排的负样本分布。原因是训练分布要和线上面对的分布一致:召回线上面对的是全库,用曝光未点击训出来的模型只学会了精排级别的细微区分,从全库里挑不出东西。
🛑 可以停在这里
先记住这几件事
- 排序只能选择已经召回的候选,所以先检查目标是否进入候选池。
- 多路召回利用不同信号,比较每一路带来的新增覆盖。
- 召回评测和负采样要对应真实候选分布,不能直接套用精排口径。
打卡记录保存在你的浏览器里,首页能看到总进度