1. 概述
前面已经介绍了多个搜索召回中的向量召回算法,如Facebook的EBR,Que2Search,京东的DPSR。对于搜索系统来说,召回通常是由倒排召回构成,倒排召回的简单原理如下图所示:
对于Document,首先对其关键词的提取,并将其索引化,在索引中,其key是核心词,value对应了item的列表,这便是倒排索引的来源,这部分是可以离线完成的。对于在线的检索部分,首先会通过分词将用户的Query进行分词,得到Query的核心词后在倒排索引中查找到相关的item。倒排召回的原理相对比较简单,同时因为是基于词的匹配,相对而言相关性上能够得到保证。但是基于倒排索引的召回形式也存在着一些问题:
- 语义鸿沟(Semantic Gap)的问题。如item的核心词是“长裙”,那么对于“长裙”的Query,通过核心词便不能对其找回,当然这部分问题可以通过query改写或者query扩展的方式进行解决;
- 个性化的召回。基于词匹配的方式无法加入个性化的特征,因此在召回匹配的过程中无法进行个性化的操作。
- 多模态特征的融合。这一点与个性化类似。
前面介绍到的基于向量召回的召回算法能够很好的解决上述提到的问题。淘宝在2021年也提出了对应的向量召回算法MGDSPR(Multi-Grained Deep Semantic Product Retrieval)[1]。在MGDSPR中着重要解决的问题是如何优化相关性的问题,这一点在其他的文章中很少提及,但是搜索中的相关性问题对于向量召回来说是避不开的一个问题,而且是一个较难解决的一个问题。
2. MGDSPR的算法原理
2.1. MGDSPR的模型结构
MGDSPR的模型结构如下图所示:
相比较于EBR,Que2Search以及DPSR,MGDSPR的结构是相当复杂。分开来讲,模型的特征主要是三个方面,Query侧(1-gram,2-gram,q_seg和q_his),用户行为序列(实时行为序列,短期行为序列,长期行为序列),item侧(item ID和title)。
2.2. 特征的处理
2.2.1. Query侧
Query侧的模型结构详细如下图所示:
特征方面主要是四个,分别为1-gram,2-gram,q_seg和q_his。这样设计的目的是希望对于Query能够尽可能的挖掘多粒度的特征,这也就对应了MGDSPR中的Multi-Grained。那么这几个部分都是如何实现的呢?当一个用户发起一次query请求时,如“红色连衣裙”,其对应的分词结果为qu={w1u,⋯,wnu},如上述的query分词结果为“{红色,连衣裙}”。而每一个词又是由单个字组成wu={c1u,⋯,cmu},如词“红色”是由“{红,色}”组成。历史query是由多个query组成qhis={q1u,⋯,qku}∈Rk×d。通过组合可以得到6个维度的query侧的特征Qmgs。
第一个是q1_gram,也就是单字维度的特征,其取的是所有字的embedding的均值q1_gram=mean_pooling(c1,⋯,cm),其中cm∈R1×d,则q1_gram∈R1×d。
第二个是q2_gram,也就是2个字维度的特征,与单字维度的特征类似,其值为q2_gram=mean_pooling(c1c2,⋯,cm−1cm),且q2_gram∈R1×d。
第三个是qseg,也就是词维度的特征,与单字维度的特征类似,其值为qseg=mean_pooling(w1,⋯,wn),其中wn∈R1×d,则qseg∈R1×d。
第四个是qseg_seq,也就是将词粒度的又当成序列作为特征。这里使用了基于Transformer的方法来处理序列数据,最终取均值qseg_seq=mean_pooling(Trim(w1,⋯,wn)),且qseg_seq∈R1×d。
第五个是qhis_seq,也就是历史query的序列,这里直接与qseg做attention操作qhis_seq=softmax(qseg⋅(qhis)T)qhis,且qhis_seq∈R1×d。
第六个是qmix,也就是混合上述的五个特征,在MGDSPR直接将其相加qmix=q1_gram+q2_gram+qseg+qseg_seq+qhis_seq,且qmix∈R1×d。
最后将上述六个粒度的特征垂直concat在一起,便得到了Qmgs:
Qmgs=concat(q1_gram,q2_gram,qseg,qseg_seq,qhis_seq,qmix)
且qmgs∈R6×d。
2.2.2. 用户行为序列
对用户行为序列的挖掘就成为个性化的核心,通过用户历史行为,挖掘出用户的兴趣。行为序列部分的模型结构详细如下:
对于用户行为序列的挖掘,包括三个部分,分别为实时用户行为序列,短期用户行为序列,长期用户行为序列。
对于实时用户行为序列Ru={i1u,⋯,itu,⋯,iTu},使用LSTM对其进行处理,得到隐含层的结果Rlstmu={h1u,⋯,htu,⋯,hTu},再经过Multi-head Self Attention得到Rself_attu={h1u,⋯,htu,⋯,hTu},在Rself_attu的第一个位置上加入全0的向量,得到Rzero_attu={0,h1u,⋯,htu,⋯,hTu}∈R(T+1)×d,最后与qmgs进行Dot-Product Attention的计算,且qmgs作为Q,Rzero_attu作为K和V,得到实时个性化表示Hreal∈R6×d,其数学表达式为:
Hreal=softmax(Qmsg⋅Rzero_attT)⋅Rzero_attT
对于短期用户行为序列Su={i1u,⋯,itu,⋯,iTu},通过Multi-head Self Attention得到Sself_attu={h1u,⋯,htu,⋯,hTu},在Sself_attu的第一个位置上加入全0的向量,得到Szero_attu={0,h1u,⋯,htu,⋯,hTu}∈R(T+1)×d,最后与qmgs进行Dot-Product Attention的计算,且qmgs作为Q,Szero_attu作为K和V,得到短期个性化表示Hshort∈R6×d,其数学表达式为:
Hshort=softmax(Qmsg⋅Szero_attT)⋅Szero_attT
对于长期用户行为序列的挖掘与上述的不一样,在长期用户行为序列的描述中包含四个方面的属性,分别为item维度Litemu,shop维度Lshopu,叶子类目维度Lleafu和品牌维度Lbrandu。而对于每一个维度,又分为三个方面的行为序列,以item维度为例,又分为点击Lclick_item,购买Lbuy_item和收藏Lcollect_item。这里直接对向量进行mean-pooling对其压缩合并成一个向量(文章中给出的原因是考虑到速度),最终得到item维度的结果Litemu={0,hclick,hbuy,hcollect},最后与qmgs进行Dot-Product Attention的计算,且qmgs作为Q,Litemu作为K和V,得到实时个性化表示Ha_item∈R6×d,其数学表达式为:
Ha_item=softmax(Qmsg⋅LitemT)⋅LitemT
其他两个维度类似,得到Ha_shop∈R6×d,Ha_leaf∈R6×d和Ha_brand∈R6×d,最终得到长期用户行为的挖掘结果,其数学表达式为:
Hlong=Ha_item+Ha_shop+Ha_leaf+Ha_brand
在上述的Rzero_attu,Szero_attu和Litemu中都添加了0,简单来说就是为了在计算attention的时候用于处理与Qmsg不相关的情况,相关性为0。
2.2.3. Query和User塔的输出
通过上面的计算,得到了query的各粒度表示qmgs∈R6×d,实时个性化表示Hreal∈R6×d,短期个性化表示Hshort∈R6×d以及长期个性化表示Hlong∈R6×d,其中,qmgs为多粒度的语义表示,{Hreal,Hshort,Hlong}为用户个性化表示,将[CLS]
和qmgs,H_{real},H_{short}和H_{long}合并作为Multi-head Self Attention的输入(类似于Bert中的输入),最终取[CLS]
作为Query和User塔的输出Hqu∈R1×d,其数学表达式为:
Hqu=Self_Attfirst([[CLS],Qmsg,Hreal,Hshort,Hlong])
2.4. Item塔
相对而言,Item塔就简单了很多,特征主要包含两个方面,分别为ID类和title,ID类直接通过Embedding转换成向量ei∈R1×d,标题的分词结果Ti={w1i,⋯,wNi},最终通过下面的数学表达式得到item的向量表示:
Hitem=e+tanh(Wt⋅N∑i=1Nwi)
其中,Wt为转换矩阵。
这里直接对分词后的词向量取均值,而没有使用序列的方式学习,文中给出的解释是关键词缺乏语法结构,但是在qseg_seq中却对分词结果使用了Transformer,这一点是存在矛盾的。
2.3. 损失函数
在MGDSPR中的损失函数使用的是交叉熵损失,没有选择Hinge Loss。文中指出Hinge Loss会导致训练和推断不一致,Hinge Loss只具备局部的比较能力。其中Hinge Loss的数学表达式为:
L=i=1∑Nmax(0,D(q(i),d+(i))−D(q(i),d−(i))+m)
对于局部比较能力,我的理解是在损失函数中,比较的是D(q(i),d+(i))和D(q(i),d−(i)),因此是一个局部的比较。同时Hinge Loss受到超参数m的影响较大。
而Cross-entropy Loss的数学表达式为:
L=−i∈I∑yilog(∑i′∈Iexp(F(qu,i′))exp(F(qu,i+)))
其中,F表示的是内积,I表示的是全量商品,i+表示的是item塔的输出Hitem,qu表示的是Query和User塔的输出Hqu。为了能便于计算,在softmax计算中,使用sampled softmax,同时对于每个batch都是用同样的负样本。
2.4. 样本选择
2.4.1. 平滑噪音数据
我们在选择正样本的过程中通常会选择点击样本作为正样本,但是这个是存在噪音的,因为用户的点击与很多因素有关,不仅仅是query和item之间的相关性,还可能与价格等其他因素有关。为了缓解这部分噪音导致的模型问题,在softmax中加入温度单数τ,那么对应的softmax的计算如下:
y^(i+∣qu)=∑i′∈Iexp(F(qu,i′)/τ)exp(F(qu,i+)/τ)
这一点在前面的文章中也已经分析过,τ的作用就是能够平滑softmax的结果。
2.4.2. 负样本
对于双塔的向量召回,负样本的选择一般包含随机负样本和困难负样本,在随机负样本部分,MGDSPR是通过从商品库I中随机选择,而对于困难样本的挖掘,就相对而言要复杂一点,假设qu,i+和i−分别表示的是query,正样本,负样本的表示。我们按照内积的大小对负样本排序,选择top-N个负样本作为困难负样本Ihard∈RN×d,然后混合i+∈11×d和Ihard,通过采样得到Imix∈RN×d,Imix的数学表达式为:
Imix=αi++(1−α)Ihard
其中,α∈RN×1,且是通过从均匀分布中采样得到,最终softmax表达式为:
y^(i+∣qu)=∑i′∈I∪Imixexp(F(qu,i′)/τ)exp(F(qu,i+)/τ)
将正样本也有一定的概率被选择为负样本,不是很清楚为什么对于结果是正向的作用。
3. 相关性控制模块
在搜索系统的向量召回中,存在很大的相关性的问题,尽管在模型上已经对query进行多粒度的建模,但是对于电商系统来说,还存在着品牌,型号,类目,颜色等更细粒度的相关性,为了能对系统具有更好的相关性控制能力,在向量召回的后面加入了相关性控制模块,具体如下图所示:
简单来说,相关性控制模块就是一个布尔匹配(boolean matching),结合ANN,最终的表达式为:(ANN results) and (Brand: Adidas) and (Category: shoes)。单独的相关性控制模块具有很好的相关性控制能力,方便对系统的维护。
4. 总结
阿里的模型相对而言是相当复杂的,里面涉及到了大量的attention的计算,这会给在线任务带来巨大的压力。从原理上来说,低一点是对Query进行多粒度的分析,试图能够挖掘多粒度的语义信息。第二点是用户行为的挖掘,相当的复杂了。第三点是对相关性的控制,设立了独立的模块用于控制相关性。其他的如样本的选择,softmax中的温度参数等都差不太多。除了上述的重点分析意外,还有几点更多的思考:
- query侧进行了多粒度的语义分析,但item侧相对就简单了很多,这个对相关性的建模是不太友好的;
- 在MGDSPR中,个性化占据了很大的计算量,但是个性化是建立在召回充足的情况下的,这部分在我们的实际使用中是可以选择性使用的。
参考文献
[1] Li S, Lv F, Jin T, et al. Embedding-based product retrieval in taobao search[C]//Proceedings of the 27th ACM SIGKDD Conference on Knowledge Discovery & Data Mining. 2021: 3181-3189.