You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fuzzywuzzy为何对完全相同的术语未返回100%相似度?

解决Fuzzywuzzy匹配相似度不符合预期的问题

先纠正代码中的致命错误

你的代码里有个关键错误:process.extract返回的每个匹配结果是**(匹配字符串, 相似度分数, 原列表索引)**,但你取了ratio[0][2](索引值)作为相似度,这完全不是真正的分数,这是导致你看到结果异常的直接原因!应该改成ratio[0][1]来获取相似度分数。

其他可能的原因及解决方案

1. 字符串存在隐藏格式差异

即使肉眼看起来相同的字符串,可能存在前后空格、全角/半角符号、不可见控制字符(换行、制表符)等差异,导致匹配分数异常。

解决方法:先对字符串做标准化清理:

def clean_string(s):
    if pd.isna(s):
        return ""
    # 去除前后空格、转小写、替换全角空格为半角、移除特殊符号(按需调整规则)
    return s.strip().lower().replace(' ', ' ').replace('[^a-zA-Z0-9\u4e00-\u9fa5]', '', regex=True)

# 应用到两个数据框的名称列
df1['NAME_CLEAN'] = df1['NAME_LIST1'].apply(clean_string)
df2['NAME_CLEAN'] = df2['NAME_LIST2'].apply(clean_string)

2. 默认匹配算法不适用你的场景

Fuzzywuzzy的process.extract默认使用WRatio算法,它是多种匹配逻辑的加权组合,在某些场景下(比如需要严格完全匹配),不如单一精准算法合适。

根据你的需求选择对应的匹配算法(通过scorer参数指定):

  • fuzz.ratio:严格逐字符比对,完全相同的字符串会返回100分,适合需要精确匹配的场景。
  • fuzz.token_set_ratio:忽略单词顺序、重复项,适合短语类匹配(比如"苹果派"和"派苹果"会得到高分)。
  • fuzz.partial_ratio:适合短字符串匹配长字符串的场景(比如"苹果"和"苹果派"会得到高分)。

修改后的匹配代码(结合清理后的字符串):

from fuzzywuzzy import process, fuzz

NAME_MATCH = []
similarity = []

# 使用fuzz.ratio做严格匹配,也可根据需求替换其他scorer
for i in df2.NAME_CLEAN:
    match_result = process.extract(i, df1.NAME_CLEAN, limit=1, scorer=fuzz.ratio)
    NAME_MATCH.append(match_result[0][0])
    similarity.append(match_result[0][1])  # 正确获取相似度分数

df2['NAME_MATCH'] = NAME_MATCH
df2['similarity'] = similarity

3. 验证字符串差异(排查疑难情况)

如果清理后还是有问题,可以打印字符串的原始字符编码,检查是否有隐藏字符:

# 取疑似相同的两个字符串
s1 = df1['NAME_LIST1'].iloc[0]
s2 = df2['NAME_LIST2'].iloc[0]
# 打印每个字符的Unicode编码
print([ord(c) for c in s1])
print([ord(c) for c in s2])

对比编码列表,就能发现是否有肉眼不可见的差异。

替代模糊匹配方案推荐

如果Fuzzywuzzy的效果仍不理想,可以尝试这些工具:

  • rapidfuzz:Fuzzywuzzy的优化复刻版,速度提升10-100倍,API完全兼容,适合大数据量匹配。
  • difflib:Python标准库,适合简单的字符串相似度比对,无需额外安装。
  • spaCy:结合NLP实体识别的专业匹配工具,适合名称、术语类的精准匹配。

内容的提问来源于stack exchange,提问作者smartini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 21:21:49