Bayesian Personalized Ranking 是基于隐式反馈数据的非常通用的个性化模型,一般实现使用的是 matrix factorization 机制,利用随机梯度下降来求解。
假设用来表达训练集的三元组为 (u,i,j),只需要找到“最优化”的用户的 f 维向量表征 wuf,positive item i 的 f 维向量表征 hif,negative item j 的 f 维向量表征 hjf,则建模完毕。
它有以下几点优势:
- 不关注于拟合的具体数值损失最小,而是关注于 item 的排序关系
- 由于特殊的负采样策略,导致它的结果相对偏 High-Precision & Low-Recall
- 因为是潜变量模型,预测只是向量的相乘,工程化性能优异
1. 模型推导
考虑我们优化的目标(θ 是我们求解的任意参数,比如矩阵分解的潜向量,>u 代表了 user 对其他所有 item 的排序关系),它可以用贝叶斯公式表示为
P(θ∣>u)=P(>u)P(>u∣θ)P(θ)
假设所有的用户行为都是独立的,因此有
P(θ∣>u)∝P(>u∣θ)P(θ)
因此优化目标拆解成了两部分,先看第一部分,可以表示为
u∈U∏P(>u∣θ)=(u,i,j)∈D∏P(i>uj∣θ)
定义user u 和 item i 的内积为 user 对 item 的偏好 xui。
对于 P(i>uj∣θ) 这个概率,直观解释就是 xui 是否大于 xuj,大于零则表示:对于用户 u 来说,i 和 j 更偏好 i :
xuij=xui−xuj
但这里有个问题,这个如果直接减的话,是 non-continuous, non-differential,
所以我们需要变换一下,把 xui−xuj 的结果用 sigmod 函数变换一下(概率化),可以写成这样
P(i>uj∣θ)=σ(xuij(θ))
因此第一部分的优化目标就可以变成这个样子了:
u∈U∏P(>u∣θ)=(u,i,j)∈D∏σ(xui−xuj)
对于第二部分的 P(θ),我们将它简化为均值为0,协方差矩阵为 λθI,即
P(θ)∼N(0,λθI)
因此对数后验估计函数可以表示为:
lnP(θ∣>u)∝lnP(>u∣θ)P(θ)=ln(u,i,j)∈D∏σ(xuij)+lnP(θ)=(u,i,j)∈D∑lnσ(xuij)+λ∣∣θ∣∣2
上式的对于 θ 的一阶导为:
=(u,i,j)∏∂θ∂lnσ(xuij)−λθ∂θ∂∣∣θ∣∣2∝(u,i,j)∏1+exuije−xuij∂θ∂xuij−λθθ
在这里有
xuij=xui−xuj=f=1∑kwufhif−f=1∑kwufhjf
因此很容易得到:
∂θ∂(xui−xuj)=⎩⎨⎧(hif−hjf)wuf−wufifθ=wufifθ=hififθ=hjf
也就是说,对于矩阵分解算法的参数 θ 来说,user 的 f 维隐向量 wuf,以及 item 的 f 维隐向量 hif,hjf 非常容易通过梯度上升法来求解。
2. 实现细节
摘抄一部分 C++ 代码
prob = sum(U(user_id, _) * (I(liked_id, _) - I(disliked_id, _)));
prob = 1 / (1 + exp(prob));
temp = U(user_id, i);
U(user_id, i) += alpha * (prob * (I(liked_id, i) - I(disliked_id, i)) - lamb*temp);
I(liked_id, i) += alpha * (prob * temp - rlamb * I(liked_id, i));
I(disliked_id, i) += alpha * (-prob * temp - lamb * I(disliked_id, i));
可以很清晰的看到所有的运算基于 σ(xuij) 以及 wuf,hif,hjf 以及常数项 alpha, lambda。
negative item j 是通过抽样方式来确定的,实际在计算的过程中只考虑 positive item i,因为 negative item 很多,所以会在所有的 item 里随机抽一个,即便是抽到了 positive item 从概率上来讲也不会对计算速度和精度有太大影响,但速度会加快很多。(想象一下电商推荐场景,不点击的长尾商品很多)
在 51Talk 老师推荐的实际应用场景又有不同,我们只针对有评分(positive)的老师进行训练,来更新用户和老师的向量,实际效果更佳优异。