推荐系统入门:从协同过滤到双塔模型——猜你喜欢的技术简史

· 约 4 分钟 ·
本文目录(8 节)

推荐系统不只是给所有物品打分:候选太多时,通常先筛出一批可能相关的内容,再做更精细的排序。本文从协同过滤与矩阵分解讲起,区分召回、排序和评估的职责。离线指标能帮助筛选方案,但不能替代对曝光偏差和用户长期体验的检查。

前置阅读:机器学习基础、Embedding 概念(推荐系统的向量与语义检索同源)。

协同过滤:推荐的第一个伟大思想

协同过滤(CF)的洞察:相似的用户喜欢相似的物品。不需要理解物品内容,只看行为矩阵(用户 × 物品的评分/点击):

  • UserCF:找和你口味像的人,把他们喜欢而你看过的推给你。
  • ItemCF:找和你喜欢过的物品相似的物品(“看了又看”)。物品相似度由”共同喜欢它们的用户”定义。

UserCF 适合用户少的社区,ItemCF 更稳定(物品相似性变化慢),亚马逊的”购买此商品的顾客也购买了”就是 ItemCF 的经典落地。CF 的痛点:行为矩阵极度稀疏(99%+ 是空的),新用户新物品没有行为——冷启动问题。

矩阵分解:把协同过滤向量化

矩阵分解(MF)把巨大的稀疏评分矩阵 RR 分解成两个小矩阵:

Rm×n≈Pm×k⋅Qk×nR_{m \times n} \approx P_{m \times k} \cdot Q_{k \times n}

PP 的每行是用户的 k 维兴趣向量,QQ 的每列是物品的 k 维特征向量,预测就是点积。k 取几十到几百——这和 Embedding 是完全相同的思想:把离散的 ID 变成连续向量,相似性变成距离。

用 SGD 训练一个最小实现:

import numpy as np

def train_mf(R, k=32, lr=0.01, reg=0.02, epochs=50):
    m, n = R.shape
    P = np.random.normal(0, 0.1, (m, k))
    Q = np.random.normal(0, 0.1, (n, k))
    users, items = np.nonzero(R)              # 只在有行为的位置学

    for epoch in range(epochs):
        for u, i in zip(users, items):
            err = R[u, i] - P[u] @ Q[i]
            P[u] += lr * (err * Q[i] - reg * P[u])
            Q[i] += lr * (err * P[u] - reg * Q[i])
    return P, Q

# 给用户 u 推荐:P[u] @ Q.T 排序,排除已交互物品

现代架构:召回 + 排序两段式

工业推荐系统的标准架构,两个阶段各司其职:

召回(Retrieval):从百万物品里快速捞出几百个候选,要求快、求全。主力是双塔模型:用户塔和物品塔各自把特征编码成向量,训练让正样本对向量接近——线上检索就变成向量最近邻(Faiss/Milvus 的用武之地)。多路召回(行为向量 + 热门 + 内容相似)并行取并集是常态。

排序(Ranking):对几百个候选精排,要求准。特征是用户画像 + 物品属性 + 交叉特征,模型从 LR/GBDT 演进到 DeepFM/DIN。预测点击率(CTR)或时长,按分排序产出最终列表。

后面还有一层重排:打散同作者、保证多样性、插入探索流量——纯算法之外的业务规则层。

评估:离线看 AUC/Recall,在线看 AB

  • 召回侧:Recall@K(用户真实点击有多少被召回了)——漏掉的好物品排序救不回来。
  • 排序侧:AUC(点对排序能力)、NDCG@K(位置加权的命中率,排越前权重越高)。
  • 终极裁判是线上 A/B 测试:离线指标涨线上不一定涨(离线数据是旧策略的产物,有选择偏差)。评估方法的细节见 A/B 测试篇。

冷启动与偏差:推荐的两座大山

冷启动:新用户→用注册画像/热门榜兜底;新物品→用内容特征(标题/类别的向量)进入召回,给小流量试探。这是双塔里加内容特征而非纯 ID 向量的动机。

偏差治理:位置偏差(排前面的天然点击高,训练数据被污染)、流行度偏差(热门越推越热)。常见手段:点击模型去偏、IPS 加权、探索流量(ε 比例随机曝光)——和强化学习的探索-利用遥相呼应。

踩坑排查

症状原因处理
推荐全是热门物品流行度偏差降权热门、加探索流量、负采样
新用户推荐质量差冷启动无行为画像特征 + 热门兜底
离线涨在线跌选择偏差用倾向性加权;相信 A/B
双塔检索结果趋同负采样太弱加 batch 内负样本/难负样本
排序模型过拟合 IDID 特征占比过大ID embedding 降维 + 正则
推荐结果重复度高缺多样性约束重排层 MMR 打散

练习

  1. 在 MovieLens-100k 上实现矩阵分解,计算 Recall@20。
  2. 实现 ItemCF 的简化版(共现计数 + 余弦相似),与 MF 对比。
  3. 构造双塔模型的训练样本(用户历史 → 下一个点击),用 PyTorch 训练并做向量检索。
  4. 统计推荐结果的流行度分布,实现一个流行度降权并观察变化。

面试常问

Q:UserCF 和 ItemCF 怎么选? 用户少且稳定用 UserCF(新闻社区);物品稳定用 ItemCF(电商)——物品相似性更新慢、可离线预计算、推荐解释自然(“因为你买过 X”)。实践中 ItemCF 用得更广。

Q:双塔模型为什么适合做召回? 用户和物品向量解耦:物品向量可离线全量预计算建索引,线上只需算一次用户向量 + 一次 ANN 检索,毫秒级从百万库取候选。缺点是双塔交互太浅,精度不如排序模型——这正是两段式架构的分工。

Q:推荐系统怎么处理冷启动? 新用户:注册画像 + 热门/编辑精选 + 快速试探(bandit);新物品:内容特征向量进召回池 + 小流量扶持 + 观察期。核心思想是用内容信号补行为信号的缺失。

Q:为什么离线指标和线上效果经常不一致? 训练数据由旧策略产生(选择偏差),离线评估测的是”旧策略会怎么排这些数据”而非”新策略上线后用户会怎么点”。只有 A/B 测试能拿到新策略的真实因果效应。


相关阅读:A/B 测试与统计推断、K-Means 用户分群。

💬 评论

这套方案在哪一步卡住了?也欢迎补充你的实现方式或踩坑经验。

正在连接评论服务,首次访问可能需要几秒…