如何快速去除相似字符串?

How to Quickly Remove Similar Strings?

现在,我有一个包含大约 70,000 条推文的数据集,我正在尝试删除过于相似的推文。我决定使用大于 0.9 的 Levenshtein 比率作为推文过于相似的阈值。然而,我当前的代码本质上是将每条推文与其他每条推文进行比较,得到 O(N^2),这非常慢。到达 运行 需要 12 多个小时,这实在是太多了。我尝试将其并行化,这就是我现在 运行 正在做的事情,但我不知道这是否会将其加速到可接受的程度。有什么方法可以在 O(N) 内完成吗?

import json
import multiprocessing as mp
from pathlib import Path

import Levenshtein

def check_ratio(similar_removed, try_tweet):
    for tweet in similar_removed:
        if Levenshtein.ratio(try_tweet, tweet[1]) > 0.9:
            return 1
    return 0

def main():
    path = Path('C:/Data/Python/JobLoss')
    orig_data = []
    with open(path / 'Processed.json') as f:
        data = json.load(f)
        for tweet in data:
            orig_data.append(tweet[2])
    pool = mp.Pool(mp.cpu_count())
    similar_removed = []
    similar_removed.append((0, orig_data[0]))
    for i in range(1, len(orig_data)):
        print('%s / %s' % (i, len(orig_data)))
        too_similar = 0
        try_tweet = orig_data[i]
        too_similar = pool.apply(check_ratio, args=(similar_removed, try_tweet))
        if not too_similar:
            similar_removed.append((i, try_tweet))
    pool.close()
    final = [data[ind[0]] for ind in similar_removed]
    with open(path / 'ProcessedSimilarRemoved.json', 'w') as f:
            json.dump(final, f)

if __name__ == '__main__':
    main()

我最终使用了 this 问题的最佳答案中描述的方法,该方法使用 LSH 进行次线性时间查询,给出了次二次的总体复杂度;足够快满足我的需求。本质上,您使用 k-shingling 将每条推文变成一个集合,然后使用 min hash lsh 快速将相似的集合存储在一起。然后,无需将每条推文与其他所有推文进行比较,您只需在其存储桶中查找匹配项,这使得该方法比对所有对使用 Levenshtein 比率要快得多。