算法 - 字符串相似度得分/哈希

时间:2011-07-12 14:00:57

标签: python string algorithm cluster-analysis hash

是否有一种方法可以计算字符串的一般“相似度得分”?在某种程度上,我不是将两个字符串比较在一起,而是我为每个字符串得到一些数字/分数(哈希),以后可以告诉我两个字符串是或不相似。两个相似的字符串应该具有相似(接近)的分数/哈希值。

让我们将这些字符串和分数视为一个例子:

Hello world 1000

你好世界! 1010

Hello earth 1125

Foo bar 3250

FooBarbar 3750

Foo Bar! 3300

Foo世界! 2350

你可以看到Hello world!和Hello世界是相似的,他们的分数彼此接近。

这样,找到与给定字符串最相似的字符串将通过从其他分数中减去给定字符串得分然后对其绝对值进行排序来完成。

我的最终目标是:会有流式日志消息(只有纯消息),我想找到这些消息的模式(某种正则表达式类型)。但只有在我可以使用类似的字符串时才会启动。我再次关注我应该为每个字符串获得一些数字/分数(哈希)并且可以告诉我两个字符串是否相似

8 个答案:

答案 0 :(得分:6)

查看locality-sensitive hashing

  

基本思想是对输入项进行散列,以便类似的项以极高的概率映射到相同的存储桶(存储桶的数量远小于可能的输入项的范围)。

有一个非常好的解释here以及一些示例代码。

答案 1 :(得分:5)

有几个这样的“分数”,但它们都取决于你如何定义相似性。

答案 2 :(得分:5)

TL; DR:Python BK-tree

有趣的问题。我在这个领域的经验有限,但由于Levenshtein距离满足三角不等式,我认为必须有一种方法来计算与原点的某种绝对距离,以便在不直接执行的情况下找到彼此附近的字符串。比较整个数据库中的所有条目。

在搜索与此相关的一些条款时,我发现了一篇特别有趣的论文:Matthew Adam Skala撰写的Aspects of Metric Spaces in Computation

在第26页,他讨论了基于kd-trees和其他的相似性度量,但得出结论:

  

但是,一般度量标准空间不提供所需的几何体   那些技巧。对于没有其他的一般度量空间   假设,基于距离的距离是必要的   索引的方法完全基于它们的距离   彼此。 Burkhard和Keller [35]提供了第一个   这样的索引结构,现在称为BK树的首字母缩写   1973.在BK树中,假设度量具有一些离散的返回值,每个内部节点包含一个有利位置,并且   子树对应于度量标准的不同值。

可以找到关于BK树如何工作的博客文章here

在论文中,Skala继续描述这个问题的其他解决方案,包括VP-trees和GH-trees。第6章基于Levenshtein编辑距离分析距离。他还为字符串提供了一些其他有趣的距离指标。

我还找到Foundations of Multidimensional and Metric Data Structures,这似乎与您的问题相关。

答案 3 :(得分:2)

要快速确定字符串相似性,可能需要使用fuzzy hashing

答案 4 :(得分:1)

你总是可以使用Levenshtein距离,还有一个书面实现: http://code.google.com/p/pylevenshtein/

但是,为简单起见,您可以使用内置的difflib模块:

>>> import difflib
>>> l
{'Hello Earth', 'Hello World!', 'Foo Bar!', 'Foo world!', 'Foo bar', 'Hello World', 'FooBarbar'}
>>> difflib.get_close_matches("Foo World", l)
['Foo world!', 'Hello World', 'Hello World!']

http://docs.python.org/library/difflib.html#difflib.get_close_matches

答案 5 :(得分:1)

您可能希望使用BK-Tree。这是discussion and python implementation

BK-Tree在树中存储字符串,按照与父节点的Levenshtein距离进行排序。这通常用于在查找类似字符串时修剪搜索空间,但似乎这棵树将形成可用于创建集群的自然顺序。

答案 6 :(得分:1)

我不知道你是否还在这,但在信息理论中,有一种方法可以衡量一个字符串或一大块文本有多少信息,也许你可以使用该值作为哈希来排序你的字符串。 它被称为熵,维基百科有一篇很好的文章:https://en.wikipedia.org/wiki/Entropy_(information_theory)

答案 7 :(得分:0)

您可能对Hamming Distance感兴趣。 Python函数hamming_distance()计算两个字符串之间的汉明距离。

def hamming_distance(s1, s2):
    assert len(s1) == len(s2)
    return sum(ch1 != ch2 for ch1, ch2 in zip(s1, s2))