字符串相似度

来源:互联网 发布:记忆宫殿软件下载 编辑:程序博客网 时间:2024/06/05 20:29

最近要对字符串进行聚类,这些字符串都是代码的输出,尝试了几种字符串相似度度量的方法:

Levenshtein距离

字符串核函数

LCS/max(len(str1,str2))


其中相似度用公式distance=1.0/similarity-1转换为距离.使用层次聚类方法.

下面是要聚类的字符串

    points = ['aabbccdd', 'aaddccbb', 'aaaaccbb', 'bbbbccdd',              'eeeebbccdd', 'aaeebbeeccdd',              'aaaaaaaa', 'aabbbbdd', 'bbccdd', 'aabbdd',              'aabb', 'aadd', 'bbdd', 'aa', 'bb',              'aabaaabaabaabaaaaba', 'abaaabaaabaabaaaab']

下面看一下使用Levenshtein距离聚类的过程的前几部:

['aabbccdd', 'bbbbccdd'] aabbccdd['aaddccbb', 'aaaaccbb'] aaddccbb['aabbbbdd', 'aabbdd'] aabbbbdd['bbccdd', 'bbdd'] bbccdd['aabb', 'aadd'] aabb['aa', 'bb'] aa
这里出现了有疑问的地方,aa和bb应该被分到一类么?

他们的Levenshtein距离比较小,但是他们是完全不同的.Levenshtein距离容易把短小的串认为是相近的.

最后的结果是

[[15, 16], [[4, 5], [6, [[[10, 11], [13, 14]], [[1, 2], [[8, 12], [[0, 3], [7, 9]]]]]]]]



下面看看使用LCS聚类的过程的前几部:

['aabaaabaabaabaaaaba', 'abaaabaaabaabaaaab'] aabaaabaabaabaaaaba['aabbccdd', 'bbbbccdd'] aabbccdd['aaddccbb', 'aaaaccbb'] aaddccbb['aabbbbdd', 'aabbdd'] aabbbbdd['bbccdd', 'aabbccdd', 'bbbbccdd'] bbccdd['eeeebbccdd', 'aaeebbeeccdd'] eeeebbccdd['bbdd', 'bbccdd', 'aabbccdd', 'bbbbccdd'] bbccdd['eeeebbccdd', 'aaeebbeeccdd', 'bbdd', 'bbccdd', 'aabbccdd', 'bbbbccdd'] bbccdd['aabb', 'aadd'] aabb['aa', 'aabb', 'aadd'] aa
可以看到,首先就把两个最长的聚到一起了,lcs认为他俩最相似.

lcs当然不会出现Levenshtein距离把aa和bb聚到一起的问题.

最后的结果是

<pre name="code" class="python">[[6, [15, 16]], [[14, [[4, 5], [12, [8, [0, 3]]]]], [[13, [10, 11]], [[1, 2], [7, 9]]]]]

这里把6和15,16聚到一起了


使用字符串核函数方法聚类,两个参数分别为,n=2,lambda=0.8
下面是使用字符串核函数聚类的过程的前几部:

['aaaaaaaa', 'aa'] aaaaaaaa['aabaaabaabaabaaaaba', 'abaaabaaabaabaaaab'] abaaabaaabaabaaaab['aabbbbdd', 'aabbdd'] aabbbbdd['bbbbccdd', 'bbccdd'] bbbbccdd['aaaaaaaa', 'aa', 'aabaaabaabaabaaaaba', 'abaaabaaabaabaaaab'] aabaaabaabaabaaaaba['eeeebbccdd', 'aaeebbeeccdd'] eeeebbccdd

这里首先把aaaaaaaa和aa聚到一起了,反映出字符串核函数也不是很完美

字符串核函数是计算两个字符串的长度为n的公共子序列有多少,lambda用来使大跨度子串的贡献呈指数递减.

最后的结果是

[[[4, 5], [0, [3, 8]]], [[1, 11], [[2, [[6, 13], [15, 16]]], [14, [12, [10, [7, 9]]]]]]]

字符串核函数能考虑到子串的跨度问题,这个是直接使用LCS不能做到的.

但是字符串核函数要计算长度为n的公共字串,成了一个大问题,


对代码的输出进行聚类,很明显,Levenshtein距离是不适合的.

字符串核函数因为n的限制,也有点问题.

反而是用LCS效果还不错.


0 0
原创粉丝点击