今天的博客主要参考了2019年AAAI的论文《Session-based Recommendation with Graph Neural Networks》和2020年SIGIR的论文《Global Context Enhanced Graph Neural Networks for Session-based Recommendation》。
主要讲解了如何利用当下最火的GNN模型辅助Session-based 下的行为序列建模。所谓Session-based 场景下的推荐模型建模,其实就是利用用户在 t − 1 t-1 t−1时间范围内的行为点击item序列,来预测在t时刻的点击商品。其实问题本身还是比较清楚的。常规的做法也很简单,因为问题本质上就是行为序列建模问题,就想NLP对句子处理一样,利用LSTM、GRU这些类RNN序列模型是非常合适的。
但是,作者分析直接这样使用,可能会有一些问题:主要是类RNN主要建模的重点是在相邻的item之间的变化,又因为基于RNN的模型天然会把注意力更多的放在序列的后半部分,使得前半部分的序列变化规律提取变的较为困难;同时在序列中,前后相距较远的item context之间的关系也是难以提取。比方说对于序列: A C B A . . . . . A A C B A ..... A ACBA.....A,假设序列中间没有出现过C,则在最后一个A点击之后,在序列前半部分出现的 A C AC AC这样成对的序列关系就会被RNN模型轻易忽视。也就是说,对于一个点击session内的item之间关系的刻画,使用从前到后的“线性扫描”是会损失较多信息的。如何对这些同一个session内的item关系进行更好的建模和表征,这两篇paper都用到了图结构的表征方法。
下面首先讲解的论文是《Session-based Recommendation with Graph Neural Networks》。话不多说首先上整个模型的架构图:
从左到右可以看到,首先利用一个session内的数据item点击行为序列
v
1
,
v
2
,
.
.
.
v
n
v_1,v_2,...v_n
v1,v2,...vn构建session级别的有向graph网络(具体graph是否有向,根据具体的问题来定,并不是说一定要构造有向的网络)。具体的构建方法也是非常直观,网络中的节点就是item,网络中的边就是item之间的访问关系,即有用户的访问序列
v
1
,
v
3
,
v
7
,
v
1
v_1,v_3,v_7,v_1
v1,v3,v7,v1,那么将
i
t
e
m
1
−
>
i
t
e
m
3
,
i
t
e
m
3
−
>
i
t
e
m
7
,
i
t
e
m
7
−
>
i
t
e
m
1
item_1->item_3,item_3->item_7,item_7->item_1
item1−>item3,item3−>item7,item7−>item1的边权加1。将网络使用临接矩阵A表示,则有如下图所示的形式:
从表中我们可以看到,针对从某个点作为出边或者入边的边权重都使用了归一化的处理方法。假设
v
i
t
v_i^{t}
vit代表了节点
i
i
i在
t
t
t时刻的向量表征,A代表了session级graph的临接矩阵,作者借鉴了GRU模型中门结构的设计思路,提出了以下的变换公式:
a
i
t
=
A
i
T
[
v
1
t
−
1
,
.
.
.
,
v
n
t
−
1
]
T
+
b
a_i^t=A_i^T[v_1^{t-1},...,v_n^{t-1}]^T+b
ait=AiT[v1t−1,...,vnt−1]T+b
z
i
t
=
σ
(
W
z
.
a
i
t
+
U
z
v
i
t
−
1
)
z_i^t=\sigma(W_z.a_i^t+U_zv_i^{t-1})
zit=σ(Wz.ait+Uzvit−1)
r
i
t
=
σ
(
W
r
.
a
i
t
+
U
r
v
i
t
−
1
)
r_i^t=\sigma(W_r.a_i^t+U_r v_i^{t-1})
rit=σ(Wr.ait+Urvit−1)
c
i
t
=
t
a
n
h
(
W
o
a
i
t
+
U
o
(
r
i
t
⨀
v
i
t
−
1
)
)
c_i^t=tanh(W_oa_i^t+U_o(r_i^t \bigodot v_i^{t-1}))
cit=tanh(Woait+Uo(rit⨀vit−1))
v
i
t
=
(
1
−
z
i
t
)
⨀
v
i
t
−
1
+
z
i
t
⨀
c
i
t
v_i^t=(1-z_i^t)\bigodot v_i^{t-1}+z_i^t\bigodot c_i^t
vit=(1−zit)⨀vit−1+zit⨀cit
按照公式的计算,就能从graph session中节点在t-1时刻的表征得到其在t时刻的表征。
在得到了一个session各个节点的最新表征之后,由于最终的目的是要预测用户在基于当前的session点击行为之后最可能点击的商品,接下来就要对整个session序列进行编码了。在这个部分作者就提出了long-term interest 和 current session interest这两个概念,假设用户的点击序列在进行了基于graph session网络的GNN操作之后得到的embedding序列为 [ v 1 , v 2 , v 3 , . . . v n ] [v_1,v_2,v_3,...v_n] [v1,v2,v3,...vn]。
那么作者简单的将current session interest定义为点击序列的最后一个元素即
s
l
o
c
a
l
=
v
n
s_{local}=v_n
slocal=vn;
对于long-term interest部分的提取,即借鉴了attention思想,使用
v
n
v_n
vn作为key和序列中每一个元素计算相关联程度,最终的加权求和即是long-term interest的表征。公式如下:
α
i
=
q
T
σ
(
W
1
s
l
o
c
a
l
+
W
2
v
i
+
c
)
\alpha_i=q^T\sigma(W_1s_{local}+W_2v_i+c)
αi=qTσ(W1slocal+W2vi+c)
s
g
l
o
b
a
l
=
∑
i
=
1
m
α
i
v
i
s_{global}=\sum_{i=1}^m \alpha_iv_i
sglobal=∑i=1mαivi
最终
s
t
o
t
a
l
=
W
[
v
l
o
c
a
l
;
v
g
l
o
b
a
l
]
s_{total}=W[v_{local};v_{global}]
stotal=W[vlocal;vglobal]。
由于该问题本质还是召回问题,在得到了序列的表征向量
s
t
o
t
a
l
s_{total}
stotal之后,将其和候选集的商品
v
i
v_i
vi构建损失函数,即
L
o
s
s
=
y
i
∗
−
l
o
g
(
s
o
f
t
m
a
x
(
s
t
o
t
a
l
∗
v
i
)
)
)
Loss=y_i*-log (softmax(s_{total}*v_i)))
Loss=yi∗−log(softmax(stotal∗vi)))。
第二篇要讲解的paper《Global Context Enhanced Graph Neural Networks for Session-based Recommendation》其实是上一篇工作的进一步扩展。虽然上一篇paper利用了session内的商品点击序列构建了graph,但是其构建graph所依赖的数据仅仅依靠了当前要预测session内的商品数据,即偏local的信息。而全局的考虑了所有session 内商品点击行为的global context却没有使用,而这部分全局的global信息对目标session信息的提取和预测都是有较大好处的。
整个模型结构图如下图所示:
从整体流程来看,输入目标session之后,分别从当前分析的session中构建graph以及从global context中构建graph,得到序列中每个节点在两个视角下的不同表征,再将其进行融合。
Global graph
在构建global graph的时候,先定义一个
μ
\mu
μ,对于同一个序列,任意两个结点想构造连边时,这两个结点之间的单位距离必须小于
μ
\mu
μ。构造得到的图是带权无向图。连边权重使用共现的次数来表示。对每个结点,只保留Top-N权重的边。和Top-N机制的目的都是为了减小复杂度,如果序列所有结点之间做全连接,那么构造得到的图的边规模会非常庞大。提取全局图上的物品表征的主要好处是能够借鉴其它session中和目标session相关的有用信息。因此,这里头的关键点是,如何衡量全局图上的信息是否和目标session序列相关,是否对目标结点的表征有作用。
为了实现这一点,作者提出了一种session-aware的注意力机制,计算global-graph上和
v
i
v_i
vi相邻的结点
v
j
v_j
vj的贡献值
π
(
v
i
,
v
j
)
\pi(v_i,v_j)
π(vi,vj)。其中
π
(
v
i
,
v
j
)
\pi(v_i,v_j)
π(vi,vj)的计算公式如下所示:
π
(
v
i
,
v
j
)
=
s
o
f
t
m
a
x
(
q
T
L
e
a
k
y
R
e
l
u
(
W
[
s
⨀
h
v
j
;
w
i
j
]
)
)
\pi(v_i,v_j)=softmax(q^TLeakyRelu(W[s\bigodot h_{v_j};w_{ij}]))
π(vi,vj)=softmax(qTLeakyRelu(W[s⨀hvj;wij]))
其中,s是目标序列的表征,是目标序列中所有结点的mean pooling结果,即
s
=
1
∣
s
∣
∑
v
i
∈
S
h
v
i
s=\frac{1}{|s|}\sum_{v_i \in S}h_{v_i}
s=∣s∣1∑vi∈Shvi。
h
v
i
h_{v_i}
hvi是结点的表征;
w
i
j
w_{ij}
wij是结点和在global graph上的连边权重。这个公式的好处是把目标序列S,邻居结点
v
j
v_j
vj以及目标结点
v
i
v_i
vi和
v
j
v_j
vj的亲和度
w
i
j
w_{ij}
wij都考虑进去了,求出来的注意力值能够衡量global-graph上的邻居结点
v
j
v_j
vj和目标session序列是否相关,对目标结点的表征是否有用。softmax在的所有邻居结点上求一个概率分布。这个注意力机制是此部分的主要亮点,剩余的步骤就是常规的加权邻域汇聚结点并叠加多层来提取global-graph上多阶的结点关系。
h
N
v
i
g
=
∑
v
j
∈
h
N
v
i
g
π
(
v
i
,
v
j
)
h
v
h_{N_{v_i}}^g=\sum_{v_j \in h_{N_{v_i}}^g}\pi(v_i,v_j)h_{v}
hNvig=∑vj∈hNvigπ(vi,vj)hv
最后通过信息汇聚和自身的信息融合起来,得到目标节点
v
i
v_i
vi在global context视角下的表征形式
h
v
i
g
=
R
e
l
u
(
W
[
h
i
;
N
v
i
g
]
)
h_{v_i}^g=Relu(W[h_i;_{N_{v_i}}^g])
hvig=Relu(W[hi;Nvig])
current session Graph
current session level的物品表征就是从session-graph中和目标结点相邻的邻域结点中提出信息。这里头的主要亮点就是注意力机制的设计,在计算序列中结点之间的attention值时,attention的设计考虑了结点之间的4种连边类型(即:出度,入度,自连接,双向),即:edge-type specific attention机制。
α
i
j
=
s
o
f
t
m
a
x
(
L
e
a
k
y
R
e
l
u
(
α
r
i
j
T
(
h
v
i
⨀
h
v
j
)
)
)
\alpha_{ij}=softmax(LeakyRelu(\alpha_{r_{ij}}^T(h_{v_i}\bigodot h_{v_j})))
αij=softmax(LeakyRelu(αrijT(hvi⨀hvj)))
r
i
j
r_{ij}
rij是序列中的两个结点
v
i
v_i
vi和
v
j
v_j
vj连边类型,
α
i
j
\alpha_{ij}
αij是该连边类型特定的参数向量。根据该注意力值加权汇聚邻域结点。由于有自连接边,所以加权汇聚的过程中实际上相当于同时做了信息传播和信息汇聚。
h
v
i
c
u
r
r
e
n
t
=
∑
v
j
∈
N
v
i
c
u
r
r
e
n
t
α
i
j
h
v
j
h_{v_i}^{current}=\sum_{v_j \in N_{v_i}^{current}}\alpha_{ij}h_{v_j}
hvicurrent=∑vj∈Nvicurrentαijhvj
最终,每个结点的表征是global-level的表征和current session-level的表征sum pooling的结果,即图中加号的部分。具体而言,作者对global-level的表征加了一层dropout来防止过拟合。即:
h
v
i
f
i
n
a
l
=
d
r
o
p
o
u
t
(
h
v
i
g
)
+
h
v
i
c
u
r
r
e
n
t
h_{v_i}^{final}=dropout(h_{v_i}^g)+h_{v_i}^{current}
hvifinal=dropout(hvig)+hvicurrent
得到了序列中每个结点的表征后,需要对序列中的每个结点表征进行汇聚,从而形成序列表征。以下几个点是需要重点关注的:
1 位置ID的embedding编码。首先在序列结点
v
i
v_i
vi的表征
h
v
i
f
i
n
a
l
h_{v_i}^{final}
hvifinal中融入了位置信息。位置编码包括顺序编码和逆序编码,二者存在差异的原因主要在于,不同序列的长度是不一样的。因此肯定会设置一个最大编码长度参数,大于这个最大编码长度的就是取默认编码值。此时,顺序编码会导致部分长序列末尾的位置编码都是默认值,逆序编码会导致部分长序列头部的位置编码都是默认的。作者特意强调了逆序编码更有用,这其实是非常符合直觉的。
z
i
=
t
a
n
h
(
W
[
h
v
i
f
i
n
a
l
;
p
l
−
i
+
1
]
+
b
)
z_i=tanh(W[h_{v_i}^{final};p_{l-i+1}]+b)
zi=tanh(W[hvifinal;pl−i+1]+b)
其中
p
l
−
i
+
1
p_{l-i+1}
pl−i+1代表了位置的embedding表征,
l
l
l代表了最大编码长度。
2 然后对序列中的结点表征作mean pooling得到session information,可以认为是这个session序列浓缩后的信息。 s s u m m a r y = 1 l ∑ i = 1 l h v i f i n a l s_{summary}=\frac{1}{l}\sum_{i=1}^l h_{v_i}^{final} ssummary=l1∑i=1lhvifinal
这个session information作为序列attention的trigger去和序列中的每个结点做soft attention,得到表示每个结点对序列表征的贡献度值。作者称这种注意力机制为position-aware attention(
z
i
z_i
zi中融入了位置信息,这个和上一篇paper的工作是比较大的差异点,上一篇paper中用的last item作为trigger去做attention)。根据该值加权每个结点的表征,最终得到序列的表征。
β
i
=
q
T
σ
(
W
1
z
i
+
W
2
s
s
u
m
m
a
r
y
+
b
)
\beta_i=q^T\sigma(W_1z_i+W_2s_{summary}+b)
βi=qTσ(W1zi+W2ssummary+b)
S
=
∑
i
=
1
l
β
i
h
v
i
f
i
n
a
l
S=\sum_{i=1}^l \beta_i h_{v_i}^{final}
S=∑i=1lβihvifinal
最后当得到了整个用户点击序列的表征之后,和上一篇paper一样,通过和其他商品内积的softmax方式构造损失函数,完成最终模型的训练过程。
这两篇paper都可以看做是知识图谱在推荐领域的相关应用。确实,最近知识图谱这个概念炒的比较火,接下来的一段时间,我会不断跟进这个方向,期望能看到更多在工业界落地应用的成果案例。