字符串相似度问题

问题这样引出,两个字符串的相似度如何进行比较?朴素的想:先比较长度,再单独比较每个字符,那么又有问题,当长度不一样字符也不一样的时候这个不同的度是多少?

这个问题表现了本人的思想一种奇怪的回路,多维视角的问题下不清晰的定义导致解决问题无法继续。

多维视角下的问题的确是存在和合理的,但是需要将维度统一化,长度不同 字符不同,如果你把空位视为一个"字符",长度不同也是一种字符不同,而不必陷入去怎么定义,长度不同时给他的度是多少,字符不同时他的度是多少,这种无法解决的问题或者给定任意数并不影响解决问题,这个可以归属到系数上面。

另一个奇怪回路是:a和b的不同与a与s的不同的度量是否一样,这也是不影响最终解决问题的系数问题,在26键下,你可以定义a和s的差距是1,而ab是6,在9键输入时,可以定义a和b的差距是1,而as是5;这种考虑不能说是没有意义,它不应该阻碍你对模型的建立。

搜索一番,我们得到一些前人已有的结论:
https://zhuanlan.zhihu.com/p/91645988?utm_id=0

Jaccard 相似度

J ( A , B ) = ∣ A ∩ B ∣ ∣ A ∪ B ∣ = ∣ A ∩ B ∣ ∣ A ∣ + ∣ B ∣ − ∣ A ∩ B ∣ J(A,B) = \frac{|A\cap B |}{|A\cup B |} = \frac{|A\cap B |}{|A| + |B| - |A \cap B|} J(A,B)=ABAB=A+BABAB
模怎么求?模就是集合A的长度

The Jaccard coefficient measures similarity between finite sample sets, and is defined as the size of the intersection divided by the size of the union of the sample sets

Sorensen Dice 相似度

s = 2 ∣ A ∩ B ∣ ∣ A ∣ ∪ ∣ B ∣ s = \frac{2|A\cap B |}{|A|\cup| B |} s=AB2∣AB

集合交集的 2 倍除以两个集合相加,并不是并集。

Levenshtein 莱文斯坦距离

这个算法比较重要,实现算法也很妙,用了动态规划。这个算法会比较两个字符串的每个字符,把不同定义为:增加 修改 删除,成为编辑距离。
那么什么时候应该增加,修改删除呢?
比如字符串 abcd bcd,比较两个字符串第一个字符,a和b时,应该修改?把a改成b还是把b改成a?嘉定我们以长的为准,那么应该是把b改成a
于是有了 abcd acd 但是这个字符串实际上应该是增加a就行了呢?所以何时应该修改?
那么,因为只有一个字符,我们看不出来应该增加还是修改,但是显然它不同,我们再纳入第二个字符
ab和bc?乱套了!!!!!
自然想到,这个时候就需要n* n 次遍历比较了
固定一个,另一个动,两个都动没意义。
a b
a bc
a bcd
ab b
ab bc
ab bcd
abc b
abc bc
abc bcd
abcd b
abdc bc
abcd bcd

我们最终要求的是 abcd 和 bcd的距离
这个问题的确可以拆分成更小的子问题 l(abcd, bcd) =min( l(a,_ ) + l(bcd,bcd) , l(a,b) + l(bcd,cd) …) 同级分解时取最小数
首先知道要拆分处理,但是拆分时又存在分割符移动,那么,简单地,遍历就行。这个东西真的不好陈述
莱温斯坦算法中已经定义变更分为三种:删除,插入,修改;怎么处理字符串应不应该删除?在目标字符串前加入空白字符串即可,就是上面的_
关于插入和修改的问题:当是等长对比时,字符不一样,那么显然就是修改,当源字符串长度小于目标字符串时,就是插入了,因为变更操作导致的距离都是1,没有额外的系数,所以直接加1就行
于是就有两个运算示例表
abcd和acd的距离,就是矩阵最后一个值1
s r c s p a c e a c d a 1 0 1 2 b 2 1 1 2 c 3 2 1 3 d 4 3 3 1 \begin{matrix} src & space & a & c & d\\ a & 1 & 0 & 1 & 2\\ b & 2 & 1 & 1 & 2 \\ c & 3 & 2 & 1 & 3 \\ d & 4 & 3 & 3 & 1 \end{matrix} srcabcdspace1234a0123c1113d2231
在确定 matrix[i][j]的值时,先取matrix[i-1][j-1] matrix[i][j-1]`` matrix[i-1][j]这三个的最小值,就是它的上方左方左上中的最小值,如果mtrix[i][0]是等于matrix[0][j],说明这个位置不需要再变化,直接取附近距离的最小值,否则加1。
以图中c=2 a=2 的位置计算举例,这个位置表示abc到a的莱温斯坦距离,
左上表示 L(ab->_ _ ) = 2
上方表示L( ab->a ) = 1
左方表示L(abc->_ _ _ ) = 3
因为a!=c 所以此位置为 1 + 1 = 2 表示L(abc -> a) = 2

汉明距离

两个等长字符串中的不一致字符的个数

余弦相似度

s = cos ⁡ ( θ ) = A B ∣ A ∣ ∣ B ∣ s = \cos (\theta )= \frac {AB}{|A||B|} s=cos(θ)=A∣∣BAB

∣ A ∣ = ∑ i = 1 n A i |A| = \sqrt { \sum_{i=1}^{n} A_{i} } A=i=1nAi
那么,已知字符串,怎么表示成向量A?
求两个字符串的并集,然后把每个字符,通过0表示不存在,1表示存在转换成向量

附录

Letax语法支持-在线书写:https://www.latexlive.com/
Letax语法支持-简书:https://www.jianshu.com/p/23e03593916d
莱文斯坦距离:https://www.zhihu.com/question/315634571

你可能感兴趣的:(算法)