转载来源:https://zhuanlan.zhihu.com/p/144911605
背景
搜索和推荐经常会被放在一起对比,其中最突出的区别就是搜索中存在 query,需要充分考虑召回内容和 query 之间的相关性,而如果内容是搜索广告,则对内容有更高的要求,相关性过低的内容被展示会让用户有很差的体验。
相关性在一定程度上可以被抽象成 doc 和 query 之间的语义相似度问题,其实当前语义相似度的研究已经非常成熟,在 sigir2018 中有人曾经对搜索和推荐中的深度学习匹配进行了非常全面的综述:Deep Learning for Matching in Search and Recommendation。在语义匹配上,大家的关注点经常在于如何去定义 “匹配” 上,尤其是分析如何将两者的编码内容更好地匹配起来。
常见的其实就是两个思路:
- 前者是重表示学习,也就是我们常说的 “endocer”,然后通过简单的方法计算他们的相似度(如余弦相似度)。最具有代表性的应该是 DSSM 等双塔模型了。
- 后者则重相似度计算,encode 之后,通过句子之间的交互关系计算相似度,达成目标。常用的交互计算就是两个句子 token 间相互 attention 的过程,当然也有一些两者一起进入 encoder 共同计算的方法,比如 BERT 中的 Text_a+Text_b 的训练方式,就是同时进行句内和句间的表示计算。
虽然语义相似度问题已经有很多解决办法了,然而事实上,在应用过程中,相关性和相似度还是有着很大的差距,因为搜索内容的细微变化会带来较大的语义意图变化。比如用户想买 “手机充电器”,但结果出了 “手机壳”。虽然两者有一定的相似度,但明显是不相关的。
回过头来谈搜索广告,搜索广告是搜索中商(zhuan)业(qian)化的一环,希望的是能给到用户尽可能接触的东西尽可能相关,本来广告点的人就少,还无关就更凉凉了。
不慌,今天就介绍一个最新方法,来自亚马逊 ACL20 的《Learning Robust Models for e-Commerce Product Search》,文章主要用在商品搜索的场景下,目的是判断 query 和 item/doc 之间的相关性。文中提出了一个与 “对抗生成网络” 类似结构的模型,其中的判别器能够衡量 query 和 doc 之间的相关性,判断两者是否相关,生成器则能够生成与 query 相似却不相关的 doc,借助类似对抗生成网络模式的训练,能够在较多噪音数据下,仍尽可能保证模型的鲁棒性。
模型
问题定义
为了更好的对模型进行描述,对问题进行定义,对一个匹配对 ( I , Q ) (I,Q) (I,Q),其中文档内容 I I I 和对应的 query Q , y ( I , Q ) Q,y(I,Q) Q,y(I,Q) 表示两者的匹配情况, y = 1 y=1 y=1 表示两者不匹配而 y = 0 y=0 y=0 表示两者匹配,而在建模过程中,会产生一个 Q g e n Q_{gen} Qgen,当 y ( I , Q ) = 0 y(I,Q)=0 y(I,Q)=0时会有 y ( I , Q g e n ) y(I,Q_{gen}) y(I,Qgen) 。
模型架构
想要学东西,看论文肯定不能错过模型部分了。
模型主要分为 3 大部分:
- LSTM-attention 为基础的分类模型(蓝色虚线框)
- 变分编码 - 解码生成器(a variational encoder-decoder query generator,VED)(红色虚线框)
- 状态融合器(橙色实心矩形)
分类器
上面提到,分类器是一个 LSTM-attention 模式的模型。它的模式是基于 (Rocktaschel et al., 2015) 产生的,作者认为搜索场景的语句格式和常规的自然语言会存在差异。首先 query 和对应的物品 title,在语法结构上会存在不同,query 一般较短,而 title 的描述则更多的是关键词的堆砌。广告场景下的 query 和 title,更可能是一个多对一的情况,比如“红色跑鞋 耐克” 和 “红色 耐克运动鞋” 都对应着同一个商品;另外,query 中存在的对属性的描述,如品牌颜色等(电商场景),这些属性会在长句中出现,因此需要具有一定记忆性的模型。综上,作者对 query 和物品的标题 title 分别进行了不同的词向量训练,最终合并然后计算。
底层的输入本就有两块,一块是 titie,另一块是 query,两者分别通过自己训练的 word2vector 进行编码,然后如图所示地进入各自的 LSTM,其中还能看到的是 query 的 LSTM 其实还用了 title LSTM 的末端信息信息,随后,进入了一个 additive attention,其实是一种比较常规的 attention 方法 (Bahdanau et al., 2014),此后,就进入三层全连接,最终完成了匹配度的计算。
值得注意的是里面 attention 的使用,作者虽然使用的是 additive attention,但是还提出了一个改进,这个改进把 attention 本来不包含上下文信息的模式升级为考虑了上一期信息的模式,来看看他具体是怎么做的:
设
k
k
k 为 LSTM 的输出维数,
K
=
[
k
1
,
k
2
,
.
,
,
,
,
k
m
]
K=\left[k_{1}, k_{2}, .,,,, k_{m}\right]
K=[k1,k2,.,,,,km]和
H
=
[
h
1
,
h
2
,
…
,
h
n
]
H=\left[h_{1}, h_{2}, \ldots, h_{n}\right]
H=[h1,h2,…,hn] 是 title 和 query 分别经过各自 LSTM 的输出矩阵。
M
t
=
tanh
(
[
K
T
,
h
t
T
,
r
t
−
1
T
]
W
h
)
,
W
h
∈
R
3
k
×
k
,
t
=
1
,
2
,
3
,
…
n
α
t
=
tanh
(
M
t
ω
)
,
ω
∈
R
k
r
t
=
K
T
α
t
+
tah
n
(
W
r
r
t
−
1
)
\begin{array}{c} M_{t}=\tanh \left(\left[K^{T}, h_{t}^{T}, r_{t-1}^{T}\right] W_{h}\right), W_{h} \in R^{3 k \times k}, t=1,2,3, \ldots n \\ \alpha_{t}=\tanh \left(M_{t} \omega\right), \omega \in R^{k} \\ r_{t}=K^{T} \alpha_{t}+\operatorname{tah} n\left(W_{r} r_{t-1}\right) \end{array}
Mt=tanh([KT,htT,rt−1T]Wh),Wh∈R3k×k,t=1,2,3,…nαt=tanh(Mtω),ω∈Rkrt=KTαt+tahn(Wrrt−1)
要理解 attention,首先要弄明白的是 attention 的对象和依据,显然,构造 r t r_t rt 的时候,我们针对的是 query 中 LSTM 输出后每一个节点进行计算的,因此公式表示的意思是,对于 query 中的每个词 h t h_t ht,分别对 title 的表示 K K K 进行 attention 并得到分数 r t r_t rt,另外计算时引入了 r t − 1 r_{t-1} rt−1,目的是加入 t-1 步之前模型主要 focus 的信息。
当然了,attention 只是一种对信息的调整,最终还要考虑原来的信息,汇总出去,于是有: h = tanh ( W x [ r n T , q n T , ∣ r n − q n ∣ T ] ) h=\tanh \left(W_{x}\left[r_{n}^{T}, q_{n}^{T},\left|r_{n}-q_{n}\right|^{T}\right]\right) h=tanh(Wx[rnT,qnT,∣rn−qn∣T]) 其中 q n q_{n} qn是 query 经过 LSTM 后的最终输出。得到的 h h h 就是 query 这一次送入全连接层之前的形态。
细心的我们可以发现,除了我们计算得到的 r r r 和 q q q,还多考虑了 ∣ r n − q n ∣ T \left|r_{n}-q_{n}\right|^{T} ∣rn−qn∣T ,作者给出的解释是提升分类的效果,具体的体现就在于前面所提到的 query 和 item 之间的 “多对一” 的关系,attention 中考虑了 query 中每个位置和 title 整体的关系后计算得到 r r r,而这个 r r r 通过参数的训练,其实能够表示一整批与 title 相关的 query,具有统一的表达能力,此时 ∣ r n − q n ∣ T |r_n-q_n|^T ∣rn−qn∣T 则能够体现这个所谓 “统一的表达” 与特定 query 之间的差距。
最后,当然就是损失函数了:
L
θ
(
X
,
y
)
=
1
N
∑
i
=
1
N
L
θ
(
x
i
,
y
i
)
=
1
N
∑
i
β
y
i
log
(
f
θ
(
x
i
)
)
+
(
1
−
y
i
)
log
(
1
−
f
θ
(
x
i
)
)
\begin{aligned} L_{\theta}(X, y) &=\frac{1}{N} \sum_{i=1}^{N} L_{\theta}\left(x_{i}, y_{i}\right) \\ &=\frac{1}{N} \sum_{i} \beta y_{i} \log \left(f_{\theta}\left(x_{i}\right)\right)+\left(1-y_{i}\right) \log \left(1-f_{\theta}\left(x_{i}\right)\right) \end{aligned}
Lθ(X,y)=N1i=1∑NLθ(xi,yi)=N1i∑βyilog(fθ(xi))+(1−yi)log(1−fθ(xi))
其中
β
\beta
β是一个调整正样本权重的超参数,在本文中会更看重正样本(不匹配的),因此有
β
>
1
\beta >1
β>1。
文本生成器
搜索引擎下正样本(不匹配)很简单,但是要找到与对应 title 不匹配,但是和对应 query 比较相似的文本,也就是我们所说的 “对抗样本”,真的不容易,我们希望的是找到对抗样本协助训练,从而提升模型的鲁棒性。
文章里作者使用的是 VED——变分编码解码器,我们希望的是,输入 ( I , Q ) (I,Q) (I,Q),能够生成一个 Q g e n Q_{gen} Qgen ,这个与 I I I 不匹配,但是与 Q Q Q 非常接近(其实某种程度上可以理解为我们要去挖掘相似度分类的 “决策边界”)。作者本身对 VED 没有很多的改进,而是直接沿用(Bahuleyan et al., 2017) 的操作,具体的格式就变得很简单:
生成器和 query 的联动
由于内部其实涉及了两个任务:分类和生成,要使这两者总体端到端化,有必要涉及一个统一的损失函数,权衡两者使两者尽可能同时达到最优。
回过头来重新看看整个模型架构,尤其是橙色部分:
s
H
g
e
n
+
(
1
−
s
)
H
,
s
=
(
1
−
y
)
z
s H_{g e n}+(1-s) H, s=(1-y) z
sHgen+(1−s)H,s=(1−y)z
这里的 H H H 和 H g e n H_{gen} Hgen 分别是 query 和生成的 query 分别通过 query LSTM 后产生的结果, z z z 是一个满足概率为 p p p的伯努利分布。
展开来看看这个公式其中的原理,首先,如果 query 本身就和 title 不相似,也就是 y = 1 y=1 y=1 ,则整个公式下其实就只使用了原始 query,相反,如果 y = 0 y=0 y=0,则完全使用生成的 query。而为了产生一定的噪音,引入了一个随机数 z z z 。
损失函数设计与训练
双重任务——分类和生成,那就要谨慎考虑两者的联合学习了,为此作者设计出了这么一个公式:
1
N
∑
i
=
1
N
(
1
−
s
i
)
L
θ
(
x
i
,
y
i
)
+
s
i
L
θ
(
g
ψ
(
x
i
)
,
z
i
)
\frac{1}{N} \sum_{i=1}^{N}\left(1-s_{i}\right) L_{\theta}\left(x_{i}, y_{i}\right)+s_{i} L_{\theta}\left(g_{\psi}\left(x_{i}\right), z_{i}\right)
N1i=1∑N(1−si)Lθ(xi,yi)+siLθ(gψ(xi),zi)
仔细看看这个公式是不是和上面公式 (3) 有些类似?说白了,只有当 query 和 titile 非常相似的时候(负例),才会更多的考虑生成器生成的 query 与 title 之间的相关性。但是其实我们可以发现,上面这个损失函数,无论是看 query 还是生成的 query,都只是在分析他们与 doc 的不相似性,换言之都是再考虑“正样本”,而没有负样本,实际上他们是怎么做的呢?来看看他们的训练流程。
在训练过程中,首先要做的是对分类器进行第一轮训练,然后用分类器划分出相似和不相似的 query,然后用这块数据训练出第一版本的 VED,在此基础上,再用公式 (4) 作为损失去做调整,最终得到需要的模型,尤其是这个分类模型。
实验与效果
有了基本的模型以及一定的理论基础,当然就要开始实操这块的内容了。作者是针对电商搜索来进行的设计,当然就要用电商的数据进行实验,实验数据量将达到了 320 万对,其中只有少量是不匹配的,这里面的 “匹配” 是指 query 查询后频繁购买的那些商品的 title。
模型效果
以 gbdt 为基线(说实话这里其实并不太同意用 gbdt 来做基线,我的视角看语义相似度他并非主流,dssm 才是比较出名的基线),可以看到还是有比较明显的提升,从这里看,作者的模型效果甚至要高于著名的 bert,哪怕是只有分类器,在加上生成器进行协助训练后,效果得到了进一步的提升。
不仅离线评估效果喜人,QUARTS 在线上也获得了很好的表现,经过在两个国家的 A/B 测试后,相比当前的基线分别提升了 12.2% 和 5.75%。
生成器效果
生成器的效果,根据作者分析现实准确率能达到 82%,算是一个不错的水平吧,来看一些 case:
可以看到,如作者预期,query 和生成的 query 具有较高的相似性的同时,也能够满足与对应 title 之间的关系。
结论与展望
读完这篇文章后,我们需要做的,当然就是吸收这篇文章提到和提出的一些建模的 trick:
- 在进行语义相似度时,query 和 title 的 embedding 可以通过设置两个来表达不同的语义句式。
- attention 中引入上一期的信息。
- 在进行语义相似度时,attention 对 query 进行处理,可以加入 title 的所有信息辅助生成。
- (核心)变分编码产生正样本对原模型进行微调。
这里面让我感到比较惊喜的是,bert 被干趴下了,而且输得挺多的,不过这主要是因为 BERT 是在 DSSM 基础上进行的改进,其实可以尝试把本文模型下训练的 title embedding 和 query embedding 都换成 bert,估计会有新的提升(但模型估计会蹭蹭蹭的变大)。那么我下面给一些可以尽可能提升的思路吧(快记着,下一篇顶会就是你的了)
另外,我还想提的一个点是,在 bert 被干趴下的同时,这个模型除了 LSTM 之外本身没有复杂度很高的操作,耗时预计就在 10ms 左右。
- 中文是否有这个效果?
- 搜索的 query 大都是短句,现在看来效果还是不错的,但是从上面生成器的效果来看,还是出现一些语义类似但是文本匹配低的情况,是否可以加入文本匹配的信息协助保证文本层面的匹配度(如 BM25)。
- 相似度的衡量目前比较粗暴,直接用的全连接,是否有必要升级为余弦、矩阵相似度?
- 尝试训练一个 title embedding 和 query embedding 都换成 bert 的模型,然后用本文的模型来做蒸馏,估计还会有提升。