目的是为了计算词语之间的各种语义关系。分为以下几类:
基于语义字典的方法:
这类方法,主要使用WordNet,MeSH这样的在线语义字典来度量两个义项之间的距离。基于WordNet中的概念是由概念间关系连接在一起的,每个概念都通过关系和其他概念相连,而整个WordNet则是由概念和关系组成的巨大的网络。
还有基于路径长度的,这是最简单的,Sim(c1,c2) = -log len(c1,c2),上面3-2是对这个路径相似度的改进,即方式假设边是等距离的,但明显不适合很多场景,因此3-2做了长度归一化。这种改进效果不大。实际上,对这种评估方式的最好改进是LCS。也就是Resnik相似度:-log P(LCS(c1,c2)),就是对词语在树图中的概念概率化,利用信息定义概念c的信息量。这里作者只考虑相同信息部分
后来Lin改进了上面的方式,同时考虑排除不同信息:2 * IC(lcs) / (IC(s1) + IC(s2))
类似的,Jiang-Conrath距离:1/(IC(s1) + IC(s2) - 2 * IC(lcs))
基于字典的相似度:
就是扩展的Lesk算法,主要思想是基于字典中两个概念或者义项的注释包含相同的词语,则他们就相似。实现的时候,定义重叠函数,计算两个概念A,B的上下位,部件及其他关系的的概念的注释之间的交集。
基于特征向量
这个就很多了,有手动定义的特征向量,有自动提取的特征向量。
度量有:
曼哈顿距离,欧氏距离,余弦距离,Jaccard距离(最小/最大距离),Dice距离,交叉熵距离(Jenson-Shannon 散度距离)
实际上,我想大多数应用现在都是基于向量算的,这里记录这些,只是做个基础了解。
莱文斯坦距离,又称Levenshtein距离,是编辑距离的一种。指两个字串之间,由一个转成另一个所需的最少编辑操作次数。允许的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。如“apple” 通过删除’l’与’e’转化为“app” ,所以其最小编辑次数为2。
LCS最长公共子序列,基于动态规划。
SSK(字符串核)通过将两个字符串表示成子串组成的特征空间来计算两者的相似度。如字符串car, cat, bat, bar,以长度为2的子串来表示它们,表示结果如下:
其中γ表示字符串的权重,γ的指数表示子串的距离(子串不要求连续),则cat 和car的核计算如下:
kernel(cat,cat)=2γ^4+γ^6.(向量内积)
kernel(car, car)=2γ^4+γ^6
kernel(car,cat)=γ^4(未归一化的核)
则car和cat的归一化后的核为:kernal(car,cat)/sqrt(kernel(cat,cat)*kernel(car, car))
=γ^4/sqrt((2γ^4+γ^6)*(2γ^4+γ^6))=1/(2+γ^2)
SimHash算法是Google公司进行海量网页去重的高效算法,它通过将原始的文本映射为64位的二进制数字串,然后通过比较二进制数字串的差异(海明距离)进而来表示原始文本内容的差异。
海明距离用于表示两个等长字符串对应位置不同字符的总个数,也即把一个字符串换成另一个字符串所需要的替换操作次数。根据定义,可以把海明距离理解为编辑距离的一种特殊情况,即只计算等长情况下替换操作的编辑次数。举个例子来讲,字符串“bob”与“pom”的海明距离为2,因为需要至少两次的替换操作两个字符串才能一致。海明距离较常用与二进制串上的操作,如对编码进行检错与纠错。在计算长字符串的相似性时可以 通过hash函数将字符串映射成定长二进制串再利用海明距离来计算相似性。
海明距离的计算比较简单,通过一个循环来比较对应位置的字符是否相同即可。
Dice距离用于度量两个集合的相似性,因为可以把字符串理解为一种集合,因此Dice距离也会用于度量字符串的相似性。此外,Dice系数的一个非常著名的使用即实验性能评测的F1值。
WMD(Word Mover's Distance)算法,是利用word embedding对词的表示,将句子(sentence)/文本(document)之间的距离,转化为运输问题,通过EMD(earth mover's distance)优化算法,计算两者之间的最小匹配耗费,以此作为文本相似性的距离度量。