词语相似度计算
词义相似度计算在很多领域中都有广泛的应用,例如信息检索、信息抽取、文本分类、词义排歧、基于实例的机器翻译等等。国内目前主要是使用知网和同义词词林来进行词语的相似度计算。
本文主要是根据《基于同义词词林的词语相似度计算方法–田久乐》论文中所提出的分层算法实现相似度计算,程序采用Java语言编写。
同义词词林扩展版
《同义词词林》是梅家驹等人于1983年编纂而成,这本词典中不仅包括了一个词语的同义词,也包含了一定数量的同类词,即广义的相关词。《同义词词林扩展版》是由哈尔滨工业大学信息检索实验室所重新修订所得。该版收录词语近7万条,全部按意义进行编排,是一部同义类词典。
同义词词林按照树状的层次结构把所有收录的词条组织到一起,把词汇分成大、中、小三类,大类有12个,中类有97个,小类有1400个。每个小类里都有很多的词,这些词又根据词义的远近和相关性分成了若干个词群(段落)。每个段落中的词语又进一步分成了若干个行,同一行的词语要么词义相同,要么词义有很强的相关性。
《同义词词林》提供了5层编码,第1级用大写英文字母表示;第2级用小写英文字母表示;第3级用二位十进制整数表示;第4级用大写英文字母表示;第5级用二位十进制整数表示。例如:
Cb30A01= 这里 这边 此地 此间 此处 此
Cb30A02# 该地 该镇 该乡 该站 该区 该市 该村
Cb30A03@ 这方
分层及编码表如下所示
由于第5级有的行是同义词,有的行是相关词,有的行只有一个词,分类结果需要特别说明,可以分出具体的3种情况。使用特殊符号对这3种情况进行区别对待,所以第8位的标记有3种,分别是“=”代表“相等”、“同义”;“#”代表“不等”、“同类”,属于相关词语;“@”代表“自我封闭”、“独立”,它在词典中既没有同义词,也没有相关词。
在对文本内容进行相似度计算中,采用该论文中给出的计算公式,两个义项的相似度用Sim
表示
若两个义项不在同一棵树上,Sim(A,B)=f
若两个义项在同一棵树上:
若在第2层分支,系数为a Sim(A,B)=1*a*cos*(n*π/180)((n-k+1)/n)
若在第3层分支,系数为b Sim(A,B)=1*1*b*cos*(n*π/180)((n-k+1)/n)
若在第4层分支,系数为c Sim(A,B)=1*1*1*c×cos*(n*π/180)((n-k+1)/n)
若在第5层分支,系数为d Sim(A,B)=1*1*1*1*d*cos*(n*π/180)((n-k+1)/n)
当编码相同,而只有末尾是“#”时,那么认为其相似度为e。
例如Ad02B04# 非洲人 亚洲人
则其相似度为e。
其中n是分支层的节点分支总数,k是两个分支间的距离。
如:人 Aa01A01=
和 少儿 Ab04B01=
以A开头的子分支只有14个,分别是Aa...,Ab...,Ac... ——— An...
,而不是以A开头的所有结点的个数,所以n=14
;在第2层分支上,人的编码是a
,少儿的编码是b
,a和b之间差1,所以k=1
。
该文献中给出的参数值为a=0.65
,b=0.8
,c=0.9
,d=0.96
,e=0.5
,f=0.1
。
Java代码实现
|
|
说明,词语相似度是个数值,一般取值范围在[0,1]之间,在原论文中,使用cos函数计算主要是将值归一化到[0,1]之间,可以将cos函数看作是一个调节因子。
testGetSimilarity的测试结果如下所示:
|
|
本文使用的是同义词词林的扩展版,而原论文使用的是同义词词林,由于两者存在微小差距,所以本文计算结果与论文中的计算结果存在稍许误差,如果算法没错,这是可以理解的!
以上仅为个人理解,如若发现错误,欢迎大家积极留言指正!
代码已经推送到GitHub上了,地址点我。注意在文章末尾所注的参考资料中的链接里面的计算方法在求n的时候存在错误,希望莫要受其误导!
参考文献
[1] http://www.cnblogs.com/einyboy/archive/2012/09/09/2677265.html