Python中的高性能模糊字符串比较,使用Levenshtein或difflib

问题描述 投票:0回答:2

我正在进行临床消息标准化(拼写检查),其中我根据 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
2个回答
234
投票

如果您对 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 绘制结果:

enter image description here

出于好奇,我还比较了 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)

结果: enter image description here

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

2018 年编辑:如果您正在努力识别相似的字符串,您还可以查看 minhashing——这里有一个很棒的概述。 Minhashing 在线性时间内查找大型文本集合中的相似性方面非常出色。我的实验室开发了一个应用程序,可以使用 minhashing 来检测和可视化文本重用:https://github.com/YaleDHLab/intertext


135
投票
  • difflib.SequenceMatcher 使用 Ratcliff/Obershelp 算法,它计算匹配字符的双倍数量除以两个字符串中的字符总数。

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

复杂性

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

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

性能

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

© www.soinside.com 2019 - 2024. All rights reserved.