为什么fuzz库的token_sort_ratio()计算相似度时结果不符合预期?
核心原因与解决方案
你得到49分的匹配结果并非代码逻辑错误,本质是对fuzzywuzzy不同匹配方法的计算逻辑存在认知偏差,选错了适配的匹配方法。
为什么计算结果是49分
fuzz.token_sort_ratio的底层逻辑是:将两个输入字符串全量拆分为独立分词,按字典序排序后重新拼接为新字符串,再计算两个新字符串的逐字符莱文斯坦相似度。整个计算过程会把两个字符串的全部内容纳入对比范围,不会自动识别、忽略长文本中与目标短串无关的冗余内容。- 你当前的对比场景中,目标短串(
key_up/key_low)仅17个字符长度,长串t1包含大量与目标无关的"blah"、"more"冗余内容,整串对比时冗余内容会大幅拉低相似度。 - 由于fuzzywuzzy内部默认会将所有输入字符串统一转为小写再参与计算,因此无论使用大写的
key_up还是小写的key_low,最终得到的匹配分数完全一致,均为49分。 - 你预期的「长串中完整包含目标短串即可得到满分」的效果,从来不是
fuzz.token_sort_ratio的设计目标,用这个方法自然无法得到预期结果。
适配当前场景的正确实现
根据你的匹配目标,替换对应匹配方法即可得到满分结果:
- 如果仅需要实现「长串中完整出现目标短串就算满分」的定位需求,使用
fuzz.partial_ratio:该方法会自动遍历短串在长串中的所有可能出现位置,定位相似度最高的局部匹配段计算得分,你当前的场景下会直接返回100分。 - 如果需要更高的鲁棒性(忽略长串冗余内容、容忍词序打乱),使用
fuzz.token_set_ratio:该方法会先提取两个字符串的共有分词集合,剔除长串中与短串无关的冗余分词、以及短串中不存在于长串的冗余分词,再基于共有分词计算相似度。该方法不仅能满足当前的子串包含匹配需求,还能应对比如"DISCHARGE DATE OF"这类词序打乱的匹配场景,实用性更强。
常用模糊匹配方法的适用场景参考
fuzz.ratio:适合长度、内容范围接近的整串逐字符对比,两个串长度差较大时得分会非常低fuzz.token_sort_ratio:适合长度接近、仅存在词序差异的整串对比,不适合长短差距大的包含类匹配场景fuzz.partial_ratio:适合短串在长串中定位的逐字符匹配场景fuzz.token_set_ratio:适合长短串混合、存在冗余内容、词序不固定的复杂匹配场景
内容的提问来源于stack exchange,提问作者Mohammad Amir
相关产品推荐
相关产品推荐

