推荐系统技术解析(Recommendation Systems)

目录

  1. 推荐系统基础理论
  2. 协同过滤
  3. 矩阵分解
  4. 深度学习推荐模型
  5. 序列推荐
  6. 多任务学习
  7. 知识图谱推荐
  8. 图神经网络推荐
  9. 评估指标与实践
  10. 工业应用与前沿

1. 推荐系统基础理论

1.1 什么是推荐系统

复制代码
推荐系统的目标:
  根据用户的历史行为和偏好,预测用户对物品的喜好
  为用户推荐可能感兴趣的物品

  ┌─────────────────────────────────────────────────────────────────┐
  │                    推荐系统应用场景                               │
  ├─────────────────────────────────────────────────────────────────┤
  │                                                                 │
  │  电商推荐:                                                       │
  │  ├── 商品推荐: "猜你喜欢"                                       │
  │  ├── 相关推荐: "买了又买"                                       │
  │  └── 个性化首页: 千人千面                                        │
  │                                                                 │
  │  内容推荐:                                                       │
  │  ├── 新闻推荐: 今日头条                                          │
  │  ├── 短视频推荐: 抖音/TikTok                                    │
  │  ├── 长视频推荐: YouTube/B站                                    │
  │  └── 音乐推荐: Spotify/网易云音乐                               │
  │                                                                 │
  │  社交推荐:                                                       │
  │  ├── 好友推荐: "你可能认识的人"                                  │
  │  └── 内容推荐: 朋友圈/微博                                       │
  │                                                                 │
  │  广告推荐:                                                       │
  │  ├── 个性化广告                                                  │
  │  └── 竞价排名                                                    │
  │                                                                 │
  └─────────────────────────────────────────────────────────────────┘

1.2 推荐系统的形式化

复制代码
推荐问题的形式化:

  给定:
    用户集合 U = {u₁, u₂, ..., u_m}
    物品集合 I = {i₁, i₂, ..., i_n}
    交互历史 R = {(u, i, r, t)}  (用户-物品-评分-时间)
    
  目标:
    学习预测函数 f: U × I → R̂
    
    预测用户 u 对物品 i 的评分/点击概率

  矩阵视角:
    用户-物品交互矩阵 R ∈ ℝ^{m×n}
    
    R[u, i] = 用户 u 对物品 i 的评分/交互
    
    大多数元素缺失 (稀疏)
    
    推荐 = 矩阵补全 (预测缺失值)

1.3 推荐系统分类

复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                    推荐系统方法分类                                  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  1. 协同过滤 (Collaborative Filtering, CF)                          │
│     ├── 基于用户的 CF: 相似用户喜欢的物品                           │
│     ├── 基于物品的 CF: 相似物品                                     │
│     └── 矩阵分解: 学习用户/物品隐向量                               │
│                                                                     │
│  2. 基于内容的推荐 (Content-Based)                                  │
│     └─ 根据物品特征推荐相似物品                                      │
│                                                                     │
│  3. 混合推荐 (Hybrid)                                               │
│     └─ 结合多种方法                                                  │
│                                                                     │
│  4. 深度学习推荐 (Deep Learning)                                    │
│     ├── Wide & Deep: 记忆 + 泛化                                    │
│     ├── DeepFM: FM + DNN                                            │
│     ├── DIN: 注意力机制                                             │
│     └── DIEN: 兴趣演化                                              │
│                                                                     │
│  5. 序列推荐 (Sequential Recommendation)                            │
│     └─ 建模用户行为序列                                              │
│                                                                     │
│  6. 图推荐 (Graph-Based)                                            │
│     └─ 用户-物品交互建模为图                                         │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

1.4 推荐系统架构

复制代码
工业推荐系统架构:

  ┌─────────────────────────────────────────────────────────────────┐
  │                                                                 │
  │   召回 (Recall)           粗排 (Pre-Ranking)                    │
  │   ┌──────────────┐        ┌──────────────┐                     │
  │   │ 多路召回      │        │ 简单模型      │                     │
  │   │ - CF 召回     │───────►│ - 双塔模型    │                     │
  │   │ - 热门召回    │        │ - 轻量 DNN    │                     │
  │   │ - 向量召回    │        │              │                     │
  │   │ - 图召回      │        │ 数百→数千     │                     │
  │   │              │        └──────┬───────┘                     │
  │   │ 数万→数千    │               │                              │
  │   └──────────────┘               ▼                              │
  │                           精排 (Ranking)                        │
  │                           ┌──────────────┐                     │
  │                           │ 复杂模型      │                     │
  │                           │ - DeepFM      │                     │
  │                           │ - DIN/DIEN    │                     │
  │                           │ - 多任务模型  │                     │
  │                           │              │                     │
  │                           │ 数百→数十     │                     │
  │                           └──────┬───────┘                     │
  │                                  │                              │
  │                                  ▼                              │
  │                           重排 (Re-Ranking)                     │
  │                           ┌──────────────┐                     │
  │                           │ 策略调整      │                     │
  │                           │ - 多样性      │                     │
  │                           │ - 新鲜度      │                     │
  │                           │ - 业务规则    │                     │
  │                           │              │                     │
  │                           │ 最终展示      │                     │
  │                           └──────────────┘                     │
  │                                                                 │
  └─────────────────────────────────────────────────────────────────┘

各阶段的作用:
  召回: 从海量物品中快速筛选候选 (速度优先)
  粗排: 初步排序,减少候选数量
  精排: 精细排序,质量优先
  重排: 考虑多样性、新鲜度等因素

2. 协同过滤

2.1 基于用户的协同过滤

复制代码
核心思想:
  相似的用户可能喜欢相似的物品

  步骤:
    1. 找到与目标用户相似的用户 (邻居)
    2. 用邻居的评分预测目标用户的评分
    
  预测公式:
    r̂(u, i) = r̄_u + Σ_{v∈N(u)} sim(u, v) · (r_{v,i} - r̄_v) / Σ |sim(u, v)|
    
    其中:
      r̄_u: 用户 u 的平均评分
      N(u): 用户 u 的邻居集合
      sim(u, v): 用户 u 和 v 的相似度

相似度计算:
  1. 余弦相似度:
     sim(u, v) = (r_u · r_v) / (‖r_u‖ · ‖r_v‖)
     
  2. 皮尔逊相关系数:
     sim(u, v) = Σ_i (r_{u,i} - r̄_u)(r_{v,i} - r̄_v) / (√Σ(r_{u,i}-r̄_u)² · √Σ(r_{v,i}-r̄_v)²)
python 复制代码
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

class UserBasedCF:
    """
    基于用户的协同过滤
    
    理论:
      相似用户喜欢相似物品
      用邻居的评分加权预测
      
    优点: 简单直观
    缺点: 用户数多时计算量大
    """
    def __init__(self, k=20):
        self.k = k  # 邻居数量
    
    def fit(self, ratings):
        """
        ratings: 用户-物品评分矩阵 [n_users, n_items]
        """
        self.ratings = ratings
        self.user_mean = np.true_divide(
            ratings.sum(1), 
            (ratings != 0).sum(1),
            where=(ratings != 0).sum(1) != 0
        )
        
        # 计算用户相似度矩阵
        # 使用评分向量的余弦相似度
        ratings_normalized = ratings - self.user_mean[:, None] * (ratings != 0)
        self.sim_matrix = cosine_similarity(ratings_normalized)
        np.fill_diagonal(self.sim_matrix, 0)  # 排除自己
    
    def predict(self, user, item):
        """
        预测用户对物品的评分
        """
        # 找到对物品有评分的邻居
        rated_users = np.where(self.ratings[:, item] != 0)[0]
        
        if len(rated_users) == 0:
            return self.user_mean[user]
        
        # 选择最相似的 k 个邻居
        similarities = self.sim_matrix[user, rated_users]
        top_k_idx = np.argsort(similarities)[-self.k:]
        top_k_users = rated_users[top_k_idx]
        top_k_sims = similarities[top_k_idx]
        
        # 加权平均
        if np.sum(np.abs(top_k_sims)) == 0:
            return self.user_mean[user]
        
        pred = self.user_mean[user] + np.sum(
            top_k_sims * (self.ratings[top_k_users, item] - self.user_mean[top_k_users])
        ) / np.sum(np.abs(top_k_sims))
        
        return pred

"""
基于用户 CF 的问题:

  1. 稀疏性: 用户-物品矩阵很稀疏
  2. 冷启动: 新用户没有历史数据
  3. 可扩展性: 用户数多时计算量大
  
  解决: 基于物品的 CF、矩阵分解
"""

2.2 基于物品的协同过滤

复制代码
核心思想:
  相似的物品会被相似的用户喜欢

  步骤:
    1. 计算物品之间的相似度
    2. 用用户历史交互的相似物品预测评分
    
  预测公式:
    r̂(u, i) = Σ_{j∈I(u)} sim(i, j) · r_{u,j} / Σ |sim(i, j)|
    
    其中:
      I(u): 用户 u 交互过的物品集合
      sim(i, j): 物品 i 和 j 的相似度

优势:
  物品数量通常比用户数量少
  物品相似度可以离线计算
  更稳定 (物品变化比用户慢)
python 复制代码
class ItemBasedCF:
    """
    基于物品的协同过滤
    
    理论:
      相似物品会被相似用户喜欢
      用用户历史中的相似物品预测
      
    优势:
      - 物品数通常少于用户数
      - 物品相似度更稳定
      - 可以离线计算
    """
    def __init__(self, k=20):
        self.k = k
    
    def fit(self, ratings):
        self.ratings = ratings
        
        # 计算物品相似度矩阵
        self.sim_matrix = cosine_similarity(ratings.T)  # [n_items, n_items]
        np.fill_diagonal(self.sim_matrix, 0)
    
    def predict(self, user, item):
        # 用户交互过的物品
        rated_items = np.where(self.ratings[user] != 0)[0]
        
        if len(rated_items) == 0:
            return 0
        
        # 选择最相似的 k 个物品
        similarities = self.sim_matrix[item, rated_items]
        top_k_idx = np.argsort(similarities)[-self.k:]
        top_k_items = rated_items[top_k_idx]
        top_k_sims = similarities[top_k_idx]
        
        # 加权平均
        if np.sum(np.abs(top_k_sims)) == 0:
            return 0
        
        pred = np.sum(top_k_sims * self.ratings[user, top_k_items]) / np.sum(np.abs(top_k_sims))
        
        return pred

"""
ItemCF vs UserCF:

  UserCF:
    适合用户数 << 物品数的场景
    推荐结果新颖性高
    
  ItemCF:
    适合物品数 << 用户数的场景
    推荐结果更稳定
    
  实践中 ItemCF 更常用
"""

3. 矩阵分解

3.1 基本矩阵分解

复制代码
论文: "Matrix Factorization Techniques for Recommender Systems" (Koren et al., 2009)

核心思想:
  将用户-物品评分矩阵分解为用户矩阵和物品矩阵的乘积
  
  R ≈ U · V^T
  
  其中:
    R ∈ ℝ^{m×n}: 用户-物品评分矩阵
    U ∈ ℝ^{m×k}: 用户隐因子矩阵
    V ∈ ℝ^{n×k}: 物品隐因子矩阵
    k: 隐因子维度 (通常 10-200)

理论:
  每个用户用 k 维向量表示
  每个物品用 k 维向量表示
  评分 = 用户向量与物品向量的点积
  
  r̂(u, i) = u_u · v_i = Σ_f u_{u,f} · v_{i,f}

优化目标:
  min Σ_{(u,i)∈observed} (r_{u,i} - u_u · v_i)² + λ(‖u_u‖² + ‖v_i‖²)
  
  最小化观测评分的平方误差 + L2 正则化
python 复制代码
import torch
import torch.nn as nn

class MatrixFactorization(nn.Module):
    """
    矩阵分解模型
    
    R ≈ U · V^T
    
    理论:
      将稀疏的评分矩阵分解为稠密的用户/物品向量
      用向量点积预测评分
    """
    def __init__(self, num_users, num_items, embedding_dim=64):
        super().__init__()
        
        # 用户嵌入
        self.user_embedding = nn.Embedding(num_users, embedding_dim)
        
        # 物品嵌入
        self.item_embedding = nn.Embedding(num_items, embedding_dim)
        
        # 用户和物品偏置
        self.user_bias = nn.Embedding(num_users, 1)
        self.item_bias = nn.Embedding(num_items, 1)
        
        # 全局偏置
        self.global_bias = nn.Parameter(torch.zeros(1))
        
        # 初始化
        nn.init.normal_(self.user_embedding.weight, std=0.01)
        nn.init.normal_(self.item_embedding.weight, std=0.01)
        nn.init.zeros_(self.user_bias.weight)
        nn.init.zeros_(self.item_bias.weight)
    
    def forward(self, user_ids, item_ids):
        """
        user_ids: [B] 用户 ID
        item_ids: [B] 物品 ID
        返回: [B] 预测评分
        """
        # 嵌入查找
        user_emb = self.user_embedding(user_ids)  # [B, D]
        item_emb = self.item_embedding(item_ids)  # [B, D]
        
        user_b = self.user_bias(user_ids).squeeze()  # [B]
        item_b = self.item_bias(item_ids).squeeze()  # [B]
        
        # 预测: 全局偏置 + 用户偏置 + 物品偏置 + 用户·物品
        pred = (self.global_bias + user_b + item_b + 
                (user_emb * item_emb).sum(dim=1))
        
        return pred

"""
矩阵分解的理论分析:

  1. 隐因子的含义:
     每个维度可以解释为某种"特质"
     例如: 动作程度、喜剧程度、文艺程度
     
  2. 几何解释:
     用户和物品在同一隐空间中
     距离近 = 喜好度高
     
  3. 泛化能力:
     即使两个用户没有共同评分的物品
     也可以通过隐向量比较相似度
"""

3.2 SVD++

复制代码
论文: "Factorization Meets the Neighborhood: A Multifaceted Collaborative 
      Filtering Model" (Koren, 2008)

改进:
  在矩阵分解的基础上,加入隐式反馈信息

  预测公式:
    r̂(u, i) = μ + b_u + b_i + v_i · (u_u + |N(u)|^{-1/2} Σ_{j∈N(u)} y_j)
    
    其中:
      N(u): 用户 u 交互过的物品集合 (隐式反馈)
      y_j: 物品 j 的辅助嵌入
      
  理论:
    不仅用用户的显式评分向量
    还用用户的隐式行为 (点击、浏览等)
python 复制代码
class SVDPlusPlus(nn.Module):
    """
    SVD++ 模型
    
    在 MF 基础上加入隐式反馈
    
    理论:
      用户表示 = 显式嵌入 + 隐式行为聚合
      捕获用户的历史行为模式
    """
    def __init__(self, num_users, num_items, embedding_dim=64):
        super().__init__()
        
        # 显式嵌入
        self.user_embedding = nn.Embedding(num_users, embedding_dim)
        self.item_embedding = nn.Embedding(num_items, embedding_dim)
        
        # 隐式反馈嵌入
        self.item_auxiliary = nn.Embedding(num_items, embedding_dim)
        
        # 偏置
        self.user_bias = nn.Embedding(num_users, 1)
        self.item_bias = nn.Embedding(num_items, 1)
        self.global_bias = nn.Parameter(torch.zeros(1))
    
    def forward(self, user_ids, item_ids, history_items, history_mask):
        """
        user_ids: [B]
        item_ids: [B]
        history_items: [B, L] 用户历史物品
        history_mask: [B, L] 历史掩码
        """
        # 显式嵌入
        user_emb = self.user_embedding(user_ids)
        item_emb = self.item_embedding(item_ids)
        
        # 隐式反馈聚合
        history_emb = self.item_auxiliary(history_items)  # [B, L, D]
        history_emb = history_emb * history_mask.unsqueeze(-1)  # 掩码
        implicit_feedback = history_emb.sum(dim=1) / (history_mask.sum(dim=1, keepdim=True) + 1e-8).sqrt()
        
        # 用户表示 = 显式 + 隐式
        user_combined = user_emb + implicit_feedback
        
        # 预测
        user_b = self.user_bias(user_ids).squeeze()
        item_b = self.item_bias(item_ids).squeeze()
        
        pred = self.global_bias + user_b + item_b + (user_combined * item_emb).sum(dim=1)
        
        return pred

"""
SVD++ 的优势:

  1. 利用隐式反馈:
     即使没有显式评分
     点击、浏览等行为也有价值
     
  2. 更好的用户表示:
     显式评分 + 隐式行为
     
  3. 冷启动改善:
     新用户可能有浏览行为
"""

4. 深度学习推荐模型

4.1 Wide & Deep

复制代码
论文: "Wide & Deep Learning for Recommender Systems" (Cheng et al., 2016)

核心思想:
  Wide 部分: 记忆历史模式 (线性模型)
  Deep 部分: 泛化到未见模式 (DNN)

  ┌─────────────────────────────────────────────────────────────┐
  │                                                             │
  │   Wide (记忆)              Deep (泛化)                      │
  │   ┌──────────────┐        ┌──────────────┐                 │
  │   │ 线性模型      │        │ Embedding    │                 │
  │   │              │        │      ↓       │                 │
  │   │ 特征交叉     │        │ Dense Layers │                 │
  │   │              │        │      ↓       │                 │
  │   └──────┬───────┘        └──────┬───────┘                 │
  │          │                       │                          │
  │          └───────┬───────────────┘                          │
  │                  ↓                                          │
  │            输出层 (联合训练)                                  │
  │                                                             │
  └─────────────────────────────────────────────────────────────┘

理论:
  Wide: 学习特征组合的记忆
    例: user_installed_app=Netflix & impression_app=Pandora → 点击
    
  Deep: 学习未见过的特征组合的泛化
    通过低维嵌入学习语义相似性
python 复制代码
class WideAndDeep(nn.Module):
    """
    Wide & Deep 模型
    
    Wide: 线性模型,记忆历史模式
    Deep: DNN,泛化到新组合
    
    理论:
      记忆 + 泛化 = 更好的推荐
    """
    def __init__(self, num_users, num_items, embedding_dim=32, 
                 deep_layers=[256, 128, 64]):
        super().__init__()
        
        # Wide 部分 (线性)
        self.wide_linear = nn.Linear(num_users + num_items, 1)
        
        # Deep 部分
        self.user_embedding = nn.Embedding(num_users, embedding_dim)
        self.item_embedding = nn.Embedding(num_items, embedding_dim)
        
        deep_input_dim = embedding_dim * 2
        layers = []
        for dim in deep_layers:
            layers.extend([
                nn.Linear(deep_input_dim, dim),
                nn.ReLU(),
                nn.BatchNorm1d(dim),
                nn.Dropout(0.2)
            ])
            deep_input_dim = dim
        
        self.deep_mlp = nn.Sequential(*layers)
        self.deep_output = nn.Linear(deep_layers[-1], 1)
        
        # 输出层
        self.output = nn.Sigmoid()
    
    def forward(self, user_ids, item_ids, wide_features):
        """
        user_ids: [B]
        item_ids: [B]
        wide_features: [B, wide_dim] Wide 特征 (one-hot)
        """
        # Wide
        wide_out = self.wide_linear(wide_features)
        
        # Deep
        user_emb = self.user_embedding(user_ids)
        item_emb = self.item_embedding(item_ids)
        deep_input = torch.cat([user_emb, item_emb], dim=1)
        deep_out = self.deep_output(self.deep_mlp(deep_input))
        
        # 联合
        pred = self.output(wide_out + deep_out)
        
        return pred

4.2 DeepFM

复制代码
论文: "DeepFM: A Factorization-Machine based Neural Network for CTR Prediction" 
      (Guo et al., 2017)

核心思想:
  FM 部分: 建模二阶特征交互
  Deep 部分: 建模高阶特征交互

  FM: 自动学习特征交叉 (不需要手工设计)
  Deep: 学习更复杂的模式
python 复制代码
class DeepFM(nn.Module):
    """
    DeepFM 模型
    
    FM: 二阶特征交互
    Deep: 高阶特征交互
    
    理论:
      FM 自动学习特征交叉
      Deep 学习更复杂的模式
      两者共享嵌入
    """
    def __init__(self, num_features, embedding_dim=16, deep_layers=[256, 128]):
        super().__init__()
        
        # 特征嵌入
        self.embedding = nn.Embedding(num_features, embedding_dim)
        
        # FM 一阶权重
        self.first_order = nn.Embedding(num_features, 1)
        
        # Deep 部分
        deep_input_dim = num_features * embedding_dim
        layers = []
        for dim in deep_layers:
            layers.extend([
                nn.Linear(deep_input_dim, dim),
                nn.ReLU(),
                nn.BatchNorm1d(dim),
                nn.Dropout(0.2)
            ])
            deep_input_dim = dim
        
        self.deep_mlp = nn.Sequential(*layers)
        self.deep_output = nn.Linear(deep_layers[-1], 1)
        
        self.bias = nn.Parameter(torch.zeros(1))
    
    def forward(self, feature_ids):
        """
        feature_ids: [B, F] 特征 ID
        """
        # 嵌入
        emb = self.embedding(feature_ids)  # [B, F, D]
        
        # FM 一阶
        first_order = self.first_order(feature_ids).sum(dim=1)  # [B, 1]
        
        # FM 二阶
        # (Σ v_i x_i)² - Σ (v_i x_i)² = Σ_{i≠j} <v_i, v_j> x_i x_j
        sum_of_emb = emb.sum(dim=1)  # [B, D]
        sum_of_square = (emb ** 2).sum(dim=1)  # [B, D]
        fm_second_order = 0.5 * ((sum_of_emb ** 2 - sum_of_square).sum(dim=1, keepdim=True))
        
        # Deep
        deep_input = emb.flatten(1)  # [B, F*D]
        deep_out = self.deep_output(self.deep_mlp(deep_input))
        
        # 联合
        pred = torch.sigmoid(self.bias + first_order + fm_second_order + deep_out)
        
        return pred

"""
FM 的理论:

  二阶特征交互:
    y = w_0 + Σ w_i x_i + Σ_{i<j} <v_i, v_j> x_i x_j
    
  直接计算: O(n²) 复杂度
  优化计算: O(n) 复杂度
  
  Σ_{i<j} <v_i, v_j> x_i x_j = 0.5 * (||Σ v_i x_i||² - Σ ||v_i x_i||²)
"""

4.3 DIN (Deep Interest Network)

复制代码
论文: "Deep Interest Network for Click-Through Rate Prediction" (Zhou et al., 2018)

核心思想:
  用户兴趣是多样的
  不同的历史行为对当前预测的重要性不同
  使用注意力机制自适应地加权历史行为

  理论:
    传统方法: 用户表示 = 所有历史行为的平均/求和
    DIN: 用户表示 = 注意力加权的历史行为
    
    注意力 = f(历史行为, 候选物品)
    
    不同的候选物品,激活不同的历史行为
python 复制代码
class DIN(nn.Module):
    """
    Deep Interest Network (DIN)
    
    核心创新:
      注意力机制加权历史行为
      
    理论:
      用户兴趣是多样的
      不同候选物品激活不同的历史行为
      注意力机制自适应地选择相关行为
    """
    def __init__(self, num_items, embedding_dim=32, attention_hidden=64):
        super().__init__()
        
        # 物品嵌入
        self.item_embedding = nn.Embedding(num_items, embedding_dim)
        
        # 注意力网络
        self.attention = nn.Sequential(
            nn.Linear(embedding_dim * 4, attention_hidden),
            nn.ReLU(),
            nn.Linear(attention_hidden, 1)
        )
        
        # DNN
        self.dnn = nn.Sequential(
            nn.Linear(embedding_dim * 3, 256),
            nn.ReLU(),
            nn.BatchNorm1d(256),
            nn.Dropout(0.2),
            nn.Linear(256, 128),
            nn.ReLU(),
            nn.Linear(128, 1)
        )
    
    def forward(self, candidate_ids, history_ids, history_mask):
        """
        candidate_ids: [B] 候选物品
        history_ids: [B, L] 历史物品
        history_mask: [B, L] 历史掩码
        """
        # 嵌入
        candidate_emb = self.item_embedding(candidate_ids)  # [B, D]
        history_emb = self.item_embedding(history_ids)  # [B, L, D]
        
        # 注意力计算
        # 将候选物品广播到每个历史物品
        candidate_expand = candidate_emb.unsqueeze(1).expand_as(history_emb)
        
        # 拼接特征
        attention_input = torch.cat([
            history_emb,
            candidate_expand,
            history_emb - candidate_expand,
            history_emb * candidate_expand
        ], dim=-1)  # [B, L, 4D]
        
        # 注意力权重
        attn_weights = self.attention(attention_input).squeeze(-1)  # [B, L]
        attn_weights = attn_weights.masked_fill(history_mask == 0, -1e9)
        attn_weights = torch.softmax(attn_weights, dim=-1)
        
        # 加权历史表示
        user_interest = (history_emb * attn_weights.unsqueeze(-1)).sum(dim=1)  # [B, D]
        
        # DNN
        dnn_input = torch.cat([candidate_emb, user_interest, candidate_emb * user_interest], dim=1)
        pred = torch.sigmoid(self.dnn(dnn_input))
        
        return pred

"""
DIN 的注意力机制:

  输入: [历史行为, 候选物品, 差异, 乘积]
  
  理论:
    差异: 捕获历史行为与候选的差异
    乘积: 捕获历史行为与候选的相似性
    
  效果:
    对于不同的候选物品
    激活不同的历史行为
    
    例:
      候选: 运动鞋 → 注意力集中在运动装备历史
      候选: 书籍 → 注意力集中在阅读历史
"""

4.4 DIEN (Deep Interest Evolution Network)

复制代码
论文: "Deep Interest Evolution Network for Click-Through Rate Prediction" 
      (Zhou et al., 2019)

改进:
  不仅考虑用户的历史行为
  还考虑兴趣的演化过程

  理论:
    用户兴趣是随时间变化的
    兴趣有演化轨迹
    使用 GRU 建模兴趣演化
python 复制代码
class DIEN(nn.Module):
    """
    Deep Interest Evolution Network (DIEN)
    
    核心创新:
      兴趣演化建模
      使用 GRU 捕获兴趣变化轨迹
      
    理论:
      用户兴趣是动态的
      兴趣有演化过程
      GRU 建模时序依赖
    """
    def __init__(self, num_items, embedding_dim=32):
        super().__init__()
        
        self.item_embedding = nn.Embedding(num_items, embedding_dim)
        
        # 兴趣抽取层 (GRU)
        self.interest_extractor = nn.GRU(
            input_size=embedding_dim,
            hidden_size=embedding_dim,
            batch_first=True
        )
        
        # 兴趣演化层 (注意力 GRU)
        self.evolution_gru = nn.GRU(
            input_size=embedding_dim,
            hidden_size=embedding_dim,
            batch_first=True
        )
        
        # 注意力
        self.attention = nn.Sequential(
            nn.Linear(embedding_dim * 2, 64),
            nn.ReLU(),
            nn.Linear(64, 1)
        )
        
        # 输出
        self.output = nn.Sequential(
            nn.Linear(embedding_dim * 2, 128),
            nn.ReLU(),
            nn.Linear(128, 1)
        )
    
    def forward(self, candidate_ids, history_ids, history_mask):
        # 嵌入
        history_emb = self.item_embedding(history_ids)
        candidate_emb = self.item_embedding(candidate_ids)
        
        # 兴趣抽取
        interest_seq, _ = self.interest_extractor(history_emb)
        
        # 兴趣演化 (注意力 GRU)
        evolved_seq = self.attention_gru(interest_seq, candidate_emb, history_mask)
        
        # 最终兴趣表示
        final_interest = evolved_seq[:, -1, :]
        
        # 预测
        pred = torch.sigmoid(self.output(torch.cat([candidate_emb, final_interest], dim=1)))
        
        return pred
    
    def attention_gru(self, interest_seq, candidate, mask):
        """注意力 GRU"""
        outputs = []
        hidden = None
        
        for t in range(interest_seq.shape[1]):
            # 注意力权重
            attn_input = torch.cat([interest_seq[:, t], candidate], dim=-1)
            attn_weight = torch.sigmoid(self.attention(attn_input))
            
            # 加权输入
            weighted_input = interest_seq[:, t] * attn_weight
            
            # GRU 步
            output, hidden = self.evolution_gru(
                weighted_input.unsqueeze(1), 
                hidden
            )
            outputs.append(output)
        
        return torch.cat(outputs, dim=1)

"""
DIEN 的理论:

  兴趣演化:
    t1: 对电子产品感兴趣
    t2: 开始关注手机
    t3: 深入研究 iPhone
    t4: 准备购买
    
  GRU 捕获这种演化轨迹
  注意力机制关注与候选物品相关的演化阶段
"""

5. 序列推荐

5.1 序列推荐概述

复制代码
序列推荐 (Sequential Recommendation):

  输入: 用户的历史行为序列 [i₁, i₂, ..., i_t]
  输出: 预测下一个物品 i_{t+1}

  与传统 CF 的区别:
    CF: 静态的用户-物品交互
    序列推荐: 考虑行为的顺序
    
  应用:
    - 下一个视频推荐
    - 下一个商品购买预测
    - 音乐播放列表预测

5.2 SASRec (Self-Attentive Sequential Recommendation)

复制代码
论文: "Self-Attentive Sequential Recommendation" (Kang & McAuley, 2018)

核心思想:
  使用 Transformer 的自注意力机制建模序列
  每个位置关注所有历史位置

  优势:
    - 并行计算
    - 长距离依赖
    - 灵活的注意力模式
python 复制代码
class SASRec(nn.Module):
    """
    SASRec (自注意力序列推荐)
    
    使用 Transformer 编码器建模行为序列
    
    理论:
      自注意力: 每个位置关注所有历史位置
      位置编码: 保留序列顺序信息
      因果掩码: 只关注过去
    """
    def __init__(self, num_items, embedding_dim=64, max_len=50, 
                 num_heads=2, num_layers=2):
        super().__init__()
        
        self.embedding_dim = embedding_dim
        
        # 物品嵌入
        self.item_embedding = nn.Embedding(num_items + 1, embedding_dim, padding_idx=0)
        
        # 位置嵌入
        self.position_embedding = nn.Embedding(max_len, embedding_dim)
        
        # Transformer 编码器
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=embedding_dim,
            nhead=num_heads,
            dim_feedforward=embedding_dim * 4,
            dropout=0.1,
            batch_first=True
        )
        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
        
        # 输出层
        self.output = nn.Linear(embedding_dim, num_items)
        
        # 因果掩码
        self.register_buffer('causal_mask', 
            torch.triu(torch.ones(max_len, max_len), diagonal=1).bool()
        )
    
    def forward(self, item_ids):
        """
        item_ids: [B, L] 物品序列
        """
        B, L = item_ids.shape
        
        # 嵌入
        item_emb = self.item_embedding(item_ids)
        position_ids = torch.arange(L, device=item_ids.device).unsqueeze(0)
        pos_emb = self.position_embedding(position_ids)
        
        x = item_emb + pos_emb
        
        # 因果掩码
        mask = self.causal_mask[:L, :L]
        padding_mask = (item_ids == 0)  # padding 位置
        
        # Transformer
        x = self.transformer(x, mask=mask, src_key_padding_mask=padding_mask)
        
        # 预测下一个物品
        # 使用每个位置的输出预测下一个
        logits = self.output(x)  # [B, L, num_items]
        
        return logits

"""
SASRec 的训练:

  输入: [i₁, i₂, ..., i_t]
  目标: [i₂, i₃, ..., i_{t+1}]
  
  损失: 交叉熵
  
  理论:
    每个位置预测下一个物品
    因果掩码保证只看到历史
"""

5.3 BERT4Rec

复制代码
论文: "BERT4Rec: Sequential Recommendation with Bidirectional Encoder Representations 
      from Transformer" (Sun et al., 2019)

核心思想:
  使用 BERT 的掩码语言模型思想
  随机掩码历史行为,预测被掩码的物品

  与 SASRec 的区别:
    SASRec: 单向 (只看过去)
    BERT4Rec: 双向 (看整个序列)
python 复制代码
class BERT4Rec(nn.Module):
    """
    BERT4Rec
    
    使用 BERT 的 MLM 思想进行序列推荐
    
    理论:
      随机掩码历史物品
      预测被掩码的物品
      双向注意力捕获上下文
    """
    def __init__(self, num_items, embedding_dim=64, max_len=50,
                 num_heads=2, num_layers=2, mask_ratio=0.2):
        super().__init__()
        
        self.mask_ratio = mask_ratio
        self.mask_token_id = num_items  # 特殊的掩码 token
        
        # 嵌入
        self.item_embedding = nn.Embedding(num_items + 1, embedding_dim)  # +1 for mask
        self.position_embedding = nn.Embedding(max_len, embedding_dim)
        
        # Transformer
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=embedding_dim,
            nhead=num_heads,
            dim_feedforward=embedding_dim * 4,
            batch_first=True
        )
        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
        
        # 输出
        self.output = nn.Linear(embedding_dim, num_items)
    
    def forward(self, item_ids):
        """
        item_ids: [B, L] 物品序列
        """
        B, L = item_ids.shape
        
        # 随机掩码 (训练时)
        if self.training:
            mask = torch.rand(B, L) < self.mask_ratio
            mask = mask & (item_ids != 0)  # 不掩码 padding
            
            input_ids = item_ids.clone()
            input_ids[mask] = self.mask_token_id
        else:
            input_ids = item_ids
            mask = torch.ones(B, L, dtype=torch.bool)
        
        # 嵌入
        item_emb = self.item_embedding(input_ids)
        pos_emb = self.position_embedding(torch.arange(L, device=item_ids.device))
        x = item_emb + pos_emb
        
        # Transformer (双向,无因果掩码)
        padding_mask = (input_ids == 0)
        x = self.transformer(x, src_key_padding_mask=padding_mask)
        
        # 预测
        logits = self.output(x)  # [B, L, num_items]
        
        return logits, mask

"""
BERT4Rec vs SASRec:

  SASRec:
    单向注意力 (因果掩码)
    自回归预测下一个
    
  BERT4Rec:
    双向注意力 (无因果掩码)
    掩码预测被遮挡的物品
    
  BERT4Rec 的优势:
    双向上下文更丰富
    训练效率更高 (并行预测多个掩码)
"""

6. 多任务学习

6.1 多任务学习概述

复制代码
多任务学习在推荐中的应用:

  推荐系统通常需要同时优化多个目标:
    - 点击率 (CTR)
    - 转化率 (CVR)
    - 停留时长
    - 点赞/收藏
    - 分享
    
  多任务学习:
    一个模型同时预测多个目标
    共享底层特征,各自的任务头

  理论:
    不同任务之间有相关性
    共享特征可以互相帮助
    缓解过拟合

6.2 Shared-Bottom 架构

python 复制代码
class SharedBottom(nn.Module):
    """
    Shared-Bottom 多任务架构
    
    所有任务共享底层网络
    每个任务有自己的任务头
    
    理论:
      底层共享: 学习通用特征
      任务头: 学习任务特定特征
    """
    def __init__(self, input_dim, shared_dim, task_dims, num_tasks):
        super().__init__()
        
        # 共享底层
        self.shared_bottom = nn.Sequential(
            nn.Linear(input_dim, shared_dim),
            nn.ReLU(),
            nn.BatchNorm1d(shared_dim),
            nn.Linear(shared_dim, shared_dim),
            nn.ReLU()
        )
        
        # 任务头
        self.task_heads = nn.ModuleList([
            nn.Sequential(
                nn.Linear(shared_dim, task_dim),
                nn.ReLU(),
                nn.Linear(task_dim, 1),
                nn.Sigmoid()
            )
            for task_dim, _ in zip(task_dims, range(num_tasks))
        ])
    
    def forward(self, x):
        # 共享特征
        shared_features = self.shared_bottom(x)
        
        # 各任务预测
        predictions = [head(shared_features) for head in self.task_heads]
        
        return predictions

"""
Shared-Bottom 的问题:

  任务冲突: 不同任务的梯度可能冲突
  负迁移: 一个任务可能损害另一个任务
  
  解决: MMoE, PLE 等门控机制
"""

6.3 MMoE (Multi-gate Mixture-of-Experts)

复制代码
论文: "Modeling Task Relationships in Multi-task Learning with Multi-gate 
      Mixture-of-Experts" (Ma et al., 2018)

核心思想:
  使用多个专家网络
  每个任务有自己的门控网络
  自适应地选择专家组合

  理论:
    不同任务可能需要不同的特征
    门控网络学习任务相关的专家组合
    缓解任务冲突
python 复制代码
class MMoE(nn.Module):
    """
    MMoE (Multi-gate Mixture-of-Experts)
    
    多个专家网络 + 任务特定门控
    
    理论:
      每个任务有自己的门控
      门控学习选择哪些专家
      不同任务可以有不同的专家组合
    """
    def __init__(self, input_dim, expert_dim, num_experts, num_tasks):
        super().__init__()
        
        self.num_experts = num_experts
        self.num_tasks = num_tasks
        
        # 专家网络
        self.experts = nn.ModuleList([
            nn.Sequential(
                nn.Linear(input_dim, expert_dim),
                nn.ReLU(),
                nn.Linear(expert_dim, expert_dim),
                nn.ReLU()
            )
            for _ in range(num_experts)
        ])
        
        # 门控网络 (每个任务一个)
        self.gates = nn.ModuleList([
            nn.Sequential(
                nn.Linear(input_dim, num_experts),
                nn.Softmax(dim=-1)
            )
            for _ in range(num_tasks)
        ])
        
        # 任务头
        self.task_heads = nn.ModuleList([
            nn.Sequential(
                nn.Linear(expert_dim, 64),
                nn.ReLU(),
                nn.Linear(64, 1),
                nn.Sigmoid()
            )
            for _ in range(num_tasks)
        ])
    
    def forward(self, x):
        """
        x: [B, input_dim]
        """
        # 专家输出
        expert_outputs = [expert(x) for expert in self.experts]
        expert_outputs = torch.stack(expert_outputs, dim=1)  # [B, E, D]
        
        # 各任务的门控和预测
        predictions = []
        for task_idx in range(self.num_tasks):
            # 门控权重
            gate_weights = self.gates[task_idx](x)  # [B, E]
            
            # 加权专家输出
            task_input = (expert_outputs * gate_weights.unsqueeze(-1)).sum(dim=1)  # [B, D]
            
            # 任务预测
            pred = self.task_heads[task_idx](task_input)
            predictions.append(pred)
        
        return predictions

"""
MMoE 的理论:

  专家网络: 学习不同的特征表示
  门控网络: 学习任务相关的专家选择
  
  对于任务 A: 可能主要使用专家 1, 3
  对于任务 B: 可能主要使用专家 2, 4
  
  效果:
    缓解任务冲突
    提升多任务性能
"""

7. 知识图谱推荐

7.1 知识图谱概述

复制代码
知识图谱 (Knowledge Graph, KG) 在推荐中的应用:

  知识图谱: 实体和关系的网络
  
  例:
    (电影, 属于, 动作片)
    (电影, 导演, 诺兰)
    (电影, 演员, 小李子)
    (用户, 喜欢, 动作片)
    
  优势:
    1. 丰富物品的语义信息
    2. 提供可解释性
    3. 缓解冷启动问题

7.2 KGAT (Knowledge Graph Attention Network)

复制代码
论文: "KGAT: Knowledge Graph Attention Network for Recommendation" 
      (Wang et al., 2019)

核心思想:
  在知识图谱上使用注意力机制
  聚合邻居信息
  学习实体和关系的表示
python 复制代码
class KGAT(nn.Module):
    """
    KGAT (知识图谱注意力网络)
    
    在知识图谱上使用图注意力
    
    理论:
      实体表示 = 聚合邻居信息
      注意力权重 = 基于关系和实体
    """
    def __init__(self, num_entities, num_relations, embedding_dim=64):
        super().__init__()
        
        # 实体和关系嵌入
        self.entity_embedding = nn.Embedding(num_entities, embedding_dim)
        self.relation_embedding = nn.Embedding(num_relations, embedding_dim)
        
        # 注意力网络
        self.attention = nn.Sequential(
            nn.Linear(embedding_dim * 3, 64),
            nn.ReLU(),
            nn.Linear(64, 1)
        )
    
    def forward(self, entity_ids, neighbor_ids, relation_ids):
        """
        entity_ids: [B] 实体 ID
        neighbor_ids: [B, N] 邻居实体 ID
        relation_ids: [B, N] 关系 ID
        """
        # 嵌入
        entity_emb = self.entity_embedding(entity_ids)  # [B, D]
        neighbor_emb = self.entity_embedding(neighbor_ids)  # [B, N, D]
        relation_emb = self.relation_embedding(relation_ids)  # [B, N, D]
        
        # 注意力计算
        entity_expand = entity_emb.unsqueeze(1).expand_as(neighbor_emb)
        attn_input = torch.cat([entity_expand, neighbor_emb, relation_emb], dim=-1)
        attn_weights = torch.softmax(self.attention(attn_input).squeeze(-1), dim=-1)
        
        # 聚合邻居信息
        aggregated = (neighbor_emb * attn_weights.unsqueeze(-1)).sum(dim=1)
        
        # 更新实体表示
        updated_entity = entity_emb + aggregated
        
        return updated_entity

"""
知识图谱推荐的优势:

  1. 丰富语义:
     物品有丰富的属性和关系
     
  2. 可解释性:
     推荐理由: "因为你喜欢动作片,推荐这部"
     
  3. 冷启动:
     新物品可以通过知识图谱获得信息
"""

8. 图神经网络推荐

8.1 用户-物品交互图

复制代码
用户-物品交互可以建模为二部图:

  节点: 用户 + 物品
  边: 交互 (点击、购买、评分)
  
  ┌─────────────────────────────────────────────────────────────┐
  │                                                             │
  │   用户节点              物品节点                            │
  │   ○ u₁ ─────────────── ○ i₁                                │
  │   │      ╲             │                                    │
  │   │        ╲           ○ i₂                                │
  │   ○ u₂ ────────────────│                                    │
  │   │                    ○ i₃                                │
  │   │         ╱          │                                    │
  │   ○ u₃ ───╱────────── ○ i₄                                │
  │                                                             │
  └─────────────────────────────────────────────────────────────┘

  GNN 在图上传播信息:
    用户表示 = 聚合交互过的物品信息
    物品表示 = 聚合交互过的用户信息

8.2 LightGCN

复制代码
论文: "LightGCN: Simplifying and Powering Graph Convolution Network for 
      Recommendation" (He et al., 2020)

核心思想:
  简化 GCN,去掉特征变换和非线性激活
  只保留邻域聚合

  消息传播:
    e_u^{(k+1)} = Σ_{i∈N(u)} (1/√|N(u)|·√|N(i)|) · e_i^{(k)}
    e_i^{(k+1)} = Σ_{u∈N(i)} (1/√|N(i)|·√|N(u)|) · e_u^{(k)}
    
  最终表示:
    e_u = Σ_{k=0}^K α_k · e_u^{(k)}
    
  理论:
    去掉不必要的复杂性
    邻域聚合本身就是有效的
python 复制代码
class LightGCN(nn.Module):
    """
    LightGCN
    
    简化的图卷积网络
    
    理论:
      去掉特征变换和非线性
      只保留邻域聚合
      更简单,效果更好
    """
    def __init__(self, num_users, num_items, embedding_dim=64, num_layers=3):
        super().__init__()
        
        self.num_users = num_users
        self.num_items = num_items
        self.num_layers = num_layers
        
        # 嵌入
        self.user_embedding = nn.Embedding(num_users, embedding_dim)
        self.item_embedding = nn.Embedding(num_items, embedding_dim)
        
        nn.init.normal_(self.user_embedding.weight, std=0.1)
        nn.init.normal_(self.item_embedding.weight, std=0.1)
    
    def forward(self, user_ids, item_ids, adj_matrix):
        """
        user_ids: [B]
        item_ids: [B]
        adj_matrix: [num_users+num_items, num_users+num_items] 邻接矩阵
        """
        # 初始嵌入
        all_user_emb = self.user_embedding.weight  # [M, D]
        all_item_emb = self.item_embedding.weight  # [N, D]
        
        # 拼接所有嵌入
        all_emb = torch.cat([all_user_emb, all_item_emb], dim=0)  # [M+N, D]
        
        # 多层传播
        emb_list = [all_emb]
        for _ in range(self.num_layers):
            all_emb = torch.sparse.mm(adj_matrix, all_emb)
            emb_list.append(all_emb)
        
        # 聚合各层
        final_emb = torch.stack(emb_list, dim=0).mean(dim=0)
        
        # 分离用户和物品
        user_emb = final_emb[:self.num_users]
        item_emb = final_emb[self.num_users:]
        
        # 获取特定用户的嵌入
        user_feat = user_emb[user_ids]
        item_feat = item_emb[item_ids]
        
        # 预测
        pred = (user_feat * item_feat).sum(dim=1)
        
        return pred

"""
LightGCN 的优势:

  1. 简单: 没有复杂的非线性变换
  2. 高效: 只有矩阵乘法
  3. 有效: 效果优于复杂的方法
  
  理论:
    邻域聚合本身就是强大的操作
    不需要额外的复杂性
"""

9. 评估指标与实践

9.1 评估指标

复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                    推荐系统评估指标                                  │
├─────────────────┬───────────────────────────────────────────────────┤
│  类别            │  指标                                            │
├─────────────────┼───────────────────────────────────────────────────┤
│  准确率          │  RMSE, MAE (评分预测)                            │
│                 │  Precision@K, Recall@K (Top-K 推荐)              │
├─────────────────┼───────────────────────────────────────────────────┤
│  排序质量        │  NDCG@K (归一化折损累积增益)                     │
│                 │  MAP@K (平均精度均值)                             │
│                 │  MRR (平均倒数排名)                               │
├─────────────────┼───────────────────────────────────────────────────┤
│  分类质量        │  AUC, LogLoss (CTR 预测)                        │
├─────────────────┼───────────────────────────────────────────────────┤
│  覆盖率          │  Coverage (推荐物品的覆盖率)                     │
│                 │  Diversity (多样性)                               │
├─────────────────┼───────────────────────────────────────────────────┤
│  其他            │  新颖度, 惊喜度, 可解释性                        │
└─────────────────┴───────────────────────────────────────────────────┘
python 复制代码
class RecommendationMetrics:
    """推荐系统评估指标"""
    
    @staticmethod
    def precision_at_k(predictions, labels, k=10):
        """
        Precision@K
        
        前 K 个推荐中相关物品的比例
        """
        top_k = torch.topk(predictions, k).indices
        relevant = labels[top_k].sum()
        return relevant / k
    
    @staticmethod
    def recall_at_k(predictions, labels, k=10):
        """
        Recall@K
        
        相关物品中被推荐的比例
        """
        top_k = torch.topk(predictions, k).indices
        relevant = labels[top_k].sum()
        total_relevant = labels.sum()
        return relevant / (total_relevant + 1e-8)
    
    @staticmethod
    def ndcg_at_k(predictions, labels, k=10):
        """
        NDCG@K (归一化折损累积增益)
        
        NDCG = DCG@K / IDCG@K
        
        DCG = Σ rel_i / log2(i+1)
        
        理论:
          考虑排序位置的影响
          排在前面的物品更重要
        """
        top_k = torch.topk(predictions, k).indices
        
        # DCG
        relevance = labels[top_k]
        positions = torch.arange(1, k + 1, dtype=torch.float)
        dcg = (relevance / torch.log2(positions + 1)).sum()
        
        # IDCG (理想排序)
        ideal_relevance = torch.sort(labels, descending=True).values[:k]
        idcg = (ideal_relevance / torch.log2(positions + 1)).sum()
        
        return dcg / (idcg + 1e-8)
    
    @staticmethod
    def hit_rate_at_k(predictions, labels, k=10):
        """
        Hit Rate@K
        
        前 K 个推荐中是否包含相关物品
        """
        top_k = torch.topk(predictions, k).indices
        hit = (labels[top_k] > 0).any().float()
        return hit
    
    @staticmethod
    def auc(predictions, labels):
        """
        AUC (ROC 曲线下面积)
        
        衡量排序质量
        正样本排在负样本前面的概率
        """
        from sklearn.metrics import roc_auc_score
        return roc_auc_score(labels.numpy(), predictions.numpy())

"""
评估指标的选择:

  评分预测: RMSE, MAE
  Top-K 推荐: Precision@K, Recall@K, NDCG@K
  CTR 预测: AUC, LogLoss
  
  实践中:
    NDCG@K 最常用 (考虑排序质量)
    离线评估 + 在线 A/B 测试
"""

9.2 A/B 测试

复制代码
A/B 测试:

  在线评估推荐系统的金标准

  流程:
    1. 将用户随机分为实验组和对照组
    2. 实验组使用新算法
    3. 对照组使用旧算法
    4. 比较关键指标
    
  关键指标:
    - 点击率 (CTR)
    - 转化率 (CVR)
    - 用户停留时长
    - 用户留存率
    - 收入
    
  注意事项:
    - 样本量要足够大
    - 测试时间要足够长
    - 考虑用户的新奇效应

10. 工业应用与前沿

10.1 工业推荐系统架构

复制代码
工业推荐系统的挑战:

  1. 规模: 数亿用户,数十亿物品
  2. 实时性: 毫秒级响应
  3. 新鲜度: 实时更新模型
  4. 多样性: 避免信息茧房
  
  解决方案:
    - 多级架构: 召回 → 粗排 → 精排 → 重排
    - 分布式训练: 参数服务器
    - 实时特征: 流式计算
    - 在线学习: 增量更新

10.2 前沿方向

复制代码
推荐系统的前沿:

  1. 大模型推荐:
     LLM 作为推荐系统的 backbone
     用 prompt 做推荐
     
  2. 多模态推荐:
     结合文本、图像、视频
     CLIP 等模型的应用
     
  3. 因果推荐:
     去除偏差 (位置偏差、曝光偏差)
     因果推断
     
  4. 联邦推荐:
     保护用户隐私
     联邦学习
     
  5. 强化推荐:
     长期收益优化
     探索与利用
     
  6. 可解释推荐:
     解释推荐理由
     提升用户信任

附录

A. 推荐系统发展时间线

复制代码
2006  ──┬──  矩阵分解 (Netflix Prize)
        │
2014  ──┼──  Word2Vec (物品嵌入)
        │
2016  ──┼──  Wide & Deep
        │
2017  ──┼──  DeepFM
        │
2018  ──┼──  DIN (注意力机制)
        │
2019  ──┼──  DIEN (兴趣演化)
        │
2020  ──┼──  LightGCN (图推荐)
        │
2021  ──┼──  SASRec, BERT4Rec (序列推荐)
        │
2023+ ──┴──  LLM + 推荐

B. 核心公式速查

公式 含义
r̂ = u·v 矩阵分解预测
y = w₀ + Σwᵢxᵢ + Σ<vᵢ,vⱼ>xᵢxⱼ FM 预测
α = softmax(QK^T/√d) 注意力权重
NDCG = DCG / IDCG 归一化折损累积增益

C. 推荐资源

  • Koren, Y., et al. (2009). Matrix Factorization Techniques
  • Cheng, H., et al. (2016). Wide & Deep Learning
  • Zhou, G., et al. (2018). Deep Interest Network
  • He, X., et al. (2020). LightGCN
相关推荐
老鱼说AI2 小时前
统计学习方法第八章:Boosting
人工智能·深度学习·神经网络·机器学习·学习方法·集成学习·boosting
钓了猫的鱼儿2 小时前
基于深度学习+AI的无人机森林火灾目标检测与预警系统(Python源码+数据集+UI可视化界面+YOLOv11训练结果)
人工智能·深度学习·无人机
无负今日_tq2 小时前
【无标题】
人工智能·深度学习·条纹
爱吃肉的鹏2 小时前
基于深度学习的电缆异常检测
人工智能·深度学习
钓了猫的鱼儿2 小时前
基于深度学习+AI的茶叶病害目标检测与预警系统(Python源码+数据集+UI可视化界面+YOLOv11训练结果)
人工智能·深度学习·目标检测
云和数据.ChenGuang2 小时前
深度学习在鲲鹏HPC下的学习
人工智能·深度学习·学习·机器学习·数据挖掘
YOLO数据集集合3 小时前
无人机航拍+深度学习落地智慧农业:作物出苗率目标检测开源数据集工程详解|YOLO作物计数、田间苗期AI监测、农情数字化训练资源
人工智能·深度学习·yolo·目标检测·计算机视觉·无人机
烬羽3 小时前
从零搭建AIGC应用:英伟达NIM + Node.js实战
深度学习
凯丨3 小时前
强化学习真能“教会“智能体推理吗?拆解 Agentic RL 的边界与配方
人工智能·推荐算法