Python中的模糊字符串比较,与使用哪个库相混淆

Mag*_*gie 119 python string-matching difflib levenshtein-distance

我想做模糊字符串比较,但与使用哪个库混淆.

选项1:

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

Result: 0.625
Run Code Online (Sandbox Code Playgroud)

选项2:

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

Result: 0.625
Run Code Online (Sandbox Code Playgroud)

在这个例子中,两者给出了相同的答案.但我更喜欢使用__CODE__.专家的任何建议.谢谢.

__CODE__

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

在这种情况下,你认为两者都表现相似吗?

duh*_*ime 138

如果您对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
Run Code Online (Sandbox Code Playgroud)

然后我用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)
Run Code Online (Sandbox Code Playgroud)

结果: 在此输入图像描述

Difflib/Levenshtein的相似性确实非常有趣.

2018编辑:如果您正在努力识别类似的字符串,您还可以查看minhashing - 这里有一个很棒的概述.Minhashing在大文本集中找到相似之处的速度比O(n**2)快得多.我的实验室整理了一个应用程序,使用minhashing检测并可视化文本重用:https://github.com/YaleDHLab/intertext

  • 这太酷了!那你怎么看?Levenshtein 对标题长度的字符串有害吗? (3认同)
  • 这实际上取决于您在相似性指标中捕获的内容... (3认同)
  • 我认为 difflib 和 levenshtein 之间的一些分歧可能是因为 difflib 使用的自动垃圾启发式方法。如果禁用它会发生什么? (3认同)
  • 这是个好问题。自动垃圾过滤器仅在观察次数大于 200 时才生效,所以我不确定这个特定的数据集(书名)是否会受到很大影响,但值得调查...... (2认同)
  • @duhaime,感谢您的详细分析。我对这些情节很陌生,不知道如何解释它们。这些情节叫什么,以便我可以查找并了解它们? (2认同)
  • 查看第一张图,它比较了 levenshtein 和 difflib `ratio()` 函数各自报告差异的差异。如果两者相等,则 x=y 斜率上只会有点,对吗?但是这些图表明,levenshtein 报告的任何给定差异都比 difflib“更相似”:整个 difflib 范围内的 levenshtein 阈值为 0.75? (2认同)
  • @ZacharyYoung 上面的第一个图是散点图,第二个图有时称为“图矩阵”。在你的第二个注释中,我想说第一个图表明 levenshtein 相似性总是 &gt;= difflib 相似性。 (2认同)

Gha*_*uni 99

  • difflib.SequenceMatcher使用Ratcliff/Obershelp算法计算匹配字符的加倍数除以两个字符串中的字符总数.

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

复杂

SequenceMatcher是最坏情况下的二次时间,其预期情况行为依赖于序列共有多少元素的复杂方式.(从这里)

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

性能

根据Levenshtein模块的源代码:Levenshtein与difflib(SequenceMatcher)有一些重叠.它只支持字符串,而不支持任意序列类型,但另一方面它更快.