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

标签 python python-3.x similarity edit-distance

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

我需要确保没有两个字符串过于相似,相似度定义为编辑距离除以字符串的平均长度。划分是因为较小的编辑距离更适合较小的字符串。 如果出于性能原因使用不同的指标,这很好,但编辑距离是首选的基线指标。

天真地,我们计算edit distance使用运行时 O(a*b),其中 a,b 是两个字符串的长度。我们对所有 n^2 对执行此操作,这给出了 O(n^2*a*b) 的总体运行时间,对于 n= 显然太大了350,000,a,b=500

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

如何加快速度?我不确定朴素算法需要多长时间才能完成(大约数周),但理想情况下运行时间应该少于一天。

最佳答案

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

假设所有字符串都存储在 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]

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

多次运行此代码段可以增加您对没有相似字符串的信心,因为每次您都会在不同的地方采样。

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

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

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

关于python - 快速检查大型数据库的编辑距离相似性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48819439/

相关文章:

metrics - 计算一组集合之间的相似度

python - 两个列表元素的PMI

r - 查找配对之间最常见的组合

python - 在 python 中重复列表 N 次?

python - Flask-登录。我在哪里存储用户以便 user_loader 函数找到他们?

python-3.x - 可以使用Google python脚本上传YouTube视频描述文件吗?

python - 抓取 PyQt 中的任何异常

python - 正则表达式搜索到第一个Python实例

python - 将 yield 与多个 ndb.get_multi_async 一起使用

python - 如何在 VIPS/Python 中对特定色调范围应用变换