二、attention 机制的用户序列建模
2. Deep Interest Evolution Network
2.1 简介
在这篇文章发布之前的CTR预估或者推荐排序算法中,都将做用户的行为序列表征进行池化或者attention机制加权平均作为用户兴趣的表征,直接使用用户的行为序列信息作为用户兴趣,没有考虑用户的潜在兴趣的特征。此外,这种办法的用户特征表征,也没有考虑用户的兴趣是处于一个u 段发展的状态,而不是固定一成不变的。
这篇文章的作者,与其他的工作直接采用用户的行为序列作为兴趣表征不同,作者建立了interest extract layer来抽取每个时间步的用户兴趣表征。然后,作者通过明确建立interest envolving layer的方式来建模用户兴趣随时间/行为发展这一趋势。
2.2 模型架构
注意图中比如特殊的几个关键部分:
- 用户兴趣提取层:Interest Extractor layer
- 用户兴趣发展建模层: Interest Evolving Layer
- 在兴趣提取层生效的辅助任务目标(Auxiliary Loss)
- 以及Interest Evolving Layer的核心部件AuGru,即融合了注意力机制的Gru。
2.2.1 用户兴趣提取层:Interest Extractor layer
作者认为,确实也是,用户的行为序列(其实用书点击过item,搜过的词,或者其他的行为的embedding向量)包含了用户的兴趣,可以从中提取出用户的兴趣表征,以前的研究都是直接用这个行为序列来表征用户的兴趣,未免过于粗糙,简单来说就是表征能力不够。
因此,作者提出了Interest Extractor layer来提取用户的特征。
本质上来讲,Interest Extractor layer就是一个GRU网络,作者认为自己选它的原因是它克服了rnn的梯度弥散,且比lstm快。
另外,如果仅仅使用这么一个GRU来提取兴趣,且反馈信号只来自于最后回传的梯度,显然不够:因为GRU学到的不过是用户行为序列的先后依赖,并不能非常有效的表达兴趣(我个人的理解,用GRU进行提取特征和attention并无甚区别,不对,还是有一点儿,不然transformer就不需要在搞个position embedding 了)。
所以作者又搞了辅助loss来直接帮助用户兴趣提取层来更好建模用户兴趣。具体的方式是,用下一时间步的用户行为
B
t
+
1
B_{t+1}
Bt+1来指导Gru中
h
t
h_t
ht(有木有很像一个AR自回归的语言模型?),然后这个
B
t
+
1
B_{t+1}
Bt+1有可能是用户真实的点击行为(正样本),也有可能是从
t
+
1
t+1
t+1时刻给用户曝光而没有点击的负样本中选择。作者,认为这样可以更好让Interest Extractor layer学习到如何建模用户兴趣,我的理解是,该辅助任务的目标就是预测用户的可能点击(兴趣),那么它所依据的
h
t
h_t
ht自然应当更应当是贴近用户兴趣。据此,该层便具备了从用户前面数个行为提取用户的能力。
L
a
u
x
=
−
1
N
(
∑
i
=
1
N
∑
t
I
(
t
=
1
)
σ
(
h
t
,
e
b
i
[
t
+
1
]
)
+
I
(
t
=
1
)
(
1
−
σ
(
h
t
,
e
b
i
[
t
+
1
]
)
)
)
L_aux = - \frac{1}{N}(\sum_{i=1}^{N}\sum_t I(t=1)\sigma(h_t,e_b^i[t+1])+I(t=1)(1 - \sigma(h_t,e_b^i[t+1]) ))
Laux=−N1(i=1∑Nt∑I(t=1)σ(ht,ebi[t+1])+I(t=1)(1−σ(ht,ebi[t+1])))
瞅瞅,其实就是看看下一个item会不会被预测对而已。
2.2.2 用户兴趣演进层:Interest Evolving Layer
在上一层(Interest Extractor layer)里作者利用Gru和辅助loss在考虑用户序列行为的前提下提取用户每个时间步的兴趣表征,但是,作者认为直接用这个兴趣表征是不够,原因有2:
- 第一,作者认为用户兴趣这种东西是随着时间变化(drift)的。举个例子,在我们滑购物app的时候,一会儿我们想看书籍,一会儿我们想看菜谱,一会儿我们想看衣服。因此有必要对这个用户兴趣的发展进行建模来获取具备更多历史相关信息的精确的用户当前时刻兴趣。
- 第二, 在进行ctr预估或者item评分的时候,我们希望仅仅看相目标条目的兴趣信息。因此,虽然不同类型(衣物、食材)的兴趣有其自己发展trend,我们仍然需要某种机制来提取其中与目标item相关的机制。
之后呢,作者就结合了注意力机制(可以看看DIN来看为什么)和GRU来建模用户兴趣的发展过程,为什么要用attetion而不是只用GRU(额,因为作者DIN中尝试了lstm建模,但没啥用么),我认为是因为希望仅仅发现与target条目相关的兴趣,并对它进行序列建模。
为此,作者提出了attention与GRU结合的三种模式:
- AIGRU(GRU with attention input)
i t ‘ = h t I n t e r e s t E v o l v i n g L a y e r ∗ a t i_t^`=h_t^{Interest Evolving Layer} * a_t it‘=htInterestEvolvingLayer∗at
a t a_t at是注意力权重。作者通过对进入gru(interest evolving network的)的输入执行注意力机制来使得模型不要关注不相关的东西。但效果不是很好,这里很关键的问题在于,对于一个不相关的interest的表征,作者希望它不要改变兴趣的演进建模,但是AIGRU的方式,最多只能作到给不相关的兴趣0输入,这仍然会改变gru的内部状态,0输入也是输入么。 - AGRU (attention-based GRU)
QA领域在2016年就提出了AGRU,具体是这样子的:
在GRU里有更新门一说,它控制了GRU当前时间步输出的信息里,前面的信息和当前信息的比例。具体GRU公式如下:
更新门计算: u t = σ ( W u i t + U u h t + b u ) u_t = \sigma(W^ui_t +U^uh_t+b^u) ut=σ(Wuit+Uuht+bu)
重置门计算: r t = σ ( W r i t + U r h t + b r ) r_t = \sigma(W^ri_t +U^rh_t+b^r) rt=σ(Writ+Urht+br)
历史信息计算: h ~ = t a n h ( W h i t + r t ⋅ h t + b r ) \widetilde{h} = tanh(W^hi_t +r_t · h_t+b^r) h =tanh(Whit+rt⋅ht+br)
输出计算: h t = ( 1 − u t ) h t − 1 + u t h ~ h_t = (1-u_t)h_{t-1} + u_t\widetilde{h} ht=(1−ut)ht−1+uth
在AGRU 中,直接使用 a t a_t at代替更新门的计算 u t u_t ut:
h t = ( 1 − a t ) h t − 1 + a t h ~ h_t = (1-a_t)h_{t-1} + a_t\widetilde{h} ht=(1−at)ht−1+ath
显然,在其他地方work的套路就是比刚想出来的奇技淫巧(AIGRU)要好一些。 - AUGRU(GRU with attentional update gate),这个玩意儿就是在AGRU 改过来的,就是说AGRU虽然克服AIGRU的问题,同时也完成了注意不同兴趣的目标,但是直接抛弃了原始更新门使得网络出现了一点点问题,因为
a
t
a_t
at这个东西是表征不同兴趣(说人话就是序列不同元素)的权重,那用这么个标量就放弃了同一个元素的不同的特征的区别这有问题,所以,应该把原先的更新门融合进来,至于方法门,标量和向量还有啥好说的,直接乘啊:
a t ‘ = u t ∗ a t a_t^` = u_t * a_t at‘=ut∗at
h t = ( 1 − a t ‘ ) h t − 1 + a t ‘ h ~ h_t = (1-a_t^`)h_{t-1} + a_t^`\widetilde{h} ht=(1−at‘)ht−1+at‘h
好了,就这些了。