1.引入背景
为什么要设计BPR算法呢,因为在有些推荐场景下,我们并不是想知道用户对某个商品的评分或者喜好,我们只想知道用户对某些商品的特殊偏好,比如同时出现两个商品,用户会倾向于选择哪个商品。这是一种排序算法,排序算法不是用来学习用户的具体喜好,而是去学习用户的偏好,就算是两个不喜欢的,在用户心中也会有优先级。BPR就是一种基于pair的排序算法。
2.BPR定义
BPR,英文名称为Bayesian Personalized Ranking,中文名称为贝叶斯个性化排序,是当下推荐系统中常用的一种推荐算法。与其他的基于用户评分矩阵的方法不同的是BPR主要采用用户的隐式反馈(如点击、收藏等),通过对问题进行贝叶斯分析得到的最大后验概率来对item进行排序,进而产生推荐。
这里涉及一个概念,显示反馈和隐式反馈,下面简单介绍一下
显式反馈:用户对物品的评分,如电影评分;
隐式反馈:用户对物品的交互行为,如浏览,购买等,现实中绝大部分数据属于隐式反馈,可以从日志中获取。
3.BPR原理
在开始深入讲解原理之前我们先了解整个 BPR 的基础假设以及基本设定。
因为是基于贝叶斯的 Pairwise 方法,BPR 有两个基本假设:
1.每个用户之间的偏好行为相互独立,即用户
u
u
u在商品
i
i
i和
j
j
j之间的偏好和其他用户无关。
2.同一用户对不同物品的偏序相互独立,即用户
u
u
u在商品
i
i
i和
j
j
j之间的偏好和其他的商品无关。
基本设定:
U
U
U代表所有的用户集合;
I
I
I代表所有的物品集合;
S
S
S代表所有用户的隐式反馈,
S
⊆
U
×
I
S⊆U×I
S⊆U×I。如下图所示,只要用户对某个物品产生过行为,就标记为
+
+
+, 所有
+
+
+样本构成了
S
S
S。那些未观察到的数据(即用户没有产生行为的数据)标记为
?
?
?。
I u + = i ∈ I : ( u , i ) ∈ S I_{u}^+={i∈I:(u,i)∈S} Iu+=i∈I:(u,i)∈S代表了用户 u u u产生过行为的物品集合
U i + = u ∈ U : ( u , i ) ∈ S U_{i}^+={u∈U:(u,i)∈S} Ui+=u∈U:(u,i)∈S代表了对物品 i i i产生过行为的用户集合
假设有用户集 U U U和物品集 I I I,当用户 u ( u ∈ U ) u(u\in U) u(u∈U)在物品展示页面点击了物品 i ( i ∈ I ) i(i\in I) i(i∈I)却没有点击同样曝光在展示页面的物品 j ( j ∈ I ) j(j\in I) j(j∈I),则说明对于物品 i i i和物品 j j j,用户 u u u可能更加偏好物品 i i i,用 Pairwise 的思想则是物品 i i i的排序要比物品 j j j的排序更靠前,这个偏序关系可以写成一个三元组 < u , i , j > <u,i,j> <u,i,j>,为了简化表述,我们用 > u >_u >u符号表示用户 u 的偏好, < u , i , j > <u,i,j> <u,i,j>可以表示为: i > u j i>_uj i>uj。单独用 > u >_u >u代表用户 u u u对应的所有商品中两两偏序关系,可知 > u ⊂ I 2 >_u⊂I^2 >u⊂I2,且 > u >_u >u 满足下面的特性:
完整性:
∀
i
,
j
∈
I
:
i
≠
j
⇒
i
>
u
j
∪
j
>
u
i
(
t
o
t
a
l
i
t
y
)
\forall i,j∈I:i≠j⇒i>_uj∪j>_ui (totality)
∀i,j∈I:i=j⇒i>uj∪j>ui(totality)
反对称性:
∀
i
,
j
∈
I
:
i
>
u
j
∩
j
>
u
i
⇒
i
=
j
(
a
n
t
i
s
y
m
m
e
t
r
y
)
\forall i,j∈I:i>_uj∩j>_ui⇒i=j (antisymmetry)
∀i,j∈I:i>uj∩j>ui⇒i=j(antisymmetry)
传递性:
∀
i
,
j
,
k
∈
I
:
i
>
u
j
∩
j
>
u
k
⇒
i
>
u
k
(
t
r
a
n
s
i
t
i
v
i
t
y
)
\forall i,j,k∈I:i>_uj∩j>_uk⇒i>_uk (transitivity)
∀i,j,k∈I:i>uj∩j>uk⇒i>uk(transitivity)
4.BPR的优势
在使用隐式反馈的情况下,我们会发现观察到的数据均为正例(因为用户对物品交互过才会被观察到),而那些没有被观察到的数据(即用户还没有产生行为的物品),分为两种情况,一种是用户确实对该物品没有兴趣(负类),另一种则是缺失值(即用户以后可能会产生行为的物品)。
传统的个性化推荐通常是计算出用户u对物品i的个性化分数
x
ˉ
u
i
\bar{x}_{ui}
xˉui ,然后根据个性化分数进行排序。为了得到训练数据,通常是将所有观察到的隐式反馈
(
u
,
i
)
∈
S
(u,i) \in S
(u,i)∈S作为正类,其余所有数据作为负类,如下图所示,左图为观察到的数据,右图为填充后的训练数据:
由图可分析,我们对观测到的数据预测为1,其他的数据均预测为0。这就导致了我们在以后的预测值中,把所有的缺失值当做了负类数据,从而产生很大的误差。
1.矩阵分解的缺陷
我们知道,矩阵分解是通过预测用户对候选物品的评分,然后根据这个预测评分去排序,最后再推荐给用户。这种方法是一种典型的 Pointwise 方法,无论是预测评分还是预测隐式反馈,本质上都是在预测用户对一个物品的偏好程度。但是这种方法有很大的问题,因为很多时候我们只能收集到少数正例样本,剩下的数据其实是真实负例和缺失值的混合构成(这里的缺失值是指训练数据中除正例和负例外的未知数据,可以理解为未曝光或者曝光了的但是用户可能没有注意到缺失数据,所以缺失值中的样本即有可能是正例,也有可能是负例),而我们用这种方法构建训练数据的时候,往往无法确定负例到底是哪些,就只能把除正例以外的其他部分都当作是负例,这就会使得训练数据中负例的一部分其实是缺失值。把缺失值当作是负样本,再以预测误差为评判标准去使劲逼近这些样本。逼近正样本没问题,但是同时逼近的负样本只是缺失值而已,真正呈现在用户面前,并不能确定是不喜欢还是喜欢。而且,这样的模型仅能预测正例或负例,对于类别内的样本无法深入区别其重要性,不利于排序。当然,对于这种情况,我们也可以用一些其他方法来规避这些问题,比如负例采样,比如按预测概率排序,但这些方法也仅仅是 “缓兵之计”,对于解决排序问题来说并不完善。我们来看看 BPR 是怎么解决的,它是如何采用 Pairwise 方法来重新优化矩阵分解的。
2.BPR的优势所在
首先 BPR 利用 Pairwise 的思想来构建偏序关系,它依然没有从无反馈数据中去区分负例样本和缺失值,不过和之前的方法不一样的是,BPR 不是单纯地将无反馈数据都看做是负例,而是与正例结合一起来构建偏序关系。
这里的核心假设是,某用户对他有过反馈的物品的偏好程度一定比没有反馈过的物品高(这里的反馈一般指隐式反馈,如点击浏览等,不涉及负反馈),未反馈的物品包括真正的负例以及缺失值。BPR 试图通过用户的反馈矩阵 S 来为每一个用户构建出完整的偏序关系,也称全序关系,用
>
u
>_u
>u表示。如下图:
5.BPR模型构建
BPR模型本质上是一种矩阵分解算法,所以其模型本质上是为了将用户物品矩阵分解成两个低维矩阵,再由两个低维矩阵相乘后得到完整的矩阵。对于用户集U和物品集I对应的 U × I U \times I U×I的预测排序矩阵 X ‾ \overline X X,我们期望得到两个分解后的用户矩阵 W ( ∣ U ∣ × k ) W(|U| \times k) W(∣U∣×k) 和物品矩阵 H ( ∣ I ∣ × k ) H(|I| \times k) H(∣I∣×k),满足:
X
‾
=
W
H
T
\overline X=WH^T
X=WHT
那么对于任意一个用户u,对应的任意一个物品i,我们预测得出的用户对该物品的偏好计算如下:
x
‾
=
w
u
⋅
h
i
=
∑
f
=
1
k
w
u
f
h
i
f
\overline x=w_u⋅h_i=\sum_{f=1}^kw_{uf}h_{if}
x=wu⋅hi=∑f=1kwufhif
而模型的最终目标是寻找合适的矩阵
W
W
W和
H
H
H,让
X
‾
\overline X
X和
X
X
X(实际的评分矩阵)最相似。看到这里,也许你会说,BPR和矩阵分解没有什区别呀?是的,到目前为止的基本思想是一致的,但是具体的算法运算思路,确实千差万别的,我们慢慢道来。
6.BPR算法优化
BPR 基于最大后验估计
P
(
W
,
H
∣
>
u
)
P(W,H|>_u)
P(W,H∣>u)来求解模型参数
W
、
H
W、H
W、H,这里我们用
θ
\theta
θ来表示参数
W
,
H
W,H
W,H,
>
u
>_u
>u代表用户u对应的所有商品的全序关系,则优化目标是
P
(
θ
∣
>
u
)
P(θ|>u)
P(θ∣>u)。根据贝叶斯公式,我们有:
P
(
θ
∣
>
u
)
=
P
(
>
u
∣
θ
)
P
(
θ
)
P
(
>
u
)
P(θ|>_u)=\frac{P(>_u|θ)P(θ)}{P(>_u)}
P(θ∣>u)=P(>u)P(>u∣θ)P(θ)
由于我们假设了用户的喜好偏序和其他用户无关,那么对于任意一个用户u来说,
P
(
>
u
)
P(>u)
P(>u)对所有的物品一样,所以有:
P
(
θ
∣
>
u
)
∝
P
(
>
u
∣
θ
)
P
(
θ
)
P(θ|>_u) \propto P(>_u|θ)P(θ)
P(θ∣>u)∝P(>u∣θ)P(θ)
后验概率正比于似然概率乘上先验概率。
这个优化目标转化为两部分。似然概率
P
(
>
u
∣
θ
)
P(>_u|\theta)
P(>u∣θ)第一部分和样本数据集D有关,先验概率
P
(
θ
)
P(\theta)
P(θ)第二部分和样本数据集D无关。
第一部分
对于第一部分,由于我们假设每个用户之间的偏好行为相互独立,同一用户对不同物品的偏序相互独立,所以有:
∏
u
∈
U
P
(
>
u
∣
θ
)
=
∏
(
u
,
i
,
j
)
∈
(
U
×
I
×
I
)
P
(
i
>
u
j
∣
θ
)
δ
(
(
u
,
i
,
j
)
∈
D
)
(
1
−
P
(
i
>
u
j
∣
θ
)
)
δ
(
(
u
,
i
,
j
)
∉
D
)
\prod _{u\in U}P(>_u|θ)=\prod _{(u,i,j)\in(U×I×I)}P(i>_uj|θ)^{δ((u,i,j)\in D)}(1−P(i>_uj|θ))^{δ((u,i,j)\notin D)}
∏u∈UP(>u∣θ)=∏(u,i,j)∈(U×I×I)P(i>uj∣θ)δ((u,i,j)∈D)(1−P(i>uj∣θ))δ((u,i,j)∈/D)
其中:
δ
(
b
)
=
{
0
,
e
l
s
e
1
,
i
f
b
i
s
t
r
u
e
\delta(b)=\lbrace ^{1,if\space b\space is\space true}_{0,else}
δ(b)={0,else1,if b is true
上面的式子类似于极大似然估计,若用户u相比于j来说更偏向i,那么我们就希望P(i>uj|θ)出现的概率越大越好。上面的式子可以进一步改写成:
∏
u
∈
U
P
(
>
u
∣
θ
)
=
∏
(
u
,
i
,
j
)
∈
D
P
(
i
>
u
j
∣
θ
)
\prod _{u\in U}P(>_u|θ)=\prod _{(u,i,j)\in D}P(i>_uj|θ)
∏u∈UP(>u∣θ)=∏(u,i,j)∈DP(i>uj∣θ)
而对于
P
(
i
>
u
j
∣
θ
)
P(i>_uj|\theta)
P(i>uj∣θ)这个概率,我们可以使用下面这个式子来代替:
P
(
i
>
u
j
∣
θ
)
=
σ
(
x
‾
u
i
j
(
θ
)
)
P(i>_uj|\theta)=\sigma (\overline x_{uij}(θ))
P(i>uj∣θ)=σ(xuij(θ))
其中,
σ
(
x
)
\sigma(x)
σ(x)是sigmoid函数,
σ
\sigma
σ里面的项我们可以理解为用户u对i和j偏好程度的差异,差异越大越能区分i和j,这种差异最简单的体现方式就是作差:
x
‾
u
i
j
(
θ
)
=
x
‾
u
i
(
θ
)
–
x
‾
u
j
(
θ
)
\overline x_{uij}(θ)=\overline x_{ui}(θ)–\overline x_{uj}(θ)
xuij(θ)=xui(θ)–xuj(θ)
省略
θ
\theta
θ我们可以将式子简略的写为:
x
‾
u
i
j
=
x
‾
u
i
–
x
‾
u
j
\overline x_{uij}=\overline x_{ui}–\overline x_{uj}
xuij=xui–xuj
因此优化目标的第一项可以写作:
∏
u
∈
U
P
(
>
u
∣
θ
)
=
∏
(
u
,
i
,
j
)
∈
D
σ
(
x
‾
u
i
−
x
‾
u
j
)
\prod _{u\in U}P(>_u|\theta)=\prod _{(u,i,j)\in D}\sigma (\overline x_{ui}−\overline x_{uj})
∏u∈UP(>u∣θ)=∏(u,i,j)∈Dσ(xui−xuj)
显然,对于训练数据中的<u,i,j>,用户更偏好于i,那么我们当然希望在
X
‾
\overline X
X矩阵中
u
i
u_i
ui对应的值比
u
j
u_j
uj对应的值大,而且差距越大越好!
第二部分
当 θ \theta θ的先验分布是正态分布时,其实就是给损失函数加入了正则项,因此我们可以假定 θ \theta θ的先验分布是正态分布:
P
(
θ
)
∼
N
(
0
,
λ
θ
I
)
P(\theta)∼N(0,\lambda_\theta I)
P(θ)∼N(0,λθI)
所以:
l
n
P
(
θ
)
=
λ
∥
θ
∥
2
lnP(\theta)=\lambda∥\theta∥^2
lnP(θ)=λ∥θ∥2
因此,最终的最大对数后验估计函数可以写作:
l
n
P
(
θ
∣
>
u
)
∝
l
n
P
(
>
u
∣
θ
)
P
(
θ
)
=
l
n
∏
(
u
,
i
,
j
)
∈
D
σ
(
x
‾
u
i
−
x
‾
u
j
)
+
l
n
P
(
θ
)
=
∑
(
u
,
i
,
j
)
∈
D
l
n
σ
(
x
‾
u
i
−
x
‾
u
j
)
+
λ
∥
θ
∥
2
lnP(\theta|>_u)\propto lnP(>_u|θ)P(θ)=ln\prod_{(u,i,j)\in D}\sigma(\overline x_{ui}-\overline x_{uj})+lnP(\theta)=\sum _{(u,i,j)\in D}ln\sigma(\overline x_{ui}−\overline x_{uj})+\lambda∥\theta∥^2
lnP(θ∣>u)∝lnP(>u∣θ)P(θ)=ln∏(u,i,j)∈Dσ(xui−xuj)+lnP(θ)=∑(u,i,j)∈Dlnσ(xui−xuj)+λ∥θ∥2
剩下的我们就可以通过梯度上升法(因为是要让上式最大化)来求解了。
下面是用梯度上升法求解:
7.BPR算法流程
下面简要总结下BPR的算法训练流程:
输入:训练集D三元组,梯度步长
α
\alpha
α, 正则化参数
λ
\lambda
λ,分解矩阵维度
k
k
k。
输出:模型参数,矩阵
W
,
H
W,H
W,H
1.随机初始化矩阵
W
,
H
W,H
W,H
2.迭代更新模型参数:
w
u
f
=
w
u
f
+
α
(
∑
(
u
,
i
,
j
)
∈
D
1
1
+
e
x
‾
u
i
−
x
‾
u
j
(
h
i
f
−
h
j
f
)
+
λ
w
u
f
)
w_{uf}=w_{uf}+\alpha(\sum_{(u,i,j)∈D}\frac{1}{1+e^{\overline xui-\overline xuj}}(h_{if}−h_{jf})+λw_{uf})
wuf=wuf+α(∑(u,i,j)∈D1+exui−xuj1(hif−hjf)+λwuf)
h
i
f
=
h
i
f
+
α
(
∑
(
u
,
i
,
j
)
∈
D
1
1
+
e
x
‾
u
i
−
x
‾
u
j
w
u
f
+
λ
h
i
f
)
h_{if}=h_{if}+\alpha(\sum_{(u,i,j)∈D}\frac{1}{1+e^{\overline xui-\overline xuj}}w_{uf}+λh_{if})
hif=hif+α(∑(u,i,j)∈D1+exui−xuj1wuf+λhif)
h
j
f
=
h
j
f
+
α
(
∑
(
u
,
i
,
j
)
∈
D
1
1
+
e
x
‾
u
i
−
x
‾
u
j
−
w
u
f
+
λ
h
j
f
)
h_{jf}=h_{jf}+\alpha(\sum_{(u,i,j)∈D}\frac{1}{1+e^{\overline xui-\overline xuj}}-w_{uf}+λh_{jf})
hjf=hjf+α(∑(u,i,j)∈D1+exui−xuj1−wuf+λhjf)
3.如果
W
,
H
W,H
W,H收敛,则算法结束,输出
W
,
H
W,H
W,H,否则回到步骤2.
当我们拿到
W
,
H
W,H
W,H后,就可以计算出每一个用户u对应的任意一个商品的排序分:
x
‾
u
i
=
w
u
∙
h
i
\overline x_{ui}=w_u∙h_i
xui=wu∙hi,最终选择排序分最高的若干商品输出。
8.BPR小结
1.BPR是基于矩阵分解的一种排序算法,它不是做全局的评分优化,而是针对每一个用户自己的商品喜好分贝做排序优化。
2.它是一种pairwise的排序算法,对于每一个三元组<u,i,j>,模型希望能够使用户u对物品i和j的差异更明显。
3.同时,引入了贝叶斯先验,假设参数服从正态分布,在转换后变为了L2正则,减小了模型的过拟合。
9.参考文献
1.https://www.biaodianfu.com/bpr.html
2.https://www.cnblogs.com/pinard/p/9128682.html