算法应用场景
在推荐系统中,要根据用户的历史行为(点击、收藏、评分等),挖掘用户感兴趣的物品进行推荐(一般用作推荐系统里面的召回算法,来召回候选集)。这个问题就可以转换成:给定 用户-物品 的评分矩阵(稀疏矩阵),根据评分矩阵里面已有的评分,预测评分矩阵里面空缺的评分,然后对于每个用户,为其对应的物品向量的评分进行排序找出 Top-N,即可完成推荐。
问题分析
这里的中心问题是:如何根据 用户-物品 评分矩阵里面的非空值,预测出该矩阵里面空缺位置应该填的值?我们可以进行矩阵分解,将 user-item 矩阵分解成 2 个矩阵相乘的形式,那么这两个矩阵怎么表示呢?假设要将 user-item 矩阵(m∗n) 分解成 P(m∗k)、Q(k∗n)矩阵,根据矩阵相乘的性质,m∗n=(m∗k)∗(k∗n),所以这里的问题转化为求出 矩阵 P 和 Q,求出了 P 和 Q 之后,P∗Q 就可以将 user-item 矩阵空缺的地方填满,即得到未知的用户-物品对的预测评分
算法推导
推导损失函数
设 user-item 矩阵为 R,用户特征矩阵为 P,物品特征矩阵为 Q
R^=P∗Q
要计算的损失就是 user-item 矩阵里面的预测评分与已知评分的偏离程度,故损失函数用平方损失函数,(u,i) 是已知的 user-item 对
loss=(u,i)∈R∑(Rui−Rui^)2
加入正则项
loss=(u,i)∈R∑(Rui−PuT∗Qi)2+λu∑∣∣Pu∣∣2+λi∑∣∣Qi∣∣2
这里 Pu 是 (1∗k)维,Qi 是 (1∗k)维,代表 用户u和物品i 对应的 k 个隐因子组成的向量,由于隐因子的数量越多,模型越复杂,为减少过拟合,加入 L2 正则项
求解损失函数
梯度下降法
到这里其实就可以用梯度下降法来求解损失函数取得最小值时对应的参数矩阵了,当然不是一下子得到整个矩阵,是逐行求解在拼接即可, 故可以化简损失函数,以求 ∂Pu∂loss 为例,此时 Qi 可以看成常量
loss=(u,i)∈R∑(Rui−PuT∗Qi)2+λu∑∣∣Pu∣∣2+λi∑∣∣Qi∣∣2=u∑(i∑(Rui−PuT∗Qi)2+λ∣∣Pu∣∣2)
此时就相当于,对于每个物品,求出对应的用户评分向量了,所以遍历每一个物品,得到的用户评分向量拼接起来,就是 Q,求 P 同理。
令
L(Pu)=i∑(Rui−PuT∗Qi)2+λ∣∣Pu∣∣2L(Qi)=u∑(Rui−PuT∗Qi)2+λ∣∣Pu∣∣2
计算梯度
∂Pu∂L=2i∑(Rui−PuT∗Qi)∗(−Qi)+2λPu∂Qi∂L=2u∑(Rui−PuT∗Qi)∗(−Pu)+2λQi
每次迭代
Pu=Pu−η∂Pu∂lossQi=Qi−η∂Qi∂loss
直到 loss 达到阈值,或者达到最大迭代次数,此时的 Pu,Qi
交替最小二乘法
先回顾一下线性回归模型里面求解损失函数的最小二乘法,本质上就是令损失函数的偏导等于0,求出对应的参数
回顾最小二乘法求解线性回归
令要求解的回归方程表达式为:y=wTx+b
损失函数:J(w,b)=∑i=1m(yi−wTxi−b)2,m为样本个数
这里以 ∂b∂J(w,b)=0 求解 b 为例
∂b∂J(w,b)=∑i=1m2(yi−wTxi−b)=0
∑i=1myi−wT∑i=1mxi−∑i=1mb=0
mb=∑i=1myi−wT∑i=1mxi
解得:b=y−wTxˉ
那么交替最小二乘法呢?
对于损失函数
loss=(u,i)∈R∑(Rui−PuT∗Qi)2+λu∑∣∣Pu∣∣2+λi∑∣∣Qi∣∣2
Pu 和 Qi 是通过矩阵乘法耦合在一起的,我们可以先以 Pu 为常量,求解 Qi,在以Qi 为常量,求解 Pu,如此反复,知道达到迭代次数上限,或 loss 小于阈值。
这里以固定 Qi 求 Pu 为例,进行推导
loss=(u,i)∈R∑(Rui−PuT∗Qi)2+λu∑∣∣Pu∣∣2+λi∑∣∣Qi∣∣2=u∑(i∑(Rui−PuT∗Qi)2+λ∣∣Pu∣∣2)
令 L(Pu)=∑i(Rui−PuT∗Qi)2+λ∣∣Pu∣∣2
求偏导,令其=0:
∂Pu∂L=2i∑(Rui−PuT∗Qi)∗(−Qi)+2λPu=0
i∑PuTQiQi−i∑RuiQi+λPu=0
又 PuTQi=QiTPu,(ATB=(BTA)T)
i∑PuTQiQi−i∑RuiQi+λPu=i∑QiTPuQi−i∑RuiQi+λPu=0
(i∑QiTQi+λE)Pu=i∑RuiQi
(QTQ+λE)Pu=RuQi
最终得到:
Pu=(QiQiT+λE)−1RuQ
同理得:
Qi=(PPT+λE)−1PRi
开源库
implicit
pyspark.mllib.recommendation.ALS
这篇真的码了很久,累死了。。
笔记:
