快速检查大型数据库的编辑距离相似性

Eva*_*urg 9 python edit-distance similarity python-3.x

我有一个350,000字符串数据库,平均长度约为500.字符串不是由单词组成的,它们是基本上随机的字符组合.

我需要确保没有两个字符串太相似,其中相似性定义为编辑距离除以字符串的平均长度.划分是因为较小的字符串更容易接受较小的编辑距离.如果出于性能原因使用不同的度量标准,则可以正常运行,但编辑距离是首选的基准度量标准.

天真地,我们用运行时计算编辑距离,两个字符串的长度O(a*b)在哪里a,b.我们为所有n^2对执行此操作,这使得整体运行时间O(n^2*a*b)明显过大n=350,000, a,b=500.

数据库采用从csv文件读取的Python列表的形式.如果可能的话,我想以Pythonic的方式处理它.

怎么加速呢?我不确定天真算法需要多长时间才能完成(大约几周)但理想情况下应该花不到一天的时间才能运行.

Hao*_* Wu 4

我用 python 编写了一个简单的局部敏感哈希算法的非常简短的原型。然而,有一些注意事项,您可能还想优化一些部分。当我们看到他们时我会提到他们。

假设所有字符串都存储在strings.

import random
from collections import Counter

MAX_LENGTH = 500
SAMPLING_LENGTH = 10

def bit_sampling(string, indices):
    return ''.join([string[i] if i<len(string) else ' ' for i in indices])

indices = random.sample(range(MAX_LENGTH),SAMPLING_LENGTH)
hashes = [bit_sampling(string, indices) for string in strings]

counter = Counter(hashes)
most_common, count = counter.most_common()[0]
while count > 1:
    dup_indices = [i for i, x in enumerate(hashes) if x == most_common]
    # You can use dup_indices to check the edit distance for original groups here.
    counter.pop(most_common)
    most_common, count = counter.most_common()[0]
Run Code Online (Sandbox Code Playgroud)

首先,这是位采样的一个微小变体,最适合一般汉明距离。理想情况下,如果所有字符串的长度相同,这可以给出汉明距离的理论概率范围。当两个字符串之间的汉明距离很小时,它们不太可能具有不同的哈希值。这可以通过参数指定SAMPLING_LENGTH。较大的值SAMPLING_LENGTH将使其更有可能将相似的字符串散列为不同的散列,但也会降低将不太相似的字符串散列为相同散列的概率。对于汉明距离,您可以轻松计算这种权衡。

多次运行此代码片段可以增加您对不相似字符串的信心,因为每次您都会对不同的位置进行采样。

为了满足您比较不同长度字符串的目的,一种可能的方法是在较短的字符串上留下填充空间并复制它们。

尽管此代码片段中的所有操作都是线性的 (O(n)),但它仍然可能消耗大量内存和运行时间,并且可能会减少一个常数因子。

您可能还想考虑使用更复杂的局部敏感哈希算法,例如此处调查的算法: https: //arxiv.org/pdf/1408.2927.pdf