文本相似度

传统方法

  • 基于TF-IDF、BM25、Jaccord、SimHash、LDA等算法抽取两个文本的词汇、主题等层面的特征,然后使用机器学习模型(LR, xgboost)训练分类模型
  • 优点:可解释性较好
  • 缺点:依赖人工寻找特征,泛化能力一般,而且由于特征数量的限制,模型的效果比较一般

代表模型:

  • BM25

BM25算法,通过候选句子的字段对qurey字段的覆盖程度来计算两者间的匹配得分,得分越高的候选项与query的匹配度更好,主要解决词汇层面的相似度问题。BM25也是Elasticsearch使用的检索算法。

深度方法:基于表征的匹配

  • 基于表征的匹配方式,初始阶段对两个文本各自单独处理,通过深层的神经网络进行编码(encode),得到文本的表征(embedding),再对两个表征进行相似度计算的函数得到两个文本的相似度

  • 优点:基于BERT的模型通过有监督的Fine-tune在文本表征和文本匹配任务取得了不错的性能

  • 缺点:BERT自身导出的句向量(不经过Fine-tune,对所有词向量求平均)质量较低,甚至比不上Glove的结果,因而难以反映出两个句子的语义相似度

    主要原因是:

    1.BERT对所有的句子都倾向于编码到一个较小的空间区域内,这使得大多数的句子对都具有较高的相似度分数,即使是那些语义上完全无关的句子对。

    2.BERT句向量表示的聚集现象和句子中的高频词有关。具体来说,当通过平均词向量的方式计算句向量时,那些高频词的词向量将会主导句向量,使之难以体现其原本的语义。当计算句向量时去除若干高频词时,聚集现象可以在一定程度上得到缓解,但表征能力会下降。

代表模型:

  • DSSM(2013)
  • CDSSM(2014)
  • ARC I(2014)
  • Siamese Network(2016)
  • InferSent(2017)
  • BERT(2018)
  • Sentence-BERT(2019)
  • BERT-flow(2020)
  • SimCSE(2021)
  • ConSERT(2021)
  • CoSENT(2022)

由于2018年BERT模型在NLP界带来了翻天覆地的变化,此处不讨论和比较2018年之前的模型(如果有兴趣了解的同学,可以参考中科院开源的MatchZoo 和MatchZoo-py)。

所以,本项目主要调研以下比原生BERT更优、适合文本匹配的向量表示模型:Sentence-BERT(2019)、BERT-flow(2020)、SimCSE(2021)、CoSENT(2022)。

该类模型适合召回

深度方法:基于交互的匹配

  • 基于交互的匹配方式,则认为在最后阶段才计算文本的相似度会过于依赖文本表征的质量,同时也会丢失基础的文本特征(比如词法、句法等),所以提出尽可能早的对文本特征进行交互,捕获更基础的特征,最后在高层基于这些基础匹配特征计算匹配分数
  • 优点:基于交互的匹配模型端到端处理,效果好
  • 缺点:这类模型(Cross-Encoder)的输入要求是两个句子,输出的是句子对的相似度值,模型不会产生句子向量表示(sentence embedding),我们也无法把单个句子输入给模型。因此,对于需要文本向量表示的任务来说,这类模型并不实用

代表模型:

  • ARC II(2014)
  • MV-LSTM(2015)
  • MatchPyramid(2016)
  • DRMM(2016)
  • Conv-KNRM(2018)
  • RE2(2019)
  • Keyword-BERT(2020)

Cross-Encoder适用于向量检索精排

DSSM

文本相似度_第1张图片

先来看其结构,DSSM分成了三个部分,embedding层对应图中的Term Vector,Word Hashing,特征提取层对应图中的,Multi-layer,Semantic feature,Cosine similarity,还有输出层Softmax,我们针对这三部分分别讲解。
embedding层
这里我把图中的Term Vector和Word Hashing都归在了embedding层,Term Vector是文本转向量后的值,论文中作者采用的是bag-of-words即词袋模型,我的代码中会采用one-hot的形式。然后是Word Hashing层,英文主流文本转vector的方式更多是采用embedding,但是该方法有一个致命的问题就是会出现OOV的问题,而作者提出了一种word hasing的方法,该方法一方面能降低输入数据的维度,其次也能保证不出现OOV的问题,接下来我们详细看下其原理。

word hashing
这里以good这个单词为例,分为三个步骤

  • 在good两端添加临界符#good#
  • 采用n-gram的方式分成多个部分,如果是trigrams那么结果是[#go, goo, ood, od#]
  • 最终good将会用[#go, goo, ood, od#]的向量来表示

在英文中,因为只有26个字母,加上临界符是27个符号,3个字母的组合是有限的,即 A 27 3 = 17550 A_{27}^3=17550 A273=17550 种可能,因此也就不会出现OOV的问题。

对于discriminative,discriminate,discrimination 三个单词的意思很像,他们的Word Hashing中也有大部分是相同的。这样两个不同的单词也有可能具有相同的tri-grams,针对这个问题论文中做了统计,这个冲突的概率非常的低,500K个word可以降到30k维,冲突的概率为0.0044%。

可见该方法对于英文来说是有效可行的,但是并不适合中文,在我的代码中,会采用字向量的形式,词典包含了大部分的中文,能有效降低oov的可能性。

特征提取层
接下来的结构就很简单了,三个全连接层,激活函数采用的是tanh,把维度降低到128,然后把两个序列的Semantic feature进行了余弦相似度计算

输出层

输出层也很简单,一个softmax,因为是计算相似度所以可以看成是二分类,细节不再赘述。

ARC I

针对上述讲到的DSSM模型对query和doc序列和上下文信息捕捉能力的不足,华为诺亚方舟在2015年在DSSM的模型基础上加入了CNN模块,里面提到了两种模型ARC-I和ARC-II,前者是基于representation learning的模型,后者是基于match function learning的模型将在第三章讲到。两个模型对比原始的DSSM模型,最大的特点是引入了卷积和池化层来捕捉句子中的词序信息,ARC-I全称Architecture-I,框架如图

文本相似度_第2张图片

ARC-I模型引入了类似CNN模块的卷积层和池化层,整体框架如图

文本相似度_第3张图片

总结下ARC-I的特点:

  • 对于query和doc两段文本的匹配,相比DSSM引入了word-ngram网络
  • 通过卷积层不同的feature map来得到相邻term之间的多种组合关系
  • 通过池化层max pooling来提取这些组合关系中最重要的部分,进而得到query和doc各自的表示。
  • 表示层:通过上述卷积层和池化层来强化相邻word的关系,因此得到的query和doc的表示比原始DSSM能捕捉到词序信息
  • 缺点:卷积层虽然提取到了word-ngram的信息,但是池化层依然是在局部窗口进行pooling,因此一定程度上无法得到全局的信息

Sentence-BERT(SBert)

文本相似度_第4张图片
SBert沿用了孪生网络的结构,文本Encoder部分用同一个Bert来处理。之后,作者分别实验了CLS-token和2种池化策略(Avg-Pooling、Mean-Pooling),对Bert输出的字向量进一步特征提取、压缩,得到u、v。

SBert直接用Bert的原始权重初始化,在具体数据集上微调,训练过程和传统Siamse Network差异不大。

但是这种训练方式能让Bert更好的捕捉句子之间的关系,生成更优质的句向量。在测试阶段,SBert直接使用余弦相似度来衡量两个句向量之间的相似度,极大提升了推理速度。

作者还做了一些有趣的消融实验。使用NLI和STS为代表的匹配数据集,在分类目标函数训练时,作者测试了不同的整合策略,结果显示**“(u, v, |u-v|)”**的组合效果最好。这里面最重要的部分是元素差:(|u - v|)。句向量之间的差异度量了两个句子嵌入维度间的距离,确保相似的pair更近,不同的pair更远。

CoSENT

具体内容在最后一个参考文献

参考

https://pypi.org/project/text2vec/

基于表征(Representation)的文本匹配、信息检索、向量召回的方法总结

https://blog.csdn.net/u012526436/article/details/90212287

https://cloud.tencent.com/developer/news/601293

https://kexue.fm/search/cosent/

你可能感兴趣的:(NLP,人工智能,深度学习)