概述
矩阵分解相当于一种Embedding 方法。矩阵分解的主要过程,就是先分解矩阵协同过滤生成的共现矩阵,生成用户和物品的隐向量,再通过用户和物品隐向量的相似性进行推荐。那么该通过什么方法把共现矩阵分解开?最常用的方法就是梯度下降。
矩阵分解协同过滤的核心思想是将用户-物品共现矩阵(如评分矩阵)分解为两个低维矩阵的乘积,从而得到用户和物品的隐向量(Embedding),然后通过向量相似度进行推荐。
分解的过程通常采用梯度下降优化算法来最小化预测误差。
什么是共现矩阵
在协同过滤中,我们通常有一个 用户-物品评分矩阵(或交互矩阵),行是用户,列是物品,单元格是评分(或隐式反馈如点击、购买)。
这个矩阵通常非常稀疏,大部分单元格是空的。
**示例数据:**假设我们有 3 个用户(U1, U2, U3)和 4 个物品(I1, I2, I3, I4),评分范围 1~5。
| 用户\物品 | I1 | I2 | I3 | I4 |
|---|---|---|---|---|
| U1 | 5 | 3 | ? | 1 |
| U2 | 4 | ? | ? | 2 |
| U3 | 1 | 1 | 5 | ? |
(“?”表示未知,需要预测)
矩阵分解的目标
我们要将这个 3×4 的矩阵 R 近似分解为两个小矩阵的乘积:
R ≈ P × Q T R≈P× Q^TR≈P×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=pu⋅qiT(点积)
如何分解?通过最小化预测误差,即对已知评分,让预测值尽可能接近真实值。
损失函数与梯度下降
我们定义损失函数(正则化后的平方误差):
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∑(rui−pu⋅qiT)2+λ(∥pu∥2+∥qi∥2)
- 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=rui−pu⋅qiT
梯度:
∂ 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}∂pu∂L=−2euiqi+2λpu∂qi∂L=−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}pu←pu+η(euiqi−λpu)qi←qi+η(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=p1⋅q1T=0.1∗0.7+0.2∗0.8=0.07+0.16=0.23
计算误差:e 11 = 5 − 0.23 = 4.77 e_{11} = 5−0.23=4.77e11=5−0.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)p1←p1+η(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)q1←q1+η(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=p1⋅qiT
- 对尚未评分的物品(如 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。
推荐:用训练好的隐向量预测未知评分,推荐高评分的物品。