跳转至

16.2   推荐系统中的统计

书店咖啡角里,小率刚给一本小说打了五星,手机就弹出几本相似书和两部电影。均哥问:“它为什么觉得你会喜欢?”小率看了看历史评分、收藏和浏览记录:“它在用过去的行为预测下一次选择。”

推荐系统(Recommendation System)的本质,是在用户、物品和场景之间估计偏好。

均哥和小率在书店咖啡角理解推荐系统

16.2.1   推荐先从用户-物品矩阵开始

把用户对物品的评分排成矩阵:

用户 书 A 书 B 电影 C 电影 D
小率 5 ? 4 ?
读者甲 5 4 ? 2
读者乙 ? 5 4 1

问号就是要预测的位置。协同过滤(Collaborative Filtering)的直觉是:如果两个人过去喜欢的东西相似,他们未来可能也会喜欢相似的东西。

一个简单的矩阵分解模型写成:

\[ \hat{r}_{ui} = \mu + b_u + b_i + \mathbf{p}_u^\mathsf{T}\mathbf{q}_i \]

其中 \(\mu\) 是全局平均分,\(b_u\) 是用户偏好偏置,\(b_i\) 是物品受欢迎程度,\(\mathbf{p}_u\)\(\mathbf{q}_i\) 是低维向量。

推荐系统统计流程讲解图

16.2.2   推荐系统通常分成召回和排序

实际系统不会对所有物品逐一精算。常见流程是两步:

  1. 召回(Recall):从海量物品中快速找出几百个候选,例如相似用户喜欢的书、同主题电影、最近热门内容。
  2. 排序(Ranking):对候选物品精细打分,综合点击概率、购买概率、多样性、新鲜度和业务约束。

这就像书店先把你可能喜欢的书架找出来,再从架子上挑最适合放到你面前的几本。

16.2.3   离线准确不等于线上有效

推荐系统常见离线指标包括 RMSE、AUC、Recall@K、NDCG@K。但线上更关心点击率、转化率、停留时长、复购和用户满意度。

曝光偏差很容易藏起来

用户没有点击某个物品,不代表他不喜欢;也可能是系统从未把它展示出来。推荐数据天然带有系统过去策略的偏差。

16.2.4   Top-K 指标更贴近推荐列表

如果推荐页只展示 10 个物品,评分预测误差不一定最重要。我们更关心“好东西有没有排到前面”。

指标 问题 直觉
Precision@K 推荐的 K 个里有多少是用户喜欢的 少推错
Recall@K 用户喜欢的物品有多少被找到了 少漏掉
NDCG@K 排得越靠前是否越相关 好东西放前面
Coverage 系统覆盖了多少物品 避免只推热门

16.2.5   用相似用户做一个小推荐

import numpy as np

ratings = np.array([
    [5, 0, 4, 0],
    [5, 4, 0, 2],
    [0, 5, 4, 1],
], dtype=float)

target = ratings[0]
others = ratings[1:]

def cosine(a, b):
    mask = (a > 0) & (b > 0)
    if mask.sum() == 0:
        return 0
    return np.dot(a[mask], b[mask]) / (
        np.linalg.norm(a[mask]) * np.linalg.norm(b[mask])
    )

sims = np.array([cosine(target, row) for row in others])
candidate_item = 1
pred = np.average(others[:, candidate_item], weights=sims)

print("similarities:", sims)
print("predicted rating for book B:", round(pred, 2))

16.2.6   为什么推荐系统需要探索

如果系统永远只推“看起来最确定”的物品,用户很难发现新兴趣,冷门物品也永远没有机会被验证。探索-利用(Explore-Exploit)权衡就是:

  • 利用:推荐当前模型最有把握的内容。
  • 探索:有控制地尝试不确定但可能有价值的内容。

新闻、短视频和新品推荐尤其需要探索,因为内容变化快,旧数据很快过期。

小率的笔记本

推荐系统不只是“猜你喜欢”。它同时涉及预测、排序、探索、偏差校正和 A/B 测试。离线指标是筛选工具,真正上线还要看因果效果和用户体验。