语义相似度(实践篇)
这篇文章,专门讲语义相似度问题。
先看场景:
scene(一):用户通过大众点评,线上约了餐馆,就餐后在上面发表了很多评论,评论中涉及了大量的餐馆的问题,比如菜品质量,酒店卫生,服务等等。现在需要抽取之中的要点,然后反馈给商家。
scene(二):KB_QA的两个问题:①获取question的语义表示②把语义表示转换成知识图谱的能够理解的语言逻辑形式。无论是核心推导链还是向量建模,核心都是question和answer的语义相似度问题。
虽然学术界对于语义相似度问题,都说是热点和难点,但是他到底难在哪里?今天有必要探讨一下。首先,衡量两个表达之间的相似度,是通过语义级别,而语义属于认知层面,这给研究带来带来了很大的难度。因为目前的联结主义,仅仅能解决语义表示,无法学习逻辑推理。其次,理解一句话或者一段话的语义,不是单纯靠归纳总结能力,还需要借助外部知识,就是说这句话表达了什么样的事件,这个事件可能会关联到很多实体,关系,路径。两个句子之间的关系、路径的交集一定程度上代表了语义的重合度。之前的研究,都是靠单纯靠联结主义,包括开头的两个场景,都是这个思路。
从算法角度来看的话,探索基于知识图谱的非监督学习是一个方向,目前有学者在研究;另外一个就是监督学习了,主要是借助深度学习。目前大部分的相似度改进,仍然是后者,前者的难度,对于工业界来说,非常大。从工业界的角度来看,最简单的相似度当然是元积了,比如著名的word2vector可以做词级别的语义相似度。通过简单的dot问题,确实能解决一些相似度问题,但是对于高精度的场景,实在是太粗糙了。如果单纯运用联结主义解决相似度的话,有3个问题需要解决:①语义表示的丰富性②语义的差异衡量③相似度的颗粒度问题。我想这是3个核心问题了。
以KB_QA作为切入点:场景是Ai第一要素,之前有很多人抛开场景研究相似度问题,比如用深度学习总结出语义表示后直接用元积或者cos,存在这种想法的人不在少数。这样的研究,没有任何意义。既然涉及到相似度,一定是句子对儿,或者文档对儿,我们一定要考虑双方的情况,不同的场景,不同的分析。那么KB_QA,涉及到question和answer,我们需要单独研究每一个对象。首先看question,举个例子:whtat's the name of Obama's wife?先用信息抽取的方法分析这句话,如果熟悉信息抽取的话,可以忽略以下了。一个问题,涉及到问题词qword,焦点词qfocus,主题词topic和中心动词qverb。其中qword比如what,who,where代表了问题的类型,比如where映射为type.location。qfocus代表了答案的类型,这是非常重要的参考标准,比如问句中的name。topic代表了问句中的主题,或者说是知识图谱中的推理的根节点,比如Obama。然后qverb一定程度上表明了topic和answer之间的一种关系,或者说是约束,当然其他的短语关系,也可以对topic构成一定的约束,比如:who first voiced Meg on Family Guy? Meg on Family Guy这个短语中,Meg对topic构成了一定的约束关系,包括出现of+topic短语,这在语言逻辑形式上往往是joint关系。明白了这些关系后,我们就知道衡量quesiton和anser之间的语义相似度,绝非是简单的cos!我们一定兼顾到question和anser之间的约束关系,因为KB_QA,本质上就是知识图谱的查询问题,只不过这个查询是通过一步步施加约束,缩小搜索范围最后得到答案。而每一步施加约束后,我们都会得到相应的奖励得分。
whtat's the name of Obama's wife?这句话得到了topic后,可以用multi-hot,也就是词袋模型来表示他的语义。然后answer,我们考虑三方面的约束关系:answer type,answer path,answer context,同样用multi-hot的词袋模型来表示,最后用dot做相似度。这个想法非常简单,但是缺陷非常多,语义相似度如果这么做的话,效果一定非常差。第一,在语义表示上存在非常的问题,类似于word2vector的词袋模型,在语义表示上不够丰富,不能考虑到语言的顺序;第二,在相似度颗粒度上,还是很粗糙,尽管考虑了answer的三个方面,但是这三个方面应该分开单独和question做相似度得分。基于这两个缺陷,我们改进为:用CNN抽取出question的三个方面的语义表示,然后答案的三种约束,单独和question的语义求形似度得分:
这样兼顾了语意表达的丰富性和相似度颗粒度问题。这个方案仍然有改进空间,方向就是语义表示的多维度问题。抛开场景,之前textCNN在文本分类中取得了成功,CNN抽取语义表示,类似于n-gram原理,比如过滤器设置为(2,3,4),分别代表2-gram,3-gram,4-gram。目前这个方案已经有了更好的,那就是BILSTM+self_attention。self_attention在捕捉一句话语义的多维度方面,有着非常大的优势,已经成为语义表示的baseline,所以把前面的方案替换为self_attention。(attention的类型很多,比如local,global,但是大多需要借助额外的语义表示,而且不能捕捉语义的多维度,self_attention是一种突破)
前面的基于向量建模的语义相似度方案,仍然存在缺陷,对于稍微复杂的问题,比如涉及到时序性的推理,或者multi-hot推理,显得略微吃力一些。向量建模其实还没有真正触及语言逻辑问题,只有融合了深度学习,语言逻辑,向量建模,规则,问答才能真正强大起来。语义解析的过程,我们换一种角度来研究。传统的语义解析,是一下子全部映射为查询语言,先经过lexicon映射,然后构建语法树。但是这个过程我们分解为多个步骤,不用一下子构建语法树,分解的好处是可以融合向量建模,信息抽取的思路,更方便地与深度学习,知识图谱融合。它其实是query graph的过程,在query的过程中不断施加约束,而每个环节施加的约束,或者说是action会有多个,我们可以从中选择出与quesion相似度得分最高的那个action最为最优的action,如此不断地施加约束,缩小范围,得到最终的结果。这就是微软著名的query graph,一下子提升了7.5个F1_score,这个提升在业内是比较罕见的。启发式的搜索算法很简单:
核心问题其实还是约束与question的语义相似度,在做core inferential chain与quesion的相似度时,颗粒度做的很细:
question和constraint,都是用CNN来抽取语义表示,然后dot。
从以上案例,我们看出,语义相似度,即使不考虑融合知识图谱的情况下,也绝不是很多人想的那样想当然。到现在为止还没有解决大众点评的问题,这个问题,明显不同于KB_QA,是另一个场景。
我们先来分析一下:之前我说过,研究深度学习,先把人自身的逻辑研究明白了,否则不会有突破,可能会走弯路。如果人工来抽取的话,你会怎么做?是一种怎样的逻辑?一定是这样的情景:在阅读用户的评论时,当读到了关于菜品质量的描述,我们做一个标记,抽取出来,当遇到卫生问题时,执行同样的逻辑。那么问题来了,人怎么知道要抽取哪些东西?他怎么知道这个要点是商家需要的?一定是在抽取之前,大脑中已经有了对应的抽取范围,他知道要抽取哪些东西。所以这个secene的解决很容易:首先收集关于餐馆问题的问题模板,尽量涵盖范围大一些,接下来就是要运用本人之前研究的siamese lstm(用self_attention改进后的方案)做语义相似度,问题迎刃而解,具体细节不走论述了。这里有一个重要的问题,抽取要点是有数量限制的,得到相似度得分之后,抽取出top K,这样做不太好,要设定得分阈值,低于这个阈值的,就pass掉。这类问题,用基于规则,效果会非常差,因为用户的评论,涉及到了情感倾向,而且会经常出现语义转折,长句子。对于这样的场景,语义表示的丰富性,多维度,非常重要了。
总结一下,语义相似度,在不考虑知识图谱的情况下,核心问题:①获取丰富的多维度的语义表示②语义表示做差后的打分函数映射,比如用ma距离衡量后用exp(-||x1 - x2||1)③颗粒度问题。另外非监督学习的方法,也可以探索,但是场景受限,准确度遭受工业界质疑。
到此为止了,今后的研究,会更多结合外部知识,融合知识图谱做语义重合度,推进语义理解的进步。