📖
Leon 的个人知识库
PERSONAL WIKI
22 篇文章

评分预测与模型融合

📖 来源:推荐系统实践(项亮)

评分预测与模型融合

评分预测(Rating Prediction)是推荐系统的经典研究问题,核心任务是根据用户的历史评分记录,预测用户对未评分物品的评分。Netflix Prize 大赛(2006-2009)是该领域最重要的推动力,最终获胜队伍通过融合上百个模型达到将预测误差降低 10% 的目标。

SVD 系列模型演进

flowchart TD Base[基础平均值\nGlobal Mean] --> |加入偏置| Bias[Bias Model\nμ + b_u + b_i] Bias --> |矩阵分解| FunkSVD[Funk-SVD\nR ≈ P·Q^T] FunkSVD --> |加入偏置| BiasSVD[BiasSVD\nμ + b_u + b_i + p_u·q_i] BiasSVD --> |加入隐式反馈| SVDpp[SVD++\n加入用户行为集合] SVDpp --> |加入时间特征| TimeSVD[TimeSVD++\n动态偏置函数] TimeSVD --> |模型融合| Ensemble[🏆 Ensemble\nNetflix Prize方案] style Ensemble fill:#FFD700

评分预测问题定义

数据集 :用户评分三元组 (u, i, r),表示用户 u 给物品 i 评分 r。由于用户不会对所有物品评分,评分矩阵 R 中存在大量缺失值(Missing Value),评分预测本质上是填空问题。

评测指标

均方根误差 RMSE(Netflix Prize 采用):

RMSE = sqrt(Σ (r_{ui} - r̂_{ui})² / |Test|)

平均绝对误差 MAE:

MAE = Σ |r_{ui} - r̂_{ui}| / |Test|

RMSE 对预测偏差更严格(平方项惩罚),研究表明若评分系统基于整数,对预测结果取整可以降低 MAE。

实验设置

  • 一般按时间划分:Netflix 的做法是每个用户最早 90% 的评分为训练集,最近 10% 为测试集
  • 与时间无关的任务:按均匀分布随机划分

TopN 推荐 vs 评分预测

亚马逊前科学家 Greg Linden 指出评分预测的局限性:电影推荐的目的是找到用户最可能感兴趣 的电影,而非预测他看后会给的分数。某部电影用户看后会给高分,但用户选择看它的可能性可能很低。因此 TopN 推荐更贴近实际系统需求,本书主体内容讨论 TopN 推荐(见 协同过滤算法),本章专注于评分预测。

评分预测算法

1. 平均值方法

最简单的基准算法,不同维度的平均值性能差异显著。

全局平均值

r̂_{ui} = μ = (1/|Train|) * Σ r_{ui}

物品平均值 (性能优于全局平均值):

r̂_{ui} = μ_i = (1/|N(i)|) * Σ_{u∈N(i)} r_{ui}

用户评分平均值

r̂_{ui} = μ_u = (1/|N(u)|) * Σ_{i∈N(u)} r_{ui}

类类平均值 (最强的平均值基准):

将用户和物品各自分类,对同类用户给同类物品的评分取平均。分类维度包括:

  • 用户活跃度(评分物品数量)
  • 物品流行度(评过分的用户数量)
  • 用户平均分(UserVoteCluster)
  • 物品平均分(ItemVoteCluster)

MovieLens 实验结果(Test RMSE):

UserGroup ItemGroup Test RMSE
Cluster(全局) Cluster 1.1167
IdCluster Cluster 1.0351
Cluster IdCluster 0.9779
UserVoteCluster IdCluster 0.9441
IdCluster ItemVoteCluster 0.9449
UserVoteCluster ** ItemVoteCluster** ** 0.9342**

结论:对用户按评分习惯分类(UserVoteCluster)、对物品按平均质量分类(ItemVoteCluster)效果最好。

2. 基于邻域的评分预测

UserCF 评分预测(皮尔逊系数相似度):

r̂_{ui} = μ_u + Σ_{v∈S(u,K)∩N(i)} w_{uv} * (r_{vi} - μ_v) / Σ|w_{uv}|

使用皮尔逊系数而非余弦相似度,因为它消除了不同用户评分尺度的差异:

w_{uv} = Σ_i (r_{ui}-μ_u)(r_{vi}-μ_v) / sqrt(Σ(r_{ui}-μ_u)² * Σ(r_{vi}-μ_v)²)

ItemCF 评分预测

r̂_{ui} = μ_i + Σ_{j∈S(i,K)∩N(u)} w_{ij} * (r_{uj} - μ_j) / Σ|w_{ij}|

物品相似度计算的三种方式(Sarwar 等比较):

  • 普通余弦相似度
  • 皮尔逊系数
  • 修正余弦相似度 (Adjusted Cosine):减去用户的评分均值再计算,效果最优
w_{ij} = Σ_u (r_{ui}-μ_u)(r_{uj}-μ_u) / sqrt(Σ_u(r_{ui}-μ_u)² * Σ_u(r_{uj}-μ_u)²)

3. 矩阵分解模型(LFM/SVD)

传统 SVD 分解

对评分矩阵 R 先用均值补全缺失值得 R',再做 SVD 分解:

R' = U * S * V^T   →   R̂ ≈ U_f * S_f * V_f^T

缺点 :需要先将稀疏矩阵补全为稠密矩阵(空间和计算代价极大),实际无法用于百万级用户/物品。

Funk-SVD(Simon Funk,2006)

Simon Funk 在博客上提出直接从观察值学习低维矩阵,引爆了学术界对矩阵分解的关注:

将 R 分解为两个低维矩阵:

R ≈ P * Q^T,即 r̂_{ui} = p_u · q_i = Σ_k p_{uk} * q_{ik}

损失函数(加 L2 正则化):

L = Σ_{(u,i)∈Train} (r_{ui} - p_u·q_i)² + λ(‖p_u‖² + ‖q_i‖²)

随机梯度下降迭代更新:

e_{ui} = r_{ui} - p_u · q_i
p_{uk} ← p_{uk} + α * (e_{ui} * q_{ik} - λ * p_{uk})
q_{ik} ← q_{ik} + α * (e_{ui} * p_{uk} - λ * q_{ik})
# 每轮衰减学习率:α *= 0.9
def LearningLFM(train, F, n, alpha, lambda_):
    p, q = InitLFM(train, F)
    for step in range(n):
        for u, i, rui in train.items():
            pui = sum(p[u][f] * q[i][f] for f in range(F))
            eui = rui - pui
            for f in range(F):
                p[u][f] += alpha * (q[i][f] * eui - lambda_ * p[u][f])
                q[i][f] += alpha * (p[u][f] * eui - lambda_ * q[i][f])
        alpha *= 0.9
    return p, q

初始化:矩阵元素用随机数填充,大小与 1/sqrt(F) 成正比。

BiasSVD(加入偏置项)

引入三个偏置项消除与用户/物品无关的系统性偏差:

r̂_{ui} = μ + b_u + b_i + p_u · q_i
  • μ :全局平均分(网站整体评分倾向)
  • b_u (用户偏置):该用户是否比较苛刻或宽松
  • b_i (物品偏置):该物品本身质量高低

偏置项通过同样的梯度下降学习,初始化为全 0。

SVD++(加入邻域影响)

Koren 在 Netflix Prize 中提出,将用户历史评分行为(隐式反馈)融入矩阵分解模型:

r̂_{ui} = μ + b_u + b_i + (p_u + |N(u)|^{-1/2} * Σ_{j∈N(u)} y_j) · q_i

其中 y_j 是物品 j 的隐式反馈向量(与 q_j 共享,令 x = q)。引入用户历史行为 N(u) 使预测更准确。

Netflix Prize 中 SVD++(F=50)的 RMSE = 0.8952,显著优于基础 LFM(RMSE = 0.9094)。

4. 加入时间信息的模型

TItemCF(时间衰减邻域模型)

BigChaos 提出:用户对近期评分物品的兴趣权重更高:

r̂_{ui}(t) = Σ_{j∈S(i,K)∩N(u)} w_{ij}(t) * (r_{uj} - μ_j)
w_{ij}(t) = w_{ij} * e^{-λ * |t_{ui} - t_{uj}|}

其中 t_{ui} - t_{uj} 是用户 u 对物品 i 和 j 的评分时间差,差值越大权重越小。

SVD 系列模型对比

模型 公式核心 改进点 RMSE提升
Funk-SVD r̂ = p_u · q_i 矩阵分解基础
BiasSVD r̂ = μ + b_u + b_i + p_u · q_i 加入用户/物品偏置 ~5%
SVD++ 加入隐式反馈集合N(u) 利用点击/购买等行为 ~5%
TimeSVD++ b_u(t), b_i(t) 随时间变化 用户兴趣漂移建模 ~2%
Ensemble 加权/Stacking融合 Netflix Prize核心武器 ~10%+

TSVD(三维矩阵分解)

对用户—物品—时间三维矩阵分解,将 BiasSVD 中的偏置项改为时间依赖:

r̂_{ui}(t) = μ(t) + b_u(t) + b_i(t) + p_u(t) · q_i
  • μ(t) :全局平均分随时间的变化
  • b_u(t) :用户偏置随时间的变化(反映用户评分习惯的演变)
  • b_i(t) :物品偏置随时间的变化(反映物品口碑随时间的变化)

TimeSVD++(Koren,2009)

在 SVD++ 基础上引入时间效应:

r̂_{ui}(t) = μ + b_u(t) + b_i(t) + p_u(t) · q_i + 季节效应项

季节效应:以时刻 t 所在的月份建模。

TimeSVD++(F=50)的 Netflix RMSE = 0.8824 ,是所有单模型中效果最好的。

Netflix Prize 各算法 RMSE 对比

方法 参数 RMSE
Global Average 1.1296
Item Average 1.0526
ItemCF K=25 0.9496
RSVD(Funk-SVD) F=96 0.9094
BiasSVD F=96 0.9039
SVD++ F=50 0.8952
TimeSVD++ ** F=50** ** 0.8824**

Netflix Prize 目标 RMSE ≤ 0.8563(比基准算法 Cinematch 的 0.9525 降低 10%),最终获奖队通过模型融合达到目标。

模型融合(Ensemble)

单个模型的性能提升空间有限,模型融合是进一步降低 RMSE 的关键手段。

级联融合(Cascade)

类似 AdaBoost:在现有预测器的基础上,训练下一个预测器来最小化残差:

r̂^{(t)}_{ui} = r̂^{(t-1)}_{ui} + Δ^{(t)}_{ui}

每一轮新预测器学习之前预测器的残差:

def Predict(train, test, alpha):
    total, count = {}, {}
    for record in train:
        gu = GetUserGroup(record.user)
        gi = GetItemGroup(record.item)
        # 学习残差(真实值 - 当前预测值)
        AddToMat(total, gu, gi, record.vote - record.predict)
        AddToMat(count, gu, gi, 1)
    for record in test:
        gu = GetUserGroup(record.user)
        gi = GetItemGroup(record.item)
        average = total[gu][gi] / (1.0 * count[gu][gi] + alpha)
        record.predict += average  # 累加残差预测

MovieLens 实验:对均值方法采用级联融合后,Test RMSE 从 0.9342 降至 0.9202

加权融合(Linear Blending)

将 K 个预测器的输出线性加权:

r̂_{ui} = Σ_k w_k * r̂^{(k)}_{ui}

为避免在同一训练集上学习权重造成过拟合,采用以下流程:

  1. 将训练集 A 分为 A1(大)和 A2(小,与测试集 B 生成方式一致)
  2. 在 A1 上分别训练 K 个预测器
  3. 在 A2 上用最小二乘法 学习线性融合权重 w_k
  4. 在完整训练集 A 上重新训练 K 个预测器,用学到的 w_k 融合,在 B 上预测

更复杂的融合方式包括神经网络融合(本质是回归问题,所有回归算法均可用)。

Netflix Prize 的模型融合经验

  • 最终获奖队(AT&T 研究人员)融合了上百个不同模型
  • 单模型 RMSE 最低可达约 0.88,融合后可降至 0.8563
  • 不同类型模型(邻域方法 + 矩阵分解 + 时间模型)互补性强,融合收益更大
  • 模型差异性(Diversity)是融合效果的关键,两个高度相似的模型融合收益有限

实践建议

  1. 先建立简单基准(全局均值、物品均值),逐步增加复杂度
  2. 矩阵分解(Funk-SVD → BiasSVD → SVD++)是单模型性能提升的主线
  3. 加入时间信息(TimeSVD++)通常能带来显著提升
  4. 模型融合是取得比赛名次的关键,但工程实现复杂度高
  5. 实际工业系统中,TopN 推荐比评分预测更重要(见 推荐系统概论

详细的 TopN 推荐算法(UserCF、ItemCF、LFM)见 协同过滤算法;实时推荐的工程架构见 推荐系统工程实践

← 链接到此页