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

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

开场白:对于事物的理解,通常分3个层次:①看山是山,看水是水②看山不是山,看水不是水③看山是山,看水是水。对AI和nlp的理解,一样会有这三个层次。好比,刚毕业的硕士或者毕业1~2年的,会热衷于研究GAN,seq2seq,甚至包括nlp刚起步的一些公司。这类群体对nlp的理解处于第一层次,后面还有不少雷区要踩,要付出必定的试错代价,成长的代价。等到有必定的积累了,对nlp的理解有必定的理解功底了,会逐渐修正研究路线和方向,这个时候比第一阶段有更多的疑惑,由于随着研究的深刻,发现nlp和图像机制存在很大的不一样,不能照搬,认知智能好像不是那么容易,由感知智能到认知智能的跨越,是这一阶段的一大进步,这是第二个层次,各个派别有争论,看山不是山,看水不是水。最高境界,返璞归真,拥有行业20年及以上的研究人员,对nlp看的比较透,目前的Ai基本上陷入了统计建模,几率的漩涡之中,还不是真正的智能。仅仅从数据中挖掘线性关系还远远不够,应该让机器具备认知能力,挖掘因果关系。致力于推动nlp认知智能的进步,加大力度研究知识图谱,包括知识图谱的向量化,与深度学习的融合,让神经网络学习规则等等。能够这样说,目前从感知智能到认知智能的跨越,才刚刚开始,知识工程的复苏势不可挡。本人接触过许多刚入门的人,基本上对seq2seq和GAN比较狂热,对nlp缺少完整系统的认知。对于GAN在nlp中不work以及为什么不适用于nlp,可能没有深刻的思考,甚至图像处理机制和nlp文字理解的神经元机制,到底存在哪些不一样,目前须要深刻探讨。好比动物神经元对图像的识别,第一层神经元是保角映射,那么nlp中是否须要这种机制?把CNN照搬到nlp中,为什么会出现语义丢失问题?word2vector对于训练语料中未出现的词,如何更好地表达语义?它与TF_IDF存在着怎样的联系?LSTM一样存在语义丢失问题,如何解决?知识图谱的异构性和不均衡性给其向量化带来了挑战,在什么样的场景下须要向量化?把CRF神经网络化的必要性和场景又是什么?挖掘因果关系,好比:李娜为何是最好的网球运动员?这种简单的因果关系推理,知识图谱是如何发挥做用的?再好比,一我的从非洲回来了,发高烧了。这件事情背后,非洲,发高烧和疟疾存在线性关系,那么因果关系是什么?因此总结起来,nlp同时须要联结主义和符号主义,对于研究人员来讲,我的认为目前nlp的研究整体上应该朝着如下方向进行:①联结主义在nlp中的主要做用是语义表示,语义丢失问题必需要解决②由感知到认知的跨越:知识图谱,而后结合联结主义,其中一个方向是transD向量化,而后融入到深度学习模型中。写这篇文章不是为了发论文,也不是探讨基础的公式推导,主要目的是扩大传播面,点到为止,让一些刚入门的研究人员多一些思考,扩大知识面,甚至帮助其矫正研究方向。前面本人提到的问题,后面会部分有解答,可是大多数还须要坐冷板凳深刻研究。多与业内大咖探讨,共同推动nlp的进步。下面进入正文。数组

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

  然而联结主义只是解决了人的感知能力,还不具有逻辑推理。众所周知,人类有两种智能,一个是概括总结,另外一个是逻辑推理,前者属于感知层面,后者属于认知层面。从感知到认知的跨越,知识图谱是必不可少的!深度学习目前在语义表示上最大的问题是太机械化了,自适应能力太差,相比之下的统计几率语言模型能够平滑,灵活度高一些。好比用w2v训练出的词语义表示就很机械化,对于汉语中的一词多义现象,他没法作到上下文重叠。lstm用最后的压缩向量来表示一个句子的语义也很机械化,不能照顾到上下文的语境问题,同一句话在不一样的语境或者上下文中其语义或者语义贡献度是不一样的,因此语义表示也应该不一样。甚至同一句话用不一样的语气说,语义也是不一样的,机器如何感知?如何让现有的模型训练出的语义更加灵活是一个重要的研究课题。框架

  word2vector的语言模型有CBOW和Skip_gram,核心思想是:相同语境出现的词语义相近。这个思想在nlp语义上占据重要位置。用word2vector训练出的词表达具有语义关联,同时兼顾了上下文。w2v能够解决词级别的语义类似度问题。本人以word2vector为核心进行了延伸,以下:函数

  本人所画的图,对w2v进行了深刻的分析以及拓展,其中上下文交叉,词语歧义还属于空白。w2v的底层原理没必要多说,可是有不少的文章关于他的公式推导是不正确的,包括skip_gram的优化。tensorflow的nce(negative constantive estimate)源代码必定要完整地阅读一遍。关于w2v存在的问题,以前博客里有部分论述,这里不讨论他的缺陷了。词向量属于序列化问题,知识图谱的向量化是图结构的,把他碾平了能够当作是序列化的,其语言模型核心思想与w2v一模一样。有一个重要的须要讨论的问题是它与TF_IDF的关系,在SIF这篇论文里会有一些论述,把二者结合起来是有必要的,可是要看场景!!w2v从语义层面,TF_IDF从字面层面,二者结合能够更加灵活,能够解决w2v训练过程当中的部分高频词的语义倾斜,尤为是在out of context的场景下,这点从skip_gram的NEG底层公式推导中能够得出结论。更深一步地讲,w2v获取的词向量与频率有着密不可分的关联。能够把每一个句子看做是一篇没有重复词的DOC,那么训练语料中词的频率能够看做是TF_IDF中的IDF。在众多相同或者相近的上下文中,每一个词出现的频率不一样,直接致使每一个词与其上下文的语义关联程度不一样,最后形成的结果是高频词的语义向量相对于低频词更加稠密,与上下文关联更加紧密。从频率角度来看,高频词确实应该向量更加稠密一些,可是也会有部分高频词的语义倾斜是无心义的(在特定的场景下),好比and ,or等词语,而这些词在情感分析中却又是必要的。而针对out of context的场景,也就是这个词的上下文在训练语料中并无出现过,进行语义平滑是最恰当不过的了。图中出现了句子embedding表示,基于非监督学习的思想,每句话会有一个隐含的embedding表示,而句子中的每一个词会有训练好的embedding(w2v),由句子embedding进行发射,映射到每一个词的embedding,会有发射权重,加权求和后获得句子向量。这个向量与隐含的embedding的距离应该最小。这是SIF的思想精髓。而国外一些文献中,会有研究未登陆词的embedding,运用词形态学把词拆分,相似于character_cnn,可是很遗憾不适用于汉语。深刻研究w2v有助于利用非监督学习方法作语义层面的运算,包括词语,句子,文章摘要,甚至将来的歧义词。研究简单实用的方案,永远是工业界的使命。w2v的应用场景:①给机器一个简短语句,机器生成类似度比较高的句子,方案具体细节能够询问张俊林博士②运用SIF解决句子类似度问题(非监督学习)③结合pagerank作文章摘要④最广泛的,做为RNN的输入。最后强调一句,必定要对TF_IDF以及w2v深刻研究,发现二者的优缺点,学会在适当的场景下结合二者,可是不是绝对的,再强调一遍,学习Ai不要停留在套模型的原始思惟阶段。好比IDF的演化推导,能够从信息论的角度来理解。学习

  另外w2v训练过程的优化,若是优化效果不错的话,会提高LSTM,CNN等模型的效果。w2v须要改进,CNN一样也须要改进,尤为是max pooling,在nlp中不能照搬图像处理的机制,不然会丢失语义信息。关于丢失语义信息问题,是深度学习在nlp中必需要解决的问题。解决途径:①self_attention②k_max pooling或者动态池化层。本人比较青睐于self-attention,它主要与BiLSTM结合,更加符合nlp规律。还有,LSTM和CNN获取的语义表示,其实属于语言模型层面的,这一点能够本身体会。大数据

  在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是不同的,须要单独训练好,好比第二个能够衡量段落之间的语义类似性。

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

  其实上面描述的过程明显涉及到了hierarchical attention,并且是两个级别的attention:词级别的和句子级别的。词级别的attention负责把上下文中的每一个句子的词从新组合成一个新的句子,句子级别的attention在此基础上把这些新造成的句子再次从新组合成一个新的句子,这就是最终的上下文。若是这个最终的上下文语义表示和咱们猜想的中心句语义类似度很高,那么他就是中心句,若是不是,前向搜索继续执行这个逻辑。这个方案是本人首次提出的siamese lstm + hierarchical attention组合而成的,用以模拟人脑在抽取文章中心句的过程。具体训练的语料格式能够以下:【文章,中心句,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最大的意义是提供了基础学术研究,由于他获取到的语义表达是独立的,不具有语义关联,重要的事情重复三遍,不具有语义关联,不具有语义关联,不具有语义关联!!考察语义类似度,要考虑单个句子或者整篇文档的上下文。

  目前,计算语义关联,或者计算语义类似度,有众多学者探索了如下方案:①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构成,结构参考下面两张图:

  连体(双胞胎)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),尤为在情感分析中,效果很是好。 

  对于融合知识图谱和深度学习好比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

关于self_attention在语义表示中的做用:http://www.cnblogs.com/txq157/p/8445513.html

相关文章
相关标签/搜索