原创:语义相似度(理论篇)

如果本文观点有不对的地方,欢迎指正! author:佟学强 

  nlp中语义理解一直是业内的难题。汉语不同于英语,同样一个意思,可以有很多种说法,比如你是谁的问题,就可以有如下几种:①你是谁?②你叫什么名字?③您贵姓?④介绍一下你自己 等等。这些句子在语义上是十分接近的,如果做一个智能音响,对音响说出上述任何一句,其结果不应该因为句子形式的不同而不同,也就是说训练出的模型不能对同义语句太敏感。在神经概率语言模型,也就是深度学习引入到nlp中之后,word2vector,lstm,cnn开始逐步占据主导。在最开始的由word2vector表达词向量,扩展到目前的用LSTM表达句子的向量,还有RCNN应用于NLP可以抽取出一个句子的高阶特征,这几年热度一直居高不下。

  然而联结主义只是解决了人的感知能力,还不具备逻辑推理。深度学习目前在语义表示上最大的问题是太机械化了,自适应能力太差,相比之下的统计概率语言模型可以平滑,灵活度高一些。比如用w2v训练出的词语义表示就很机械化,对于汉语中的一词多义现象,他无法做到上下文重叠。lstm用最后的压缩向量来表示一个句子的语义也很机械化,不能照顾到上下文的语境问题,同一句话在不同的语境或者上下文中其语义或者语义贡献度是不同的,所以语义表示也应该不同。甚至同一句话用不同的语气说,语义也是不同的,机器如何感知?如何让现有的模型训练出的语义更加灵活是一个重要的研究课题。

  word2vector的语言模型有CBOW和skip_gram,核心思想是:相同语境出现的词语义相近。这个思想在nlp语义上占据重要位置。用word2vector训练出的词表达具备语义关联,同时兼顾了上下文。w2v可以解决词级别的语义相似度问题。

  在word2vector产生后,情感分析便由word2vector和svm主导,先获取到用户评价句子的每个词的表示,对每个词打分,然后加权求和得出一句话的得分,来判断这句话是好评,中评还是差评。很显然,这种方法只是从词这个局部单元考虑出发,并没有考虑到整句话所表达的意思,很容易陷入局部最优解。lstm产生后,便摒弃了这个方案,先由lstm训练出这句话的向量,然后进入到回归层进行打分。这样就能从整句话出发来判断用户的评价了。

  尽管如此,研究人员并没有停止语义分析研究的步伐。如何做句子级别的语义相似度?在nlp中,文章摘要或者信息抽取一直是没有突破的课题,深度学习引入之后,便有了一些改进。文章摘要,不管采用什么样的手段,都离不开三个核心问题:①句子相似度的计算②文摘句抽取③文摘句排序。运用siamese lstm,训练的时候,输出为两个句子向量的一阶范数的指数函数,代表两个句子的差异程度,让这个值与真实的打分值的损失函数最小。这样训练得出的两个句子的向量与普通的标准的LSTM训练出来的向量是有区别的。标准的lstm单独训练出来的每个句子向量只能代表一个句子,句子之间是独立的。这个方案可以解决句子的语义相似度。

  如何获取整篇文章的语义表示?可以把每个句子的向量累加成文章向量,然后用元智或者元积衡量每个句子和文章向量的差异,选出k个相似度最高的句子作为文章摘要句。关于如何获取整篇文章的语意表达,这里有一个比较low的方案,呵呵:

   feature1:一篇文章包括A,B,C三段,每段有a,b,c……句子,先用siamese lstm获取到每个句子的语义表示,然后把每个句子作为基本输入单元,输入到siamese lstm中,再把每段作为基本单输入到siamese lstm。这里的每个siamese lstm是不一样的,需要单独训练好,比如第二个可以衡量段落之间的语义相似性。

  这个方案很明显是不切实际的,只是粗糙地累加而且训练时间复杂度太高,运行效率明显存在问题,训练的模型太多。有没有更好的方案呢?本人认为,一个比较好的方案是可以抽取出文章的中心句作为整篇文章的语义表示。而这个中心句的语义表示很显然与他的上下文存在着密切的语义关联,训练过程中必须照顾到这一点。我们可以先谈一下人脑对于一篇文章的语义理解。给你一篇文章,从第一句话顺序阅读,直到文章结束,我们会抽取出其中的中心句或者总结出中心思想来代表这个文章。从第一句话开始,我们的大脑就开始猜测他是不是中心句,然后看下面的内容是否围绕着它来展开论述的,如果不是,继续猜测后面的句子,执行相同的逻辑推理,主要看上下文与这个句子的语义关联程度。而在阅读的过程中,大脑的高级中枢会指挥注意力分配机制,具体来说,上下文的每句话中的每个词对中心句的语义贡献度是不同的,这些词随着时间的推移,有些给我们留下了深刻的印象,有些则遗忘了。这种注意力分配会导致新的句子的形成,而到达下一个句子时,前面新形成的句子同样存在着这样的现象。

  其实上面描述的过程明显涉及到了attention model,而且是两个级别的attention:词级别的和句子级别的。词级别的attention负责把上下文中的每个句子的词重新组合成一个新的句子,句子级别的attention在此基础上把这些新形成的句子再次重新组合成一个新的句子,这就是最终的上下文。如果这个最终的上下文语义表示和我们猜测的中心句语义相似度很高,那么他就是中心句,如果不是,前向搜索继续执行这个逻辑。这个方案是本人首次提出的siamese lstm + attention moel组合而成的,用以模拟人脑在抽取文章中心句的过程。具体训练的语料格式可以如下:【文章,中心句,1.0】后面是相似度得分,用目前计算语义相似度最好的模型siamese lstm。(2017年有学者提出了非监督学习的SIF,但是本人认为应用场景很受限,仅供借鉴)上下文的每个句子的词序列输入到siamese lstm中的第一个lstm中,中心句输入到另一个lstm中,然后用中心句的语义表示对齐第一lstm中的每个词语义表示,累加成新的句子语义存储起来,而后做句子级别的attention对齐,使用中心句的语义表示对存储的所有上下文新句子的语义表示进行对齐操作,然后求加权平均值得到最后的上下文语义表示,最后输出打分值:exp(-||x1 - x2||1),然后用MSE作为损失函数开始训练。

  预测的时候,模拟人脑抽取中心句的过程,从第一句开始,时间序列t0,后面的语句全是下文,用训练好的模型得到最终的语义,然后运行exp(-||x1 - x2||)节点,然后把第一句的编号和相似度得分封装成一个对象,存储在一个数组里面,增加时间序列到t1,计算他的上下文语义,把第二句话编号和相似度得分存储在数组里,以此类推。最后用本人设计的优先级队列(优于jdk底层的优先级队列,要求兼顾时间空间最优)推荐出top K,K一般非常小,比如2,3。

  计算句子语义相似度在nlp中不仅限于文章摘要。他可以增强nlp的语义理解能力,在机器翻译中也有重要的应用甚至在nlp的挑战性的场景,比如给你一段话,要求不改变文章思想的情况下把这段话拆分成两段,也就是文章断句分段。这个问题的解决方案可能复杂一些,siamese lstm只是一个基础性的支撑。解决语义问题,首先要解决的是获取语义的表示,通常情况下用dense向量来表达。但是标准的lstm最大的意义是提供了基础学术研究,因为他获取到的语义表达是独立的,不具备语义关联,重要的事情重复三遍,不具备语义关联,不具备语义关联,不具备语义关联!!考察语义相似度,要考虑单个句子或者整篇文档的上下文。

  目前,计算语义关联,或者计算语义相似度,2014~2016年间,有众多学者探索了以下方案:①convnet,cnn引入到nlp中②skip_thought,改进型的w2v③tree_lstm。基于ma结构的siamese lstm已经超越了当下的state of the art,效果已经击败了上述三个方案。他的最大亮点是exp(-||x1 - x2||1),为什么不用L2范数衡量获取到的句子向量的差异,一方面用w2v训练出的词,存在大量的欧氏距离相同的情况,如果用L2范数衡量,效果很不稳定,存在语义丢失现象,而cos相似度适用于向量维度特别大的场景。用ma距离来衡量是最恰当的。另一方面,BPTT说起,用L2范数会存在梯度消失的问题。因为最终获取的向量实际上是两个句子向量的差值,可以看成是一个向量,上述的函数可以看作是激活函数,进行梯度训练时,由于L2函数的特性,只能衡量较短句子的差异,也就是说,当句子很长时,本来语义相似度很低,他却衡量不出来,认为是相似度很高。这一点也体现了标准的LSTM的能力是有限的,超过30步数记忆能力直线下降,一个长句子通过模型训练得到的final_state.h,占据比重最大的是后面的词语,前面的基本消失,因此需要attention model。

  再强调一下,衡量特征向量差异的指标通常有欧式距离,曼哈顿距离和余弦相似度。如果一对儿向量在空间的绝对距离相等的情况下用欧式距离衡量效果是很差的,这个时候有曼哈顿距离效果会很好,曼哈顿距离会比欧氏距离稳定。用W2V训练出的词embedding在VSM中的欧式距离相等或者相近的情况是很常见的,所以用曼哈顿距离会稳定一些。余弦相似度适用于特征向量维度有很多的情况。

  Simase LSTM指的是具有simase结构的LSTM网络,由两个平行双向LSTM构成,结构参考下面两张图:

  以上截图来自2014~2015的学术论文。连体(双胞胎)LSTM输入为句子对儿,分别是上图中的左边和右边的。通过final state获取两个句子的向量,然后通过指数函数衡量差异,由于指数函数的指数为一阶范数的负数,所以取值范围为(0,1]。在构建样本的时候,一般情况给句子对儿打分都是1~5分,所以再通过一个非参数化的回归层映射到这个区间,用MSE作为损失函数,梯度优化方法为AdaDelta。一个典型的样本输入:[“I like playing basketball.”,”My favourite sports is basketball.”, 3.4]。按照作者在论文中提出的,连体的LSTM权重参数不应该一样,因为句子对儿长度是有差异的。另外作者在论文中提出了训练细节问题,经过试验验证,这个模型的准确度对参数初始化非常敏感。作者建议,权重参数初始化为随机的高斯分布参数,然后cell中忘记门的偏置值初始化为2.5,是为了训练更长的记忆能力。  

  siamese lstm方案的缺陷,有两个:①衡量长句子的语义相似度时候,效果比较差②没有融入外部知识。对于第一个缺陷,论文作者并没有进行深入的研究,本人经过摸索认为,不仅是长句子,即使对于短句子,如果里面涉及到了大量entity和relation的话,效果也并不是最优的。对于联结主义在语义理解上的贡献,本人认为第一个要突破的就是如何获取语义表示的多维度,而目前都是用LSTM的最后一个时间序列的out来压缩成一个向量来表示,这种表示不能捕捉多维度的语义。所以我们需要用一个矩阵权重参数来表示句子的语义权重,这个矩阵的每一行,应该都是一个概率和为1的概率分布,然后每一个概率分布应该捕捉语义的不同维度,最后concate来表示这个句子的语义。因此,在此基础上融合self_attention(2017年句子语义表示的baseline),尤其在情感分析中,效果非常好。 

        2018年3月10号,在北理工听了知识图谱专家的讲座,其中提到了融合知识图谱来做文本相似度的方案,值得研究一下。对于融合知识图谱和深度学习比如CNN做语义相似度,一个非常重要的场景就是新闻标题的推荐。新闻标题里往往包含大量的entity,识别出来后可以查询知识图谱得到one hot的entity,在其他标题中出现这些entity的新闻,用户往往也是感兴趣的,但不是绝对的。沿着知识图谱的路径,用户的兴趣会进行传播,这样的传播会有权重,这就是著名的用户兴趣传播,会形成一定的涟漪效应。把知识图谱的entity进行向量化,然后扩展标题中的词嵌入,在原来的词embedding基础上concate entity的embedding,然后用CNN捕捉标题的语义表示,与候选新闻做语义相似度运算。之前的博客提到过,个性化推荐的本质是语义理解中的语义相似度问题,这个定位非常重要,结合知识图谱,场景切入更自然,更加接近真实的效果,而且可以处理小数据。相比于传统的基于用户浏览数据的行为挖掘,更加符合实际,更加深入。

       语义相似度是nlp中的一个难题,如果突破了,会有一些改变,比如目前的问答,进展很是缓慢,为了节约成本或者前期缺少大数据,在垂直领域,很多公司用基于规则来做,召回率太低。问答,最初的时候,比如畅捷通的会计家园,使用的是基于语义相似度的方案,效果还可以。case by case。当用户经常提出一些比较长的问题,又不是BFQ的情况,比如,用户提问,我想知道注册会计师证考下来后,对就业到底有没有实质性的帮助,薪资能提升多少,好考吗?对于这类问题,用模板匹配显然是不合适的,向量建模更不合适。所以说,知识图谱的问答不是万能的。但是如果业内在语义相似度上突破了的话,那么这种方案,在垂直领域的问答,无疑是很好的。只要语料充足,遇到用户提出的问题,我们先进行语义相似度的计算,选出得分最高的问答的答案,直接呈现出来,如果相似度得分低于人工设定的阈值,进入seq2seq模块儿。这个方案,应该比目前的基于模板匹配要好一些。但是对于复杂的推理问题,比如梁启超的儿子的情人是谁这类问题,仍然需要语义解析,而且这样的场景,并没有多少实际意义。

  更深入地讲,如果之前接触过垂直搜索lucene的话,我们会发现,问答和搜索的本质是一致的,都是减少用户需求不确定的过程。这样的过程,是靠系统的语义解析来完成的,比如lucene,用户输入"苹果",系统根本不知道用户的需求,需要额外添加约束,比如商品分类:电脑,这样经过lucene的词法处理(比如分词),句法分析(比如形成一颗查询语法树,典型的Boolean query)后,搜索引擎能够理解这样的查询语言,最后呈现出结果来。而问答呢,两个问题:①question的语义表示②把语义表示映射成知识图谱可以理解的查询语言。典型的core inferential chain,就是把这个过程一步一步分解,在查询的过程中不断施加约束,最后得出答案。目前的问答,大概有如下方案:①检索+seq2seq,适用于比例不高的自由聊天,而且seq2seq的场景比例很小②基于模板匹配:本质上是获取问题的模板表示后,训练模板与知识图谱predicate的映射概率,属于统计建模范畴,而且限制较多,不能处理multi hot推理③基于语义解析的方案④基于向量建模的方案⑤信息抽取的方案。信息检索里面,比较重要的一个场景是排序,比如著名的BM25排序,是用朴素贝叶斯推导出来后简化的。基于检索+seq2seq的自由聊天,排序用的就是BM25,question和answer的语义相似度得分用的是seq2seq框架,然后计算匹配度。对于multi hot的问答,个人认为,应该借鉴检索的核心思想,把知识图谱的搜索过程分解,逐步施加约束,融合语义解析,向量建模,基于规则等多种手段。基于规则在问答当中的作用往往是对检索施加约束,是辅助手段,而核心往往是语义相似度计算,question的语义表示。

        所以,问答,一定要case by case 。对于BFQ的问答,模板无疑是比较好的,向量建模也可以。记住,场景是AI第一要素,切不可一味奉行拿来主义,先把自己的需求和场景研究明白了,才是关键。深度学习的研究方向,一定先把人类自身对于特定场景的逻辑搞明白了,才能少走弯路。

下一篇博客,继续介绍语义相似度:http://www.cnblogs.com/txq157/p/8656856.html

猜你喜欢

转载自www.cnblogs.com/txq157/p/8975973.html