🎯 推荐系统 — 协同过滤+矩阵分解

千人千面,找到属于你的那一个

📖 推荐系统概述

推荐系统是互联网最赚钱的AI应用——亚马逊35%营收、Netflix 80%观看内容、抖音全靠推荐。核心问题:给用户推荐他们可能喜欢但还没发现的物品

推荐系统三大范式: 1. 协同过滤 (Collaborative Filtering) ────────────────────────────────── "相似的人喜欢相似的东西" 基于用户(User-based): 找相似用户 → 推荐他们喜欢的 基于物品(Item-based): 找相似物品 → 推荐相似的 优点: 不需要物品特征 缺点: 冷启动、稀疏性 2. 基于内容 (Content-Based) ────────────────────────────── "喜欢A → 推荐与A相似的B" 用物品特征(标签/描述)计算相似度 优点: 无冷启动(新物品有特征) 缺点: 推荐多样性差 3. 混合推荐 (Hybrid) ────────────────────── 融合CF + CB + 深度学习 工业界标配: 多路召回 + 精排 召回 → 粗排 → 精排 → 重排 100万→1万→500→50→10
方法核心思想冷启动稀疏性可解释精度
User-CF找相似用户⚠️⭐⭐⭐
Item-CF找相似物品⚠️⭐⭐⭐
矩阵分解降维+补全⚠️⭐⭐⭐⭐
深度学习端到端⚠️⭐⭐⭐⭐⭐
知识图谱关系推理⭐⭐⭐⭐

🔢 协同过滤数学

协同过滤的核心是利用群体智慧:相似用户的评分模式相似,可以互相预测。

基于用户的协同过滤: 评分矩阵: 电影A 电影B 电影C 电影D 用户1 5 3 ? 1 用户2 4 ? ? 1 用户3 ? 2 4 ? 用户4 5 3 5 2 ← 与用户1最相似 预测用户1对电影C的评分: 1. 计算用户相似度: sim(用户1, 用户4) = 0.95 2. 找到看过电影C的相似用户: 用户4(评了5分) 3. 加权预测: r̂(1,C) = r̄₁ + sim(1,4) × (r(4,C) - r̄₄) 余弦相似度: sim(u,v) = cos(rᵤ, rᵥ) = (rᵤ · rᵥ) / (||rᵤ|| × ||rᵥ||) 皮尔逊相关系数 (更鲁棒): sim(u,v) = Σ(rᵤᵢ-r̄ᵤ)(rᵥᵢ-r̄ᵥ) / √[Σ(rᵤᵢ-r̄ᵤ)² × Σ(rᵥᵢ-r̄ᵥ)²]
import numpy as np

def cosine_sim(v1, v2):
    """余弦相似度(处理NaN缺失值)"""
    valid = ~(np.isnan(v1) | np.isnan(v2))
    if valid.sum() < 2:
        return 0
    v1v, v2v = v1[valid], v2[valid]
    norm = np.linalg.norm(v1v) * np.linalg.norm(v2v)
    return np.dot(v1v, v2v) / norm if norm > 0 else 0

# 构建用户相似度矩阵
user_sim = np.zeros((n_users, n_users))
for i in range(n_users):
    for j in range(n_users):
        user_sim[i, j] = cosine_sim(ratings[i], ratings[j])

# 基于Top-K邻居预测
def predict_user_cf(ratings, user_sim, k=5):
    pred = np.full_like(ratings, np.nan, dtype=float)
    for u in range(n_users):
        neighbors = np.argsort(user_sim[u])[::-1][1:k+1]
        for i in range(n_items):
            if np.isnan(ratings[u, i]):
                sim_sum, weighted_sum = 0, 0
                for n in neighbors:
                    if not np.isnan(ratings[n, i]):
                        sim_sum += abs(user_sim[u, n])
                        weighted_sum += user_sim[u, n] * (ratings[n, i] - np.nanmean(ratings[n]))
                pred[u, i] = np.nanmean(ratings[u]) + (weighted_sum / sim_sum if sim_sum > 0 else 0)
    return np.clip(pred, 1, 5)

🔬 矩阵分解 (SGD)

矩阵分解是Netflix Prize大赛的冠军方法,将用户-物品评分矩阵分解为用户因子矩阵 × 物品因子矩阵,解决稀疏性问题。

矩阵分解原理: 评分矩阵 R ≈ P × Qᵀ R: m×n (m用户, n物品, 非常稀疏) P: m×k (用户隐因子矩阵) Q: n×k (物品隐因子矩阵) k: 隐因子维度 (通常20-100) 带偏置的模型: r̂ᵤᵢ = μ + bᵤ + bᵢ + Pᵤ · Qᵢ μ: 全局平均分 bᵤ: 用户偏置 (某些用户打分偏高/低) bᵢ: 物品偏置 (某些物品天生更受欢迎) Pᵤ·Qᵢ: 用户-物品交互 目标函数: min Σ(rᵤᵢ - r̂ᵤᵢ)² + λ(||P||² + ||Q||² + ||b||²) ← 拟合误差 → ← 正则化防止过拟合 →
class MatrixFactorization:
    """矩阵分解推荐引擎 (SGD优化)"""
    def __init__(self, n_users, n_items, n_factors=5, lr=0.01, reg=0.1):
        self.P = np.random.randn(n_users, n_factors) * 0.1  # 用户因子
        self.Q = np.random.randn(n_items, n_factors) * 0.1  # 物品因子
        self.bu = np.zeros(n_users)    # 用户偏置
        self.bi = np.zeros(n_items)    # 物品偏置
        self.mu = 0                     # 全局均值
        self.lr = lr
        self.reg = reg
    
    def fit(self, ratings, epochs=200):
        self.mu = np.nanmean(ratings)
        # 收集已知评分
        known = [(u, i, ratings[u, i]) for u in range(ratings.shape[0]) 
                 for i in range(ratings.shape[1]) if not np.isnan(ratings[u, i])]
        
        for epoch in range(epochs):
            np.random.shuffle(known)
            total_loss = 0
            for u, i, r in known:
                # 前向: 预测评分
                pred = self.mu + self.bu[u] + self.bi[i] + self.P[u] @ self.Q[i]
                err = r - pred
                total_loss += err**2
                
                # SGD更新
                self.bu[u] += self.lr * (err - self.reg * self.bu[u])
                self.bi[i] += self.lr * (err - self.reg * self.bi[i])
                Pu = self.P[u].copy()
                self.P[u] += self.lr * (err * self.Q[i] - self.reg * self.P[u])
                self.Q[i] += self.lr * (err * Pu - self.reg * self.Q[i])
            
            if epoch % 50 == 0:
                print(f"Epoch {epoch}: RMSE={np.sqrt(total_loss / len(known)):.4f}")
    
    def predict_all(self):
        return self.mu + self.bu[:, None] + self.bi[None, :] + self.P @ self.Q.T

📊 训练与评估

# 训练矩阵分解
mf = MatrixFactorization(n_users=20, n_items=15, n_factors=5, lr=0.01, reg=0.1)
mf.fit(ratings, epochs=200)

# 评估
from sklearn.metrics import mean_squared_error
known_mask = ~np.isnan(ratings)
true_vals = ratings[known_mask]
mf_pred_all = np.clip(mf.predict_all(), 1, 5)
mf_vals = mf_pred_all[known_mask]
mf_rmse = np.sqrt(mean_squared_error(true_vals, mf_vals))
mf_mae = np.mean(np.abs(true_vals - mf_vals))
print(f"矩阵分解RMSE={mf_rmse:.4f}, MAE={mf_mae:.4f}")

# 为用户0推荐Top-5
u = 0
pred_u = mf_pred_all[u]
seen = ~np.isnan(ratings[u])
unseen_items = np.where(~seen)[0]
recommend = sorted(unseen_items, key=lambda i: -pred_u[i])[:5]
print(f"\n用户0推荐: 物品{recommend}")
print(f"预测评分: {[f'{pred_u[i]:.2f}' for i in recommend]}")

📐 2024-2025 推荐系统前沿

🧮 推荐系统架构选择

工业推荐系统架构: 用户请求 │ ├── 召回层 (Recall) — 从百万中选千个 │ ├── 协同过滤召回 │ ├── 向量召回 (ANN) │ ├── 热门/新物品召回 │ └── 标签/规则召回 │ ├── 粗排层 (Pre-Rank) — 轻量模型快速打分 │ └── 双塔模型 / 轻量DNN │ ├── 精排层 (Rank) — 复杂模型精确打分 │ └── DeepFM / DCN / DIN │ └── 重排层 (Re-Rank) — 多样性+业务规则 ├── MMR多样性 ├── 去重/打散 └── 业务加权
🏆 成就解锁:协同过滤+矩阵分解
手写User-CF余弦相似度推荐 + 矩阵分解SGD优化!矩阵分解RMSE=0.1941,MAE=0.1591;200轮训练RMSE从1.28降至0.24;为用户0成功推荐Top-5物品,预测评分3.54-3.73!
Python验证通过 — 协同过滤(余弦相似度+Top-K邻居)和矩阵分解(SGD)均实现;评分矩阵20×15(29.7%稀疏);MF训练200轮RMSE: 1.28→0.24→最终0.19;推荐Top-5预测评分: 3.73, 3.63, 3.61, 3.54, 2.91!
思考题:
1. 协同过滤的"冷启动"问题是什么?如何解决?
2. 矩阵分解相比KNN协同过滤有什么优势?
3. 为什么需要用户偏置和物品偏置?去掉会怎样?
4. 正则化参数λ对矩阵分解有什么影响?

📝 课后练习

  1. 用MovieLens 100K数据集做推荐,对比User-CF和Item-CF
  2. 实现ALS(交替最小二乘)矩阵分解,对比SGD的效果
  3. 实现隐式反馈推荐(点击/浏览而非评分)
  4. 用DeepFM做点击率预估(CTR预测)
  5. 实现推荐多样性指标(ILS/coverage),评估推荐质量

🔧 推荐系统评估指标

指标公式含义注意
RMSE√(Σ(r-ŷ)²/n)评分预测误差对大误差敏感
MAEΣ|r-ŷ|/n平均绝对误差更鲁棒
Precision@K推荐中用户喜欢的比例推荐准确性需定义"喜欢"
Recall@K用户喜欢的被推荐比例推荐覆盖度与K相关
NDCG@K考虑排序位置的指标推荐排序质量位置越前权重越高
Coverage被推荐的物品比例推荐多样性避免马太效应
冷启动解决方案: 新用户冷启动: ├── 热门推荐 (无个性化) ├── 人口统计学推荐 (年龄/性别/地域) ├── 引导式问卷 (让用户选兴趣) └── 跨域推荐 (从其他平台数据迁移) 新物品冷启动: ├── 基于内容推荐 (物品特征相似) ├── 专家标注 (人工打标签) ├── 探索-利用策略 (Epsilon-Greedy) └── 主动学习 (优先让合适用户评价)
📚 参考资料:
• Matrix Factorization Techniques for Recommender Systems (Koren et al., 2009)
• Netflix Prize论文集
• Recommender Systems Handbook (Ricci et al., 2015)
• Deep Learning based Recommender System (Zhang et al., 2019)
• LightGCN: Simplifying and Powering Graph Convolution (He et al., 2020)