一、背景
推荐系统主要解决用户和物品之间的相关性,以及推荐列表的多样性。相关性主要通过用户兴趣和物品之间的匹配程度来衡量,希望把用户感兴趣的物品推荐给用户,可以通过CTR预估模型来构建。多样性的衡量没有那么直观,一种方法是计算不同Item之间的cosin值,值越小表明多样性越好。
Hulu在NIPS 2018会议上发表的论文《Fast Greedy MAP Inference for Determinantal Point Process to Improve Recommendation Diversity》是基于行列式点过程来提升推荐系统多样性,在实验上取得了不错的效果.
二、行列式点过程基本原理
在介绍行列式点过程之前,先给出一些符号的约定:
集合使用大写字母表示,比如: Z Z Z
向量和矩阵分别通过粗体小写字母和粗体大写字母表示
( ⋅ ) ⊤ (\cdot)^{\top} (⋅)⊤表示向量或矩阵的转置
⟨ x , y ⟩ ⟨x,y⟩ ⟨x,y⟩是向量 x x x和 y y y的内积
给定子集 X X X和 Y Y Y , L X , Y L_{X,Y} LX,Y是 L L L 的sub-matrix,通过行中的 X X X 和列中的 Y Y Y 索引。
L X , X = L X , + L X , { i } = L X , i L_{X,X}=L_X,+L_{X,\lbrace i \rbrace}=L_{X,i} LX,X=LX,+LX,{i}=LX,i,
L { i } , X = L i , X L_{\lbrace i \rbrace,X}=L_{i,X} L{i},X=Li,X。
d e t ( L ) det(L) det(L) 是矩阵 L L L 的行列式,惯例上令 d e t ( L ∅ ) = 1 det(L_\emptyset)=1 det(L∅)=1
DPP(Determinantal Point Process)行列式点过程,是一种性能较高的概率模型。其将复杂的概率计算转换成简单的行列式计算,通过核矩阵(kernel matrix)的行列式计算每一个子集的概率。该概率可以理解为用户对推荐列表满意的概率,受到相关性与多样性两个因素的影响。具体地,对于给定的集合 Z = { 1 , 2 , . . . , M } Z=\lbrace 1,2,...,M \rbrace Z={1,2,...,M},一个DPP P P P 是定义在该集合的所有子集 2 Z 2^Z 2Z 上的一个概率度量。当 P P P 会为空集给出非零概率时,存在一个矩阵 L ∈ R M × M L∈R^{M×M} L∈RM×M ,对于所有子集 Y ⊆ Z Y⊆Z Y⊆Z, Y Y Y出现的概率满足:
P ( Y ) ∝ d e t ( L Y ) P(Y) \propto det(L_Y) P(Y)∝det(LY)
其中, L L L是一个实数型(real)、半正定(PSD)的核矩阵,它通过 Z Z Z的元素进行索引。这里简单介绍一下半正定矩阵的定义:
给定一个大小为 n × n n\times n n×n的实对称矩阵 A A A,若对于任意长度为 n n n的非零向量 x x x,有 x T A x ≥ 0 x^TAx\geq0 xTAx≥0成立,则矩阵 A A A是一个半正定矩阵。
推荐列表就是从候选商品集合中选择能够最大化后验概率的商品子集,这一筛选过程就是行列式点过程的最大后验概率推断MAP(maximum a posteriori inference)。
Y m a p = a r g m a x Y ⊆ Z + d e t ( L Y ) Y_{map}=arg\space max_{Y\subseteq Z}\space+det(L_{Y}) Ymap=arg maxY⊆Z +det(LY)
三、如何通过DPP优化推荐系统多样性
DPP中的核矩阵 L) 是一个半正定矩阵,可以被分解为 L = B T B L=B^TB L=BTB,其中 B B B的每一列为候选集中商品的表示向量。
为了将DPP模型应用于推荐场景中,考虑将每个列向量 B i B_{i} Bi分解为 B i = r i f i B_{i}=r_{i}f_{i} Bi=rifi,其中:
- r i r_{i} ri为item i i i 与user之间的相关性,并且 r i ≥ 0 r_{i}\geq0 ri≥0
- f i f_{i} fi 为item i i i的embedding,并且 ∣ ∣ f i ∣ ∣ 2 = 1 ||f_i||_2=1 ∣∣fi∣∣2=1
核矩阵中的元素可以被写成:
L i j = ⟨ B i , B j ⟩ = ⟨ r i f i , r j f j ⟩ = r i r j ⟨ f i , f j ⟩ L_{ij}=\langle B_i,B_j\rangle=\langle r_if_i, r_j f_j \rangle=r_i r_j \langle f_i, f_j \rangle Lij=⟨Bi,Bj⟩=⟨rifi,rjfj⟩=rirj⟨fi,fj⟩
其中, ⟨ f i , f j ⟩ = S i j \langle f_i,f_j \rangle=S_{ij} ⟨fi,fj⟩=Sij是商品 i i i与商品 j j j之间的相似度。所以,核矩阵可以被进一步写为:
L = D i a g ( r u ) ⋅ S ⋅ D i a g ( r u ) L=Diag(r_u)\cdot S \cdot Diag(r_u) L=Diag(ru)⋅S⋅Diag(ru)
其中, D i a g ( r u ) Diag(r_u) Diag(ru)是对角阵(diagonal matrix),它的对角向量(diagonal vector)是相关性度量向量 r u r_u ru 。则核矩阵的行列式可以表示为:
∣ L ∣ = ∣ D i a g ( r u ) ∣ ⋅ ∣ S ∣ ⋅ ∣ D i a g ( r u ) ∣ = ∏ i ∈ R u r u , i 2 ⋅ ∣ S ∣ \left|L\right|=\left|Diag\left(r_{u}\right)\right|\cdot\left|S\right|\cdot\left|Diag\left(r_{u}\right)\right|=\prod_{i\in R_{u}}r_{u,i}^{2}\cdot\left|S\right| ∣L∣=∣Diag(ru)∣⋅∣S∣⋅∣Diag(ru)∣=i∈Ru∏ru,i2⋅∣S∣
取其对数,则可以表示为:
l o g d e t ( L ) = ∑ i ∈ R u l o g ( r u , i 2 ) l o g d e t ( S ) ) logdet(L)=\sum\limits_{i \in R_u}log(r_{u,i}^2)logdet(S)) logdet(L)=i∈Ru∑log(ru,i2)logdet(S))
其中, d e t ( ⋅ ) det(\cdot) det(⋅)表示矩阵的行列式。上式中的 ∑ i ∈ R u l o g ( r u , i 2 ) \sum\limits_{i\in R_u}log(r_{u,i}^2) i∈Ru∑log(ru,i2)可以表示为用户和商品的相关性, d e t ( S ) det(S) det(S)可以表示商品之间的多样性,这里简单解释一下为什么可以表示多样性。
假设$ S= \begin {bmatrix}S_{ii} +S_{ij} S_{ij}++S_{jj}\end{bmatrix} , 则 ,则 ,则 det\left(S \right)=S_{ii}S_{jj}-S_{ij}{2}=1-S_{ij}{2}$,则 d e t ( S ) det \left (S\right) det(S) 越大,对应的 S_{ij}^{2})$越小,也即多样性越好。
因此最大化 d e t ( L ) det\left(L\right) det(L)可以优化推荐集的多样性。假设系统筛选出的推荐给用户的商品子集为 C u ⊆ R u C_{u}\subseteq R_{u} Cu⊆Ru, L C u L_{C_u} LCu 表示被商品子集 C u C_u Cu 索引的核矩阵的子矩阵,则商品子集 C u C_u Cu 的相关性和多样性可以用下式度量:
l o g d e t ( L C u ) = ∑ i + ∈ + C u l o g ( r u , i 2 ) − l o g d e t ( S C u ) logdet(L_{C_u})=\sum\limits_{i+\in+C_u}log(r_{u,i}^2)-logdet(S_{C_u}) logdet(LCu)=i+∈+Cu∑log(ru,i2)−logdet(SCu)
多样性问题便可以转化为前面的MAP问题。
四、行列式点过程的MAP求解
行列式点过程的MAP求解是一个复杂的过程,Hulu的论文中提出了一种改进的贪心算法能够快速求解,该算法的时间复杂度为 O ( N 2 M ) O(N^2M) O(N2M), N N N为返回的商品列表中商品的个数。
这一求解过程简单来说就是每次从候选集中贪心地选择一个能使边际收益最大的商品加入到最终的结果子集中,直到满足停止条件为止,即每次选择商品 j j j 添加到结果集中 Y g Y_g Yg中, Y g Y_g Yg初始化为空集,商品 j j j需要满足下面的等式:
j = a r g m a x i ∈ Z \ Y g log d e t ( Y g ∪ { i } ) − l o g d e t ( Y g ) (1) j= \underset{i \in Z \backslash Y_g}{argmax} \log det(Y_g \cup \lbrace i \rbrace)- log det(Y_g) \tag{1} j=i∈Z\Ygargmaxlogdet(Yg∪{i})−logdet(Yg)(1)
其中行列式 d e t ( L Y g ) det(L_{Y_g}) det(LYg) 直接求解复杂度较高,需要有巧妙的方法简化计算过程。假设 d e t ( L Y g ) > 0 det(L_{Y_g})>0 det(LYg)>0, L Y g L_{Y_g} LYgCholesky 分解如下:
L Y g = V V ⊤ L_{Y_g}=VV^{\top} LYg=VV⊤
其中 V) 是一个可逆下三角矩阵。对于任意 i ∈ Z \ Y g i \in Z \backslash Y_g i∈Z\Yg , L Y g ∪ { i } L_{Y_g \cup \lbrace i \rbrace} LYg∪{i}的Cholesky 分解可以定为:
其中,等式右边右上角的子矩阵为0向量,是因为 V) 是一个下三角矩阵。根据矩阵乘法公式,行向量
c
i
c_i
ci 和标量
d
i
≥
0
d_i≥0
di≥0 满足:
V
c
i
⊤
=
L
Y
g
(3)
V{c_i^{\top}}= L_{Y_{g}}\tag{3}
Vci⊤=LYg(3)
d
i
2
=
L
i
i
−
∥
c
i
∥
2
2
(4)
d_i^2 =L_{ii}-\|c_i\|_2^2\tag{4}
di2=Lii−∥ci∥22(4)
另外,根据等式(2), 可以得到:
d
e
t
(
L
Y
g
∪
{
i
}
)
=
d
e
t
(
V
V
⊤
)
⋅
d
i
2
d
e
t
(
L
Y
g
)
⋅
d
i
2
(5)
det(L_{Y_g \cup \lbrace i \rbrace})=det(VV^{\top}) \cdot d_i^2 det(L_{Y_g}) \cdot d_i^2\tag{5}
det(LYg∪{i})=det(VV⊤)⋅di2det(LYg)⋅di2(5)
因此,等式(1)可以简化为:
j = a r g m a x i ∈ Z \ Y g log ( d i 2 ) (6) j = \underset{i \in Z \backslash Y_g}{argmax} \log(d_i^2) \tag{6} j=i∈Z\Ygargmaxlog(di2)(6)
一旦等式(6)被求解,根据等式(2),
L
Y
g
∪
{
i
}
L_{Y_g \cup \lbrace i \rbrace}
LYg∪{i} 的Cholesky 分解变成是:
L
Y
g
∪
{
j
}
=
[
V
0
c
j
d
j
]
[
V
0
c
j
d
j
]
⊤
(7)
L_{Y_{g} \cup\{j\}}=\left[\begin{array}{cc} V & 0 \\ c_{j} & d_{j} \end{array}\right]\left[\begin{array}{cc} V & 0 \\ c_{j} & d_{j} \end{array}\right]^{\top} \tag{7}
LYg∪{j}=[Vcj0dj][Vcj0dj]⊤(7)
其中, c j c_j cj 和 d j d_j dj是已经计算出来了的。当一个新item被添加到 Y g Y_g Yg 之后, L Y g L_{Y_g} LYg 的Cholesky因子可以被有效更新。
对于每个item i i i , c i c_i ci 和 d i d_i di 可以被增量更新。在等式(6)被求解后,将 c i ′ c_i' ci′和 d i ′ d_i' di′ 定义为新的需求求解的向量和标量,其中 i ∈ Z \ ( Y g ∪ { j } ) i \in Z \backslash (Y_g \cup \lbrace j \rbrace) i∈Z\(Yg∪{j}) 。
根据等式(3)和等式(7),我们有:
[
V
0
c
i
d
i
]
c
i
T
=
L
Y
g
∪
{
j
}
,
i
=
[
L
Y
g
,
i
L
j
i
]
(8)
\left[\begin{array}{cc} V & 0 \\ c_{i} & d_{i} \end{array}\right] c_{i}^{T}=L_{Y_{g} \cup\{j\}, i}=\left[\begin{array}{c} L_{Y_{g, i}} \\ L_{j i} \end{array}\right] \tag{8}
[Vci0di]ciT=LYg∪{j},i=[LYg,iLji](8)
通过将等式(3)和等式(8)组合,我们可以对 c i c_i ci 和 d i 2 d^2_i di2进行更新,有:
c i ′ = [ c i ( L j i − ⟨ c j , c i ⟩ ) / d j ] ≐ [ c i e i ] c_{i}^{\prime}=\left[\begin{array}{lll} c_{i} & \left.\left(L_{j i}-\left\langle c_{j}, c_{i}\right\rangle\right) / d_{j}\right] & \doteq\left[c_{i}\right. & e_{i} \end{array}\right] ci′=[ci(Lji−⟨cj,ci⟩)/dj]≐[ciei]
等式(4)意味着:
d i ′ 2 = L i i − ∥ c i ′ ∥ 2 2 = L i i ∥ c i ∥ 2 2 − e i 2 = d i 2 − e i 2 (9) d_i'^2=L_{ii}-\|c_i'\|_2^2=L{ii}\|c_i\|_2^2-e_i^2=d_i^2-e_i^2 \tag{9} di′2=Lii−∥ci′∥22=Lii∥ci∥22−ei2=di2−ei2(9)
最初,
Y
g
=
∅
Y_g=\emptyset
Yg=∅ , 等式(5)意味着:
d
i
2
=
d
e
t
(
L
i
i
)
=
L
i
i
d_i^2=det(L_{ii})=L_{ii}
di2=det(Lii)=Lii。
完整算法描述如下: