从协同过滤到双塔召回,那些你必须跨过的“坑

7 阅读5分钟

从协同过滤到双塔召回,那些你必须跨过的“坑

💡 前言

在推荐系统的漏斗中,召回(Recall) 决定了推荐的天花板,而 精排(Ranking) 只是在逼近这个天花板。

很多同学在从学校理论转向工业界实战时,往往会陷入一个误区:用搞精排的思维去搞召回。今天,结合我最近深入研究的一套大厂内部技术笔记,我想和大家聊聊召回层的“战术演进”,特别是那些教科书上没细说的工程权衡(Trade-off)


一、 传统时代的智慧:修正“人心”的偏差

在深度学习统领天下之前,基于 Item 属性的倒排索引和协同过滤(CF)是绝对的主流。但这里藏着一个经典的数学陷阱。

1.1 别再迷信余弦相似度了

我们都知道 UserCF 和 ItemCF 的核心是计算相似度。最常用的是 余弦相似度 (Cosine Similarity) 。但是,它在实际应用中有个致命 Bug:对尺度不敏感

  • 用户 A:狂热粉丝,看啥都打 5 分。
  • 用户 B:苛刻批评家,觉得 3 分就是好片。

余弦相似度只看向量方向,会认为这两人兴趣完全一致,从而忽略了用户 B 的“及格线”其实很高。

👉 进阶解法:皮尔逊相关系数 (Pearson Correlation)

工业界更推荐使用皮尔逊系数。它的本质是 “中心化” (Centering) —— 先把每个用户的评分减去他自己的平均分。

  • A 的 5 分 \rightarrow 55=05-5=0(平庸)。

  • B 的 4 分 \rightarrow 43=+14-3=+1(喜欢)。

    通过去均值,我们抹平了“打分习惯”的差异,让相似度计算回归兴趣本身。

1.2 多路召回的“端水艺术”

实际系统中,我们会有 UserCF、ItemCF、标签召回、热门召回等多路结果。怎么合并?

千万别直接按分数混排!因为不同路的分数体系不同(热门召回的分数通常会虚高)。

最佳实践:蛇形归并 (Snake Merge / Round-Robin)

第一轮取各路 Top1,第二轮取各路 Top2……这种朴素的轮询机制,反而能最大程度保证结果的多样性和公平性。


二、 向量化召回:现代推荐的基石

进入 Embedding 时代,核心逻辑变成了:万物皆向量,距离即兴趣

2.1 架构设计的铁律:必须解耦 (Decoupling)

面试高频题:精排模型(如 DeepFM)和召回模型(如 DSSM 双塔)最大的区别是什么?

  • 精排:恨不得把用户和物品特征揉碎了拼在一起,疯狂做特征交叉(Interaction),为了极致的准。
  • 召回必须解耦! 用户塔算用户向量,物品塔算物品向量,两者直到最后一步才能见面。

为什么要牺牲交叉能力?

为了速度。只有解耦,我们才能离线把几千万个 Item Embedding 算好存入 FAISS。线上来了请求,只算一次 User Embedding,就能通过 ANN(近似最近邻)毫秒级检索。如果做早期交叉,你就得把 User 和几千万个 Item 逐一过一遍 DNN,服务器直接爆炸,。


三、 样本选择:召回模型的“生死线” 🔥

这是本文的重点中的重点。很多模型效果不好,不是结构不行,是样本喂错了。

3.1 负样本的陷阱

  • 精排的负样本:曝光未点击。
  • 召回的负样本全库随机采样 (Global Random Sampling)

Why?

召回面对的是海量候选集,其中 99.9% 是用户完全不感兴趣的(八杆子打不着)。如果只用“曝光未点击”做负样本,模型就只学会了分辨“长得像但用户没点”的困难样本,却没见过“完全无关”的简单样本。上线后,模型会把大量无关噪音误判为高分。

3.2 黄金比例:Easy vs Hard

全随机(Easy Negative)虽然能让模型“开眼界”,但太简单了(教模型区分猫和汽车)。

Facebook 经验:Easy : Hard = 100 : 1。

在随机采样中,混入少量 Hard Negative(长得像正样本但不是,比如区分哈士奇和狼)。这能逼迫双塔模型学习更细粒度的特征。


四、 Loss 函数的玄机:从 NCE 到 NEG

召回模型到底在优化什么?

  • 精排:追求 绝对准确性 (BCE Loss)。预测出 CTR 是 1% 还是 1.5%,因为要用于广告计费。
  • 召回:追求 相对准确性 (Softmax/NCE)。只要 Score()>Score()Score(正) > Score(负) 即可。

4.1 NCE Loss 的“作弊惩罚”

Softmax 分母太大算不动,于是我们用 NCE (Noise Contrastive Estimation) 把它变成二分类问题。

NCE 公式里有一个极重要的校准项: logQ(tu)-\log Q(t|u)

  • Q(tu)Q(t|u) 是物品被采样的概率(通常与热度成正比)。
  • 含义:如果一个物品太热门,我就扣它分!
  • 目的去热度偏差。强迫模型去学用户真正的兴趣,而不是无脑推热门。

4.2 工业界的妥协:NEG Loss

Google 的 Word2Vec 使用了更简单的 NEG Loss。它直接忽略了 NCE 中的校准项。

虽然理论上它不能拟合真实概率,但对于“学习高质量向量”这个任务,它计算够快、效果够好,是性价比之选。


五、 实战难题:冷启动与双塔改进

5.1 物品冷启动:借尸还魂

新物品没有 ID Embedding 怎么办?

通用解法:用 CNN/BERT 提取新物品的内容 Embedding,去库里找 KK 个内容相似的高曝光老物品,把它们的 ID Embedding 取平均,作为新物品的初始向量。

5.2 改进双塔:把塔“变宽”

双塔最大的缺点是“交互太晚”,信息压缩损失大。

怎么救? 在塔的内部搞事情。

不要只用简单的 MLP。在塔底引入 DCN (Deep Cross Network) 或 FM,在单侧塔内就让特征充分交叉(比如用户侧的“性别”和“年龄”交叉)。

“大塔变小塔”:把不同类型的特征(文本、类别)分别过小塔,最后融合。这能显著提升 Embedding 的表达能力。


📝 总结

做召回,本质上是在做 “平衡”

  1. 精度 vs 速度:通过双塔解耦和 FAISS 换取速度。
  2. 广度 vs 深度:通过随机采样(Easy Negative)保证广度,通过 Hard Negative 提升深度。
  3. 理论 vs 工程:通过 NEG Loss 牺牲一点概率理论的严谨性,换取训练的高效性。