推荐系统-矩阵分解

概述

矩阵分解相当于一种Embedding 方法。矩阵分解的主要过程,就是先分解矩阵协同过滤生成的共现矩阵,生成用户和物品的隐向量,再通过用户和物品隐向量的相似性进行推荐。那么该通过什么方法把共现矩阵分解开?最常用的方法就是梯度下降。

矩阵分解协同过滤的核心思想是将用户-物品共现矩阵(如评分矩阵)分解为两个低维矩阵的乘积,从而得到用户和物品的隐向量(Embedding),然后通过向量相似度进行推荐。

分解的过程通常采用梯度下降优化算法来最小化预测误差。

什么是共现矩阵

在协同过滤中,我们通常有一个 用户-物品评分矩阵(或交互矩阵),行是用户,列是物品,单元格是评分(或隐式反馈如点击、购买)。

这个矩阵通常非常稀疏,大部分单元格是空的。

**示例数据:**假设我们有 3 个用户(U1, U2, U3)和 4 个物品(I1, I2, I3, I4),评分范围 1~5。

用户\物品I1I2I3I4
U153?1
U24??2
U3115?

(“?”表示未知,需要预测)

矩阵分解的目标

我们要将这个 3×4 的矩阵 R 近似分解为两个小矩阵的乘积:
R ≈ P × Q T R≈P× Q^TRP×QT

其中:

  • P 是 3×k 的用户隐向量矩阵(每一行代表一个用户)。
  • Q 是 4×k 的物品隐向量矩阵(每一行代表一个物品)。
  • k 是隐向量维度(超参数,通常远小于用户数和物品数,例如 k=2)。

分解后,预测评分:r ^ u i = p u ⋅ q i T \hat{r}_{ui} = p_u \cdot q_i^Tr^ui=puqiT(点积)

如何分解?通过最小化预测误差,即对已知评分,让预测值尽可能接近真实值。

损失函数与梯度下降

我们定义损失函数(正则化后的平方误差):
L = ∑ ( u , i ) ∈ K ( r u i − p u ⋅ q i T ) 2 + λ ( ∥ p u ∥ 2 + ∥ q i ∥ 2 ) L = \sum_{(u,i) \in \mathcal{K}} \left( r_{ui} - p_u \cdot q_i^T \right)^2 + \lambda \left( \|p_u\|^2 + \|q_i\|^2 \right)L=(u,i)K(ruipuqiT)2+λ(pu2+qi2)

  • K 是已知评分的集合。
  • 第二项是正则化项,防止过拟合。

梯度下降

我们随机初始化 P 和 Q,然后迭代更新每个参数,沿着负梯度方向减小损失。

对每个已知评分 (u,i),预测误差e u i = r u i − p u ⋅ q i T e_{ui} = r_{ui} - p_u \cdot q_i^Teui=ruipuqiT

梯度:

∂ L ∂ p u = − 2 e u i q i + 2 λ p u ∂ L ∂ q i = − 2 e u i p u + 2 λ q i \begin{array}{l} \frac{\partial L}{\partial p_{u}} = -2e_{ui}q_{i} + 2\lambda p_{u} \\ \\ \frac{\partial L}{\partial q_{i}} = -2e_{ui}p_{u} + 2\lambda q_{i} \end{array}puL=2euiqi+2λpuqiL=2euipu+2λqi

更新规则(学习率 η):
p u ← p u + η ( e u i q i − λ p u ) q i ← q i + η ( e u i p u − λ q i ) \begin{array}{l} p_u \leftarrow p_u + \eta (e_{ui} q_i - \lambda p_u) \\ \\ q_i \leftarrow q_i + \eta (e_{ui} p_u - \lambda q_i) \end{array}pupu+η(euiqiλpu)qiqi+η(euipuλqi)

具体计算示例

设置 k=2,正则化系数 λ=0.1,学习率 η=0.01。

初始化隐向量(随机小值)

用户向量:

  • U1: p1=[0.1,0.2]
  • U2: p2=[0.3,0.4]
  • U3: p3=[0.5,0.6]

物品向量:

  • I1: q1=[0.7,0.8]
  • I2: q2=[0.9,1.0]
  • I3: q3=[1.1,1.2]
  • ]I4: q4=[1.3,1.4]

一次迭代(以已知评分 U1-I1 = 5 为例)

计算预测值:r ^ 11 = p 1 ⋅ q 1 T = 0.1 ∗ 0.7 + 0.2 ∗ 0.8 = 0.07 + 0.16 = 0.23 \hat{r}_{11} = p_1 \cdot q_1^T = 0.1 * 0.7 + 0.2 * 0.8 = 0.07 + 0.16 = 0.23r^11=p1q1T=0.10.7+0.20.8=0.07+0.16=0.23

计算误差:e 11 = 5 − 0.23 = 4.77 e_{11} = 5−0.23=4.77e11=50.23=4.77

更新 U1 的向量:
p 1 ← p 1 + η ( e 11 q 1 − λ p 1 ) p_{1} \leftarrow p_{1} + \eta \left( e_{11} q_{1} - \lambda p_{1} \right)p1p1+η(e11q1λp1)

  • 对第一个分量:0.1+0.01∗(4.77∗0.7−0.1∗0.1)=0.1+0.01∗(3.339−0.01)=0.1+0.03329=0.13329
  • 对第二个分量:
    0.2+0.01∗(4.77∗0.8−0.1∗0.2)=0.2+0.01∗(3.816−0.02)=0.2+0.03796=0.23796

更新 I1 的向量:
q 1 ← q 1 + η ( e 11 p 1 − λ q 1 ) q_1 \leftarrow q_1 + \eta(e_{11}p_1 - \lambda q_1)q1q1+η(e11p1λq1)

(注意:这里p 1 p_1p1应该使用更新前的值还是更新后的?通常使用更新前的值,因为我们是同步更新,但实际实现中可以异步。为简化,我们用更新前的p 1 p_1p1

  • 对第一个分量:0.7+0.01∗(4.77∗0.1−0.1∗0.7)=0.7+0.01∗(0.477−0.07)=0.7+0.00407=0.70407
  • 对第二个分量:0.8+0.01∗(4.77∗0.2−0.1∗0.8)=0.8+0.01∗(0.954−0.08)=0.8+0.00874=0.80874

对所有已知评分反复执行上述更新(每次随机选择一个样本,或批量),重复多轮(epoch),直到损失收敛。

经过足够多的迭代,P 和 Q 会收敛到较优值,使得预测误差最小。

得到隐向量后如何推荐?

训练结束后,对于用户 U1,我们有他的隐向量p 1 p_1p1=[最终值],以及所有物品的隐向量q i q_iqi

  • 计算 U1 对所有物品的预测评分:r ^ 1 i = p 1 ⋅ q i T \hat{r}_{1i} = p_1 \cdot q_i^Tr^1i=p1qiT
  • 对尚未评分的物品(如 I3)预测评分,然后按预测值降序排列,推荐 top-N。

例如,最终训练后,U1 对 I3 的预测评分为 4.2,对 I4 为 1.5,那么优先推荐 I3。

为什么说矩阵分解是 Embedding 方法?

因为最终的用户向量p u p_upu和物品向量q i q_iqi都是低维稠密向量,它们就是用户和物品的嵌入(embedding)。

这些向量不仅能用于评分预测,还能用于计算相似度(如余弦相似度),从而实现基于内容的推荐或聚类分析。

总结

共现矩阵:用户-物品评分矩阵。

矩阵分解:将其分解为用户隐向量矩阵 P 和物品隐向量矩阵 Q。

梯度下降:通过最小化预测误差和正则项,迭代更新 P 和 Q。

推荐:用训练好的隐向量预测未知评分,推荐高评分的物品。