众所周知,BM25算法是Elasticsearch全文检索引擎默认相似度算法,但此种算法仅考虑了文本Term之间的匹配关系,并未考虑文本语义之间的信息,所以导致很多场景下,语义相关的内容无法召回。随着深度学习在NLP的广泛应用,在IR和QA(问答系统)中出现了很多深度模型将query和doc通过神经网络embedding,映射到一个稠密空间的向量表示,然后再计算其是否相关,并取得很好的效果,而本文就来介绍一种基于语义检索的召回模型LSTM-DSSM。
【DSSM】
DSSM是Deep Structured Semantic Model的缩写,基于深度网络的语义模型,由微软研究院在2013年发表,其其核心思想是基于搜索引擎的曝光点击行为数据,利用多层DNN网络把query及文档Doc Embeding成同一纬度的语义空间中,通过最大化约束query和doc两个语义向量的余弦举例,从而训练学习得到隐层相似度语义模型,从而实现了检索召回。
下图是DSSM模型的网络结构图
DSSM 从下往上可以分为三层结构:输入层、表示层、匹配层。
输入层:将所有query以及候选集doc映射到统一空间并作为输入,放进DNN中进行训练,但在DSSM中,中英文的处理方式有所不同。英文一般直接使用word hashing,3个字母为一组,#表示开始和结束符。为啥使用3个字母?3个字母的表达往往能代表英文中的前缀和后缀,并且实验证明,3个字母的单词冲突仅为22个,比2个字母的单词冲突数减小近100倍。而中文依赖于分词,中文分词本身就比较难,中文语义性太强,同样的词语在不同的句子中表达的意思完全不同,中文词语有近百万个,在网络中维度太高不利于训练,所以DSSM中文输入层可以模拟英文处理,使用单字分词,字向量(one-hot)作为输入,向量空间约为 1.5 万维。
表示层:采用 BOW(Bag of words)的方式,相当于不考虑文本的字符顺序和上下关系,将整个句子里的词都放在一个袋子里了。一个含有多个隐层的 DNN,用 Wi 表示第 i 层的权值矩阵,bi 表示第 i 层的 bias 项。则第一隐层向量 l1(300 维),第 i 个隐层向量 li(300 维),输出向量 y(128 维)可以分别表示为:
用 tanh 作为隐层和输出层的激活函数:
最终输出一个 128 维的低纬语义向量。
匹配层:在召回匹配过程,我们使用 [公式] 来表示一个query, [公式] 来表示一个doc,那么他们的相关性分数可以用下面的公式衡量:
其中, yQ 与 yD 分别代表query和doc的语义向量。在搜索引擎中,给定一个query,会返回一些按照相关性分数排序的文档。
DSSM模型对于短文本搜索召回有很好的召回效果,但对于长文本以及在电商搜索中很多query词都带有型号的情况下,效果会比较差,比如输入“显卡RTX3090”,如果对输入按字处理,则会强制模型学习3、0、9、0四个数字是一种固定搭配,甚至有些电子产品的型号词数字加字母长达十几位,而真正的核心中文词也许只有短短几位,这就产生了非常严重的干扰效果。不仅如此,DSSM因为其特征提取方式会导致其丢失了文本的字符顺序和上下文信息,所以有很多进化模型,比如LSTM-DSSM。
【LSTM-DSSM】
此模型通过采用LSTM进行编码的方式,同样将文本编码为一段向量,LSTM需要对文本长度进行预先的处理,对于query的长尾词处理非常的友好。
模型图如下:
【Bert训练Embedding】
这里基于迁移学习的思想,不是简单的随机初始化词token的Embedding向量,而是以亿级别的搜索query和docment的title为语料,先使用HanLP分词器进行分词处理,将分词所得的词token按顺序编码,生成后续模型需要的词典,基于Bert预训练模型进行训练,这样就能得到每个词token的语义向量,并当作为模型的输入。
【LSTM语义向量】
先进行分词得到句子的词token-X(i),基于训练好的Bert模型映射到一个word representation,就是embedding,也就是上图中的l(i)。然后把整个句子送入LSTM,训练LSTM,拿出最后输出的状态y(m),即可得到LSTM潜层语义向量。
【模型输出】
LSTM-DSSM里其实就是将DSSM的全连接改成LSTM,此处案例基于海量的搜索点击数据,分别计算搜索的query的LSTM语义向量和点击以及未点击的document的LSTM语义向量,基于LSTM训练的语义向量进行相似度度量,后续的操作与DSSM模型一致。
当然不同的场景可能使用到不同模型的变种,在电商领域,document除开标题以外,可能还会有其他很重要的信息,例如品牌和类目。此时可以将品牌、类目通过Embedding表示学习层、两层MLP直接映射成和LSTM提取的语义向量同一维度的向量,再将两者相加得到最终的语义向量表示,使用最终的语义向量表示输入到DSSM模型中进行召回。结构如下图:
根据不同场景不同需求来调整你的模型,相信可以得到更好的效果。https://mp.weixin.qq.com/s/0Mt9gKeNwizD516FmYNpdw