Python 算法-字符串相似性分数/哈希

Python 算法-字符串相似性分数/哈希,python,string,algorithm,cluster-analysis,hash,Python,String,Algorithm,Cluster Analysis,Hash,有没有一种方法可以计算字符串的一般“相似性分数”之类的东西?在某种程度上,我不是将两个字符串比较在一起,而是为每个字符串获取一些数字/分数(散列),以后可以告诉我这两个字符串是相似的还是不相似的。两个相似的字符串应具有相似(接近)的分数/哈希 让我们考虑这些字符串和分数作为一个例子: 你好,世界1000 你好,世界!1010 你好,地球1125 福巴3250 福芭芭拉3750 富吧!3300 富世界!2350 你可以看到你好世界!和Hello world相似,他们的分数相近 这样,找到与给定字符

有没有一种方法可以计算字符串的一般“相似性分数”之类的东西?在某种程度上,我不是将两个字符串比较在一起,而是为每个字符串获取一些数字/分数(散列),以后可以告诉我这两个字符串是相似的还是不相似的。两个相似的字符串应具有相似(接近)的分数/哈希

让我们考虑这些字符串和分数作为一个例子:

你好,世界1000

你好,世界!1010

你好,地球1125

福巴3250

福芭芭拉3750

富吧!3300

富世界!2350

你可以看到你好世界!和Hello world相似,他们的分数相近

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

我的最终目标是:将有流日志消息(只有纯消息),我想找到这些消息的模式(某种正则表达式类型)。但只有当我可以存储类似的字符串时,这才开始。我再次强调,我应该为每个字符串获取一些数字/分数(散列),这可以稍后告诉我两个字符串是否相似

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

  • 我认为python库已经有了一个实现
  • 您还可以计算
  • 纽约非法移民
您可能会感兴趣。Python函数hamming_distance()计算两个字符串之间的hamming距离

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

基本思想是对输入项进行散列,以便相似的项以高概率映射到相同的bucket(bucket的数量比可能的输入项的范围小得多)


有一个很好的解释和一些示例代码。

您可以始终使用Levenshtein distance,另外,还有一个书面实现:

但是,为了简单起见,您可以使用内置的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!']

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

TL;博士:

有趣的问题。我在这方面的经验有限,但由于Levenshtein距离满足三角形不等式,我认为必须有一种方法来计算到原点的某种绝对距离,以便找到彼此相邻的字符串,而无需对整个数据库中的所有条目进行直接比较

在谷歌搜索与此相关的一些术语时,我发现了一篇特别有趣的论文:马修·亚当·斯卡拉(Matthew Adam Skala)

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

但是,一般度量空间不提供 这些技术。对于一个没有其他度量空间的一般度量空间 假设,有必要使用基于距离的 仅根据点的距离对点进行索引的方法 从对方那里。Burkhard和Keller[35]提供了第一个 这种索引结构,现在被称为BK树的缩写,在 1973在BK树中,假设度量有几个离散的返回值,每个内部节点包含一个有利点,并且 子树对应于度量的不同值

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

在这篇论文中,Skala继续描述这个问题的其他解决方案,包括和GH树。第六章基于Levenshtein编辑距离分析距离。他还介绍了其他一些有趣的字符串距离度量


我还发现,这似乎与您的问题有关。

您可能想看看如何使用。这是一本书


BK树在树中存储字符串,按到父节点的Levenshtein距离排序。这通常用于在查找类似字符串时删减搜索空间,但这棵树似乎会形成一种自然的顺序,可用于创建群集。

我不知道您是否仍对此感兴趣,但在信息论中,有一种方法可以测量字符串或文本块包含的信息量,也许您可以将该值用作哈希,以便对字符串进行排序。
这就是所谓的熵,维基百科有一篇关于它的好文章:

可能的重复(以及之前的许多问题)@larsmans这篇文章的解决方案偏离了我不想看到的方向(即他们专注于基于比较字符串的字符串相似性)。对我来说,数据是巨大的流式数据,所以比较字符串是不可能的。我只找到了一种解决方法:对每个字符串进行评分(可能是糟糕的哈希类型),然后可以告诉我这两个字符串是相似的还是不相似的。您好,我对这个问题也很感兴趣。你在这个问题上有什么进展吗?@Bloodmoon:无法计算哈希值(整数)。我没能专心于研究,因为我得专心于工作。然而,我调整了charikar哈希算法,使其在某种程度上起作用。尽管如此,当字符串只有几个单词时,仍然存在一些理论上的限制。很难知道是说,Hello world类似于Hello earth还是Foo world或Foo earth?但仍然需要研究如何更好地优化字数足够多的字符串。相似性可以通过散列值的距离阈值来定义吗?假设函数为f(),且| f(“hello world”)-f(“hello worth”)|