之前写过一篇文章:语义处理工具:语义版Jaccard相似度-CSDN博客 ,但在实际应用中发现,这篇文章中提到的算法还是有点问题,这次进行了一些优化,以事例进行算法说明。
两个句子
句子A:想买笔记本,请问苹果电脑的价格
句子B:问下联想笔记本多少钱
1、分子(即:语义相似性部分)计算
第一步:分词:
SetA={想买,笔记本,请问,苹果,电脑,的,价格}
SetB={问下,联想,笔记本,多少钱}
第二步:剔除无意义的停用词:
SetA={想买,笔记本,请问,苹果,电脑,价格}
SetB={问下,联想,笔记本,多少钱}
第三步:查找两个集合求交集得出相同语言片段个数为:
1 (即为:笔记本)
剔除词语“笔记本”后,
SetA1={想买,请问,苹果,电脑,价格}
SetB1={问下,联想,多少钱}
第四步:将SetA1、SetB1中的词语构造相似性矩阵,用横坐标和纵坐标对应词语的语义相似性填充矩阵元素值(可以用Word2Vec计算两个词语的余弦相似性,一般语义越相似,Cosine得分越大),填充好的矩阵形式如下图:
想买 | 请问 | 苹果 | 电脑 | 价格 | |
问下 | 0.24 | 0.99 | 0.22 | 0.13 | 0.33 |
联想 | 0.67 | 0.18 | 0.75 | 0.56 | 0.56 |
多少钱 | 0.66 | 0.20 | 0.33 | 0.27 | 0.99 |
第五步:随便选出一个阈值a=0.8,在计算语义相似性的时候,如果语言片段相似性高于阈值,我们认为两个语言片段语义匹配,这个阈值可以用来控制计算结束过程。
算法描述如下:
语义Jaccard相似性部分计算:
输入:语义相似性矩阵S,阈值a ;
输出:语义Jaccard公式分子部分分值Total
详细步骤:
循环如下步骤,直到算法退出:
Step 1.找到相似性矩阵S中的当前所有元素中的最高值;
Step 2.如果这个最高值高于阈值a,则Total+1,转Step 3 ;如果这个最高值低于阈值,则分子部分计算结束,输出Total值;
Step 3.把当前矩阵中的最高值对应矩阵横坐标和纵坐标的行及列中所有元素值置为0,其含义是这两个片段不再参与后面的计算了,然后返回Step 1步骤继续循环。
具体例子:
1. 分子总分Total=1;假设阈值a=0.8;
2.首先找到矩阵中的最高值:
想买 | 请问 | 苹果 | 电脑 | 价格 | |
问下 | 0.24(0,0) | 0.99 | 0.22 | 0.13 | 0.33 |
联想 | 0.67 | 0.18 | 0.75 | 0.56 | 0.56 |
多少钱 | 0.66 | 0.20 | 0.33 | 0.27 | 0.99(4,2) |
坐标[4,2]对应的0.99, 其代表片段“多少钱”和“价格”的片段语义相似性, 发现其大于阈值0.8,那么累积分子得分, 更新Total值:Total=1+1=2;
3.将矩阵中第五行和第五列所有元素相似性置为0,则当前形成:
想买 | 请问 | 苹果 | 电脑 | 价格 | |
问下 | 0.24(0,0) | 0.99 | 0.22 | 0.13 | 0 |
联想 | 0.67 | 0.18 | 0.75 | 0.56 | 0 |
多少钱 | 0 | 0 | 0 | 0 | 0(4,2) |
4.然后在矩阵剩下的元素里面找到最高值:坐标[1,0]对应的0.99, 其代表片段“问下”和“请问”的片段语义相似性,发现其值大于阈值0.8,那么累积分子得分,更新Total值:Total=2+1=3
5.将矩阵中第三行和第三列所有元素相似性都置为0,则当前形成:
想买 | 请问 | 苹果 | 电脑 | 价格 | |
问下 | 0(0,0) | 0 | 0 | 0 | 0 |
联想 | 0.67 | 0 | 0.75 | 0.56 | 0 |
多少钱 | 0 | 0 | 0 | 0 | 0(4,2) |
6.然后在矩阵剩下的元素里面找到最高值:坐标[2,1]对应的0.75, 发现坐标[2,1]对应的当前最高值小于阈值a,则计算过程结束, 输出分子值Total=3。
此时两个句子剩余:【想买、苹果、电脑、联想】,可以将这几个词语看做两个句子语义不同的部分, 用来计算分母。
2、分母如何计算
分母分为两部分: 第一部分其实就是分子,代表两个语言片段集合语义相似的部分; 第二部分从含义上代表两个语言片段集合语义不同的部分。 而这两者之和代表两个集合的语义并集。
我们接着把上面没有算完的语义Jaccard计算例子算完,在分子计算部分我们已经算出两者的语义相似性Total=2,此时可以算分母了:
首先,因为两个句子剩下【想买、苹果、电脑、联想】,所以可以得出m=4,于是得出分母值为:3+4=7
3、相似度计算
由于分子部分是3,于是这两个句子的语义版Jaccard最终得分为:
SemJac(“想买笔记本,请问苹果电脑的价格”,“ 问下联想笔记本多少钱”)=3/7=0.429
4、阈值参数调节
做出一批语义相同的句子对作为正例,然后再做一批语义重叠但是又不同的句子对作为负例。然后不断调整阈值a的取值,优化目标是看哪个阈值能够使得语义Jaccard公式计算出正例的相似度得分整体偏高往上移,而负例的相似度得分整体偏低往下走。