目录
在做自然语言处理的过程中,文本相似在有很重要的应用,我们经常会遇到需要找出相似语句的场景,这时候就需要把类似的句子归到一起,这里面就涉及到句子相似度计算的问题。本节介绍 基于Jaccard相似度来进行语义相似度计算。
1、原生态Jaccard
1.1定义
别名:狭义Jaccard
假设有两个集合:集合A和集合B,每个集合内各自包含若干元素,那么Jaccard计算两个集合的相似性就是:用两个集合元素的交集作为分子,两个集合元素的并集作为分母,两者相除即可。
简单地来说就是交集/并集:J(A,B)=|A∩B|/|A∪B|
1.2引申-Jaccard距离
由Jaccard相似度,可以转换成Jaccard距离: Jaccard Distance(A, B) = 1 - Jaccard(A, B)
1.3应用
应用方法:把两个要计算相似程度的句子改造成n-gram片段组成的两个集合,然后通过计算两个集合相同的n-gram片段个数作为集合交集,两个集合合并后的n-gram片段个数作为集合并集,这样就能得出两个句子的相似性得分。
例子: 比如下面两个句子
句子A:苹果电脑的价格
句子B:苹果ipad的价格
两个句子转换为2-gram后,形成如下集合:
SetA={苹果,果电,电脑,脑的,的价,价格}
SetB={苹果,果ipad,ipad的,的价,价格}
两个集合求交集得出相同语言片段个数为:
3 (即为:苹果,的价,价格)
两个集合求并集得出分母大小为:
8(即为:苹果,果电,电脑,脑的,的价,价格,果ipad,ipad的)
所以这两个句子的相似度为: 3/8=0.375
2、语义版Jaccard
2.1诞生
原因:经典Jaccard只是衡量两个句子字面上的文本匹配程度,在很多情况下无法判断句子语义上的相似性,如果用语义相似性替代字面相似性来改造一下Jaccard,那么在处理文本的时候会更有效!
例子: 比如下面两个句子
句子A:请问苹果电脑的价格
句子B:问下联想笔记本多少钱
两个句子转换为2-gram后,形成如下集合:
SetA={请问,问苹,苹果,果电,电脑,脑的,的价,价格}
SetB={问下,下联,联想,想笔,笔记,记本,本多, 多少,少钱}
两个集合求交集得出相同语言片段个数为:0
两个集合求并集得出分母大小为:16
所以这两个句子的相似度为: 0/16=0
但是很明显地,我们可以看出下面的单词之间语义相似度是非常高的:
请问 vs 问下
苹果 vs 联想
电脑 vs 笔记本
价格 vs 多少钱
能否对传统只进行字面匹配的Jaccard进行改造,使得两个句子能够进行语义级别的匹配计算?即可以将“电脑”/“笔记本”这种字面不匹配但是语义匹配的情况考虑进去,形成语义版Jaccard的最初想法。
2.2公式
语义版Jaccard具体计算公式如下
解释:
上述公式中,分子部分代表两个句子语言片段组成集合的语义交集:即语义相似性部分,分母代表两个句子语言片段组成集合的语义并集。(分母又可分为两部分:第一个部分和分子一样,代表语义交集,而第二个部分代表这两个集合的语义差异程度,两者之和形成集合并集)
2.3示例
还是下面两个句子
句子A:请问苹果电脑的价格
句子B:问下联想笔记本多少钱
2.3.1分子(即:语义相似性部分)如何计算:
第一步:分词:
SetA={请问,苹果,电脑,的,价格}
SetB={问下,联想,笔记本,多少钱}
第二步:剔除无意义的停用词:
SetA={请问,苹果,电脑,价格}
SetB={问下,联想,笔记本,多少钱}
第三步:构造相似性矩阵,用横坐标和纵坐标对应词语的语义相似性填充矩阵元素值(可以用Word2Vec计算两个词语的余弦相似性,一般语义越相似,Cosine得分越大),填充好的矩阵形式如下图:
请问 | 苹果 | 电脑 | 价格 | |
问下 | 0.99 | 0.22 | 0.13 | 0.33 |
联想 | 0.18 | 0.75 | 0.56 | 0.56 |
笔记本 | 0.23 | 0.60 | 0.95 | 0.17 |
多少钱 | 0.20 | 0.33 | 0.27 | 0.99 |
第四步:随便选出一个阈值a=0.8,在计算语义相似性的时候,如果语言片段相似性高于阈值,我们认为两个语言片段语义匹配,这个阈值可以用来控制计算结束过程。
算法描述如下:
语义Jaccard相似性部分计算:
输入:语义相似性矩阵S,阈值a ;
输出:语义Jaccard公式分子部分分值Total
详细步骤:
循环如下步骤,直到算法退出:
Step 1.找到相似性矩阵S中的当前所有元素中的最高值;
Step 2.如果这个最高值高于阈值a,则累加到Total中,转Step 3 ;如果这个最高值低于阈值,则分子部分计算结束,输出Total值;
Step 3.把当前矩阵中的最高值对应矩阵横坐标和纵坐标的行及列中所有元素值置为0,其含义是这两个片段不再参与后面的计算了,然后返回Step 1步骤继续循环。
具体例子:
1. 分子总分Total=0;假设阈值a=0.8;
2.首先找到矩阵中的最高值:
请问 | 苹果 | 电脑 | 价格 | |
问下 | 0.97 | 0.22 | 0.13 | 0.33 |
联想 | 0.18 | 0.75 | 0.56 | 0.56 |
笔记本 | 0.23 | 0.60 | 0.95 | 0.17 |
多少钱 | 0.20 | 0.33 | 0.27 | 0.99 |
坐标[5,5]对应的0.99, 其代表片段“多少钱”和“价格”的片段语义相似性, 发现其大于阈值0.8,那么累积分子得分, 更新Total值:Total=0.99;
3.将矩阵中第五行和第五列所有元素相似性置为0,则当前形成:
请问 | 苹果 | 电脑 | 价格 | |
问下 | 0.97 | 0.22 | 0.13 | 0 |
联想 | 0.18 | 0.75 | 0.56 | 0 |
笔记本 | 0.23 | 0.60 | 0.95 | 0 |
多少钱 | 0 | 0 | 0 | 0 |
4.然后在矩阵剩下的元素里面找到最高值:坐标[1,1]对应的0.97, 其代表片段“问下”和“请问”的片段语义相似性,发现其值大于阈值0.8,那么累积分子得分,更新Total值:Total=0.99+0.97=1.96
5.将矩阵中第三行和第三列所有元素相似性都置为0,则当前形成:
请问 | 苹果 | 电脑 | 价格 | |
问下 | 0 | 0 | 0 | 0 |
联想 | 0 | 0.75 | 0.56 | 0 |
笔记本 | 0 | 0.60 | 0.95 | 0 |
多少钱 | 0 | 0 | 0 | 0 |
6.然后在矩阵剩下的元素里面找到最高值:坐标[4,4]对应的0.95, 其代表片段“笔记本”和“电脑”的片段语义相似性,发现其值大于阈值0.95,那么累积分子得分,更新Total值:Total=0.99+0.97+0.95=2.91
7.将矩阵中第三行和第三列所有元素相似性都置为0,则当前形成右下图:
请问 | 苹果 | 电脑 | 价格 | |
问下 | 0 | 0 | 0 | 0 |
联想 | 0 | 0.75 | 0 | 0 |
笔记本 | 0 | 0 | 0 | 0 |
多少钱 | 0 | 0 | 0 | 0 |
8.发现坐标[2,2]对应的当前最高值小于阈值a,则计算过程结束, 输出分子值Total=2.91。
此时两个句子各自剩余1个语言片段没有进行匹配, 即:“联想”和“苹果”,可以将这两个片段看做两个句子语义不同的部分, 用来计算分母。
2.3.2分母如何计算
分母分为两部分: 第一部分其实就是分子,代表两个语言片段集合语义相似的部分; 第二部分从含义上代表两个语言片段集合语义不同的部分。 而这两者之和代表两个集合的语义并集。
假设经过分子计算步骤后,我们已经把参与分子部分计算的语言片段陆续都从SetA和SetB中删除掉,那么两个集合SetA和SetB可能都会剩余部分语言片段没有进行匹配,则分母部分的m定义为:
其含义是两个集合中没有达到语义匹配标准(由阈值a控制)两者中取最大值。 分母中Xdif代表SetA中没有参与分子计算的所有语言片段;Ydif代表SetB中没有参与分子计算的所有语言片段。而Cosine(Xdif, Ydif)的意思是两者的语义相似性,所以1-Cosine(Xdif, Ydif)代表两者的语义差异大小,两者语义差异越大则两个句子整个语义版Jaccard相似性分数会被拉低。
我们接着把上面没有算完的语义Jaccard计算例子算完,在分子计算部分我们已经算出两者的语义相似性Total=2.91,此时可以算分母了:
请问 | 苹果 | 电脑 | 价格 | |
问下 | 0 | 0 | 0 | 0 |
联想 | 0 | 0.75 | 0 | 0 |
笔记本 | 0 | 0 | 0 | 0 |
多少钱 | 0 | 0 | 0 | 0 |
首先,因为两个句子只剩下“联想”和“苹果”两个语义不匹配的片段,所以可以得出m=1,而Cosine(Xdif, Ydif) =0.75,所以1-Cosine(Xdif, Ydif) =0.25, 于是得出分母值为:2.91+0.25=3.1
由于分子部分是2.91,于是这两个句子的语义版Jaccard最终得分为:
SemJac(“请问苹果电脑的价格”,” 问下联想笔记本多少钱”)=2.91/3.1=0.94
2.3.3阈值参数调节方法
做出一批语义相同的句子对作为正例,然后再做一批语义重叠但是又不同的句子对作为负例。然后不断调整阈值a的取值,优化目标是看哪个阈值能够使得语义Jaccard公式计算出正例的相似度得分整体偏高往上移,而负例的相似度得分整体偏低往下走。
2.4结语
语义版Jaccard确实是可以改善原生Jaccard只做字面匹配的缺点,体现出句子深层次的语义相似性的。