Python 中的高性能模糊字符串比较,使用 Levenshtein 或 difflib
- 2025-04-15 09:21:00
- admin 原创
- 28
问题描述:
我正在进行临床信息规范化(拼写检查),其中我会根据90万词的医学词典检查每个给定的单词。我更关心时间复杂度/性能。
我想进行模糊字符串比较,但不确定要使用哪个库。
选项 1:
import Levenshtein
Levenshtein.ratio('hello world', 'hello')
Result: 0.625
选项 2:
import difflib
difflib.SequenceMatcher(None, 'hello world', 'hello').ratio()
Result: 0.625
在这个例子中,两者给出了相同的答案。你认为在这种情况下两者的表现相同吗?
解决方案 1:
如果您有兴趣快速直观地比较 Levenshtein 和 Difflib 的相似性,我对约 230 万本书名进行了计算:
import codecs, difflib, Levenshtein, distance
with codecs.open("titles.tsv","r","utf-8") as f:
title_list = f.read().split("
")[:-1]
for row in title_list:
sr = row.lower().split(" ")
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)——这里有一个很棒的概述。最小哈希算法在线性时间内从大型文本集合中查找相似性方面非常出色。我的实验室开发了一个使用最小哈希算法检测和可视化文本重用的应用程序,链接如下:https://github.com/YaleDHLab/intertext
解决方案 2:
difflib.SequenceMatcher 使用Ratcliff/Obershelp算法,它计算匹配字符的两倍数除以两个字符串中的总字符数。
Levenshtein 使用Levenshtein 算法,计算将一个字符串转换为另一个字符串所需的最少编辑次数
复杂
SequenceMatcher 在最坏情况下的时间是二次方的,并且其预期行为以一种复杂的方式依赖于序列中有多少个共同元素。(来自这里)
Levenshtein 是 O(m*n),其中 n 和 m 是两个输入字符串的长度。
表现
根据Levenshtein 模块的源代码:Levenshtein 与 difflib(SequenceMatcher)有一些重叠。它仅支持字符串,而不支持任意序列类型,但另一方面,它的速度要快得多。
扫码咨询,免费领取项目管理大礼包!