【问题标题】:High performance fuzzy string comparison in Python, use Levenshtein or difflib [closed]Python中的高性能模糊字符串比较,使用Levenshtein或difflib [关闭]
【发布时间】:2011-10-05 03:59:37
【问题描述】:

我正在进行临床信息规范化(拼写检查),其中我将每个给定的单词与 900,000 个单词的医学词典进行核对。我更关心时间复杂度/性能。

我想做模糊字符串比较,但不确定使用哪个库。

选项 1:

import Levenshtein
Levenshtein.ratio('hello world', 'hello')

Result: 0.625

选项 2:

import difflib
difflib.SequenceMatcher(None, 'hello world', 'hello').ratio()

Result: 0.625

在这个例子中,两者都给出了相同的答案。您认为在这种情况下两者的表现是否相同?

【问题讨论】:

    标签: python string-matching levenshtein-distance difflib


    【解决方案1】:

    如果您对 Levenshtein 和 Difflib 相似性的快速直观比较感兴趣,我计算了大约 230 万本书的标题:

    import codecs, difflib, Levenshtein, distance
    
    with codecs.open("titles.tsv","r","utf-8") as f:
        title_list = f.read().split("\n")[:-1]
    
        for row in title_list:
    
            sr      = row.lower().split("\t")
    
            diffl   = difflib.SequenceMatcher(None, sr[3], sr[4]).ratio()
            lev     = Levenshtein.ratio(sr[3], sr[4]) 
            sor     = 1 - distance.sorensen(sr[3], sr[4])
            jac     = 1 - distance.jaccard(sr[3], sr[4])
    
            print diffl, lev, sor, jac
    

    然后我用 R 绘制了结果:

    出于好奇,我还比较了 Difflib、Levenshtein、Sørensen 和 Jaccard 的相似度值:

    library(ggplot2)
    require(GGally)
    
    difflib <- read.table("similarity_measures.txt", sep = " ")
    colnames(difflib) <- c("difflib", "levenshtein", "sorensen", "jaccard")
    
    ggpairs(difflib)
    

    结果:

    Difflib / Levenshtein 的相似性确实很有趣。

    2018 年编辑:如果您正在努力识别相似的字符串,您还可以查看 minhashing——有一个 great overview here。 Minhashing 擅长在线性时间内发现大型文本集合中的相似性。我的实验室在此处组装了一个使用 minhashing 检测和可视化文本重用的应用程序:https://github.com/YaleDHLab/intertext

    【讨论】:

    • 这太酷了!那你怎么看? Levenshtein 对标题长度的字符串很不利吗?
    • 这真的取决于您试图在相似性指标中捕获的内容...
    • 我认为 difflib 和 levenshtein 之间的一些分歧可以解释为 difflib 使用的 autojunk 启发式。如果禁用它会发生什么?
    • 这是个好问题。 autojunk 过滤器仅在观察次数大于 200 时才会生效,所以我不确定这个特定的数据集(书名)是否会受到很大影响,但值得调查......
    • @duhaime,感谢您的详细分析。我对这些情节很陌生,不知道如何解释它们。这些情节叫什么,以便我查找并了解它们?
    【解决方案2】:
    • difflib.SequenceMatcher 使用Ratcliff/Obershelp 算法计算匹配字符数的两倍除以两个字符串中的字符总数。

    • Levenshtein 使用Levenshtein algorithm 计算将一个字符串转换为另一个字符串所需的最少编辑次数

    复杂性

    SequenceMatcher 是最坏情况的二次时间,其预期情况的行为以复杂的方式取决于序列有多少共同元素。 (from here)

    Levenshtein 是 O(m*n),其中 n 和 m 是两个输入字符串的长度。

    性能

    根据 Levenshtein 模块的source code : Levenshtein 与 difflib (SequenceMatcher) 有一些重叠。它只支持字符串,不支持任意序列类型,但另一方面它要快得多。

    【讨论】:

    • 非常感谢您提供的信息。我添加了更多细节。这里是:I am doing clinical message normalization (spell check) in which I check each given word against 900,000 word medical dictionary. I am more concern about the time complexity/performance.你认为在这种情况下两者的表现是否相同。
    猜你喜欢
    • 2022-06-03
    • 2010-10-15
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多