【问题标题】:ALGORITHM - String similarity score/hash算法 - 字符串相似度得分/哈希
【发布时间】:2011-10-03 16:05:38
【问题描述】:

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

让我们以这些字符串和分数为例:

你好世界 1000

世界你好! 1010

地球你好 1125

Foo bar 3250

FooBarbar 3750

Foo 酒吧! 3300

Foo 世界! 2350

你可以看到你好世界!和 Hello world 相似,分数也很接近。

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

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

【问题讨论】:

  • String similarity algorithims? 的可能重复项(以及许多其他以前的问题)
  • @larsmans 帖子的解决方案有点偏离了我不希望的方向(即他们专注于基于比较字符串的字符串相似性)。对我来说,数据庞大且流式传输,因此比较字符串是不可能的。我只是找到一种解决方法:对每个字符串进行评分(可能是不好的哈希类型),然后可以告诉我两个字符串是否相似。
  • 您好,我也对这个问题很感兴趣。你在这个问题上有什么进展吗?
  • @Bloodmoon:无法计算哈希值(整数)。由于我必须专注于工作,因此无法专注于研究。但是,我已经调整了 charikar Hash 算法以使其在某种程度上发挥作用。尽管如此,当字符串只有几个单词时,仍然存在一些理论上的限制。很难知道是否说,Hello world 类似于 Hello earth 或 Foo world 或 Foo earth?但是仍然需要研究以更好地优化具有足够单词数的字符串..
  • 可以通过哈希值的距离阈值来定义相似度吗?假设函数是 f(),|f("hello world")-f("helloworth")|

标签: python string algorithm cluster-analysis hash


【解决方案1】:

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

【讨论】:

  • soundex 在这里可能不起作用,因为我的消息中还包含数值和一些特殊字符。关于 Levenshtein 距离,我希望存储散列值而不是比较字符串本身,这对于数量庞大的流数据可能会很慢。可能以后可以用作备份的想法...无论如何感谢您的帮助:)
【解决方案2】:

您可能对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))

【讨论】:

  • OP 在示例中明确列出了一些长度不等的字符串,因此汉明距离不起作用。更一般地说,它是文本字符串的一个非常弱的指标。
  • OP 还说他想比较哈希值而不是字符串。
  • 正是我想根据计算的哈希值对字符串进行存储
【解决方案3】:

看看locality-sensitive hashing

基本思想是对输入项目进行哈希处理,以便相似项目以高概率映射到相同的桶(桶的数量远小于可能的输入项目的宇宙)。

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

【讨论】:

  • 这是迄今为止我遇到的最好的概念。我很快就会阅读所有相关文件。非常感谢
【解决方案4】:

您始终可以使用 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

【讨论】:

  • 编辑距离方法仅用于一次比较两个字符串。由于空间复杂性,它不可能(大量数据......我想我提到流数据)......不可能存储数据并使用 Levenshtein 距离一一检查
【解决方案5】:

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

【讨论】:

    【解决方案6】:

    TL;DR:Python BK-tree

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

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

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

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

    可以在here 找到有关 BK-trees 如何工作的博客条目。

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

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

    【讨论】:

      【解决方案7】:

      您可能想看看使用BK-Tree。这是discussion and python implementation

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

      【讨论】:

        【解决方案8】:

        我不知道您是否仍然对此感兴趣,但是在信息论中,有一种方法可以测量字符串或文本块有多少信息,也许您可​​以将该值用作哈希值以便对您的字符串。 它被称为熵,维基百科有一篇关于它的好文章:https://en.wikipedia.org/wiki/Entropy_(information_theory)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-02-24
          • 2011-04-04
          • 1970-01-01
          • 2011-12-10
          • 2016-09-25
          • 2011-04-26
          • 2013-06-06
          • 2018-03-08
          相关资源
          最近更新 更多