当前位置: 首页 > article >正文

rapidfuzz进阶应用:让模糊匹配更上一层楼,解锁更强大的字符串处理能力!

rapidfuzz 进阶应用:让模糊匹配更上一层楼,解锁更强大的字符串处理能力!

回顾与升级:从入门到进阶

在上一篇文章中,我们一起认识了 Python 模糊匹配神器 rapidfuzz,体验了它闪电般的速度和强大的基本功能。我们了解了 fuzz 模块的基础用法,例如 fuzz.ratio()fuzz.partial_ratio() 等,以及 process 模块的 process.extract()process.extractOne(),掌握了如何快速进行字符串相似度计算和最佳匹配提取。

但是,rapidfuzz 的强大远不止于此! 如果你想让你的模糊匹配技术更上一层楼,应对更复杂的实际场景,那么这篇文章将带你深入 rapidfuzz 的进阶应用,解锁更多高级技巧,让你的字符串处理能力更上一层楼!

进阶主题一: 精准调优,选择合适的匹配算法

rapidfuzz 提供了多种模糊匹配算法,每种算法都有其独特的优势和适用场景。 仅仅使用 fuzz.ratio() 有时可能无法满足所有需求。 为了获得更精准的匹配结果,我们需要根据具体的应用场景选择最合适的算法。

回顾 fuzz 模块的核心算法:

  • fuzz.ratio(s1, s2) (Levenshtein Distance Ratio): 这是最常用的算法,基于编辑距离计算相似度。适用于大多数场景,特别是字符串长度相近的情况。
  • fuzz.partial_ratio(s1, s2): 适用于一个字符串是另一个字符串子串的情况。例如,在长文本中查找关键词。
  • fuzz.token_sort_ratio(s1, s2): 通过对字符串中的单词进行排序,忽略词序的影响。适用于处理词序错乱的情况。
  • fuzz.token_set_ratio(s1, s2):token_sort_ratio 的基础上,更关注单词的交集和并集,更适用于处理包含大量重复单词或关键词的情况。
  • fuzz.WRatio(s1, s2) (Weighted Ratio): rapidfuzz 默认使用的加权算法,它会根据字符串的特性(如是否是部分匹配、token 匹配等)智能地调整权重,通常能提供比 fuzz.ratio 更准确的结果。

进阶应用场景与算法选择建议:

  • 场景一: 地址匹配与标准化

    在处理地址数据时,经常会遇到地址书写不规范、简称、别称等问题。 例如 “北京市海淀区中关村大街1号” 可能被写成 “北京海淀中关村1号”、“中关村大街1号 北京”。

    • 推荐算法: fuzz.WRatiofuzz.token_sort_ratiofuzz.WRatio 通常能很好地处理地址中的细微差异。 fuzz.token_sort_ratio 可以忽略地址中词序的改变,例如 “大街 中关村” 和 “中关村 大街” 应该被认为是相似的。
    from rapidfuzz import fuzz
    
    address1 = "北京市海淀区中关村大街1号"
    address2 = "北京海淀中关村1号"
    address3 = "中关村大街1号 北京"
    
    print(f"WRatio(addr1, addr2): {fuzz.WRatio(address1, address2)}") # 输出较高相似度
    print(f"WRatio(addr1, addr3): {fuzz.WRatio(address1, address3)}") # 输出较高相似度
    print(f"token_sort_ratio(addr1, addr3): {fuzz.token_sort_ratio(address1, address3)}") # 输出 100
    
  • 场景二: 商品名称模糊搜索优化

    电商网站的商品名称往往包含大量关键词,用户搜索时可能只输入部分关键词,或者关键词顺序不同。 例如商品名称 “Apple iPhone 13 Pro Max 256GB 远峰蓝”,用户可能搜索 “iPhone 13 蓝色 256G” 或 “苹果13 Pro Max 远峰蓝”。

    • 推荐算法: fuzz.token_set_ratiofuzz.WRatio 结合 partial_ratiotoken_set_ratio 可以有效地处理关键词顺序和缺失的情况,关注关键词的集合相似度。 如果需要更精确的匹配,可以结合 partial_ratio,确保用户输入的部分关键词在商品名称中存在。
    from rapidfuzz import fuzz
    
    product_name = "Apple iPhone 13 Pro Max 256GB 远峰蓝"
    search_query1 = "iPhone 13 蓝色 256G"
    search_query2 = "苹果13 Pro Max 远峰蓝"
    
    print(f"token_set_ratio(product, query1): {fuzz.token_set_ratio(product_name, search_query1)}") # 输出较高相似度
    print(f"token_set_ratio(product, query2): {fuzz.token_set_ratio(product_name, search_query2)}") # 输出较高相似度
    print(f"WRatio(product, query1): {fuzz.WRatio(product_name, search_query1)}") # 可能略低,但仍可接受
    
  • 场景三: 基因序列或蛋白质序列比对 (生物信息学)

    在生物信息学中,序列比对是非常重要的任务。基因序列或蛋白质序列可能存在插入、删除、替换等变异。

    • 推荐算法: fuzz.ratio (Levenshtein Distance Ratio) 或考虑使用专门的生物信息学库,但 rapidfuzzfuzz.ratio 仍然可以作为快速初步筛选的工具。 对于更专业的序列比对,可能需要考虑 gap penalty 等更复杂的算法,但这超出了 rapidfuzz 的默认功能范围。
    from rapidfuzz import fuzz
    
    seq1 = "ACGTACGTACGT"
    seq2 = "ACGTACGTACT" # 略有不同
    seq3 = "AAAAAAAAAAAA" # 完全不同
    
    print(f"ratio(seq1, seq2): {fuzz.ratio(seq1, seq2)}") # 较高相似度
    print(f"ratio(seq1, seq3): {fuzz.ratio(seq1, seq3)}") # 较低相似度
    

总结: 选择合适的算法是提升模糊匹配精度的关键。 理解不同算法的特性,并结合具体的应用场景进行选择,才能发挥 rapidfuzz 的最大潜力。

进阶主题二: process 模块高级用法:自定义评分函数与多进程加速

process 模块的 extractextractOne 函数已经非常方便,但 rapidfuzz 还允许我们进行更高级的定制,例如:

  1. 自定义评分函数 (scorer): 默认情况下,process 模块使用 fuzz.WRatio 作为评分函数。 但我们可以根据需求,传入自定义的评分函数。 例如,如果我们想使用 fuzz.token_set_ratio 进行提取,可以这样做:

    from rapidfuzz import process, fuzz
    
    choices = ["apple inc", "apple incorporated", "banana inc", "orange inc"]
    query = "apple company"
    
    results_default = process.extract(query, choices, scorer=fuzz.WRatio)
    results_token_set = process.extract(query, choices, scorer=fuzz.token_set_ratio)
    
    print("Default WRatio results:", results_default)
    print("Token Set Ratio results:", results_token_set)
    

    应用场景: 当你发现默认的 fuzz.WRatio 不适用于你的特定数据时,可以通过自定义 scorer 来灵活切换到其他算法,或者甚至编写完全自定义的评分逻辑。

  2. 多进程加速 (score_cutoff, workers): 当处理海量数据时,即使 rapidfuzz 速度很快,单进程处理仍然可能耗时较长。 process.extractprocess.extractOne 函数提供了 workers 参数,可以启用多进程并行计算,显著提升处理速度。

    同时, score_cutoff 参数可以设置一个最低相似度阈值,只有当相似度高于这个阈值时才会被返回。 这可以有效地减少需要处理的结果数量,进一步提升效率。

    from rapidfuzz import process, fuzz
    import time
    
    choices = [f"string_{i}" for i in range(100000)] # 10万个字符串
    query = "string_50000_typo" # 模拟一个略有拼写错误的查询
    
    start_time_single = time.time()
    results_single = process.extract(query, choices, limit=5)
    time_single = time.time() - start_time_single
    
    start_time_multi = time.time()
    results_multi = process.extract(query, choices, limit=5, workers=-1, score_cutoff=80) # 使用所有CPU核心,并设置阈值
    time_multi = time.time() - start_time_multi
    
    print(f"单进程耗时: {time_single:.4f} 秒, 结果: {results_single[:2]}...")
    print(f"多进程耗时: {time_multi:.4f} 秒, 结果: {results_multi[:2]}...") # 多进程通常快很多
    

    注意: workers=-1 表示使用所有可用的 CPU 核心。 多进程加速在处理大规模数据集时效果显著。 score_cutoff 可以根据实际情况调整,例如只关注相似度在 80% 以上的结果。

进阶主题三: 结合其他库,构建更强大的应用

rapidfuzz 可以与其他 Python 库结合使用,构建更强大的应用。 例如:

  • pandas 结合进行数据清洗: 可以使用 rapidfuzzpandas DataFrame 中进行模糊匹配,查找相似的记录,进行去重、合并或标准化。

    import pandas as pd
    from rapidfuzz import process, fuzz
    
    data = {'product_name': ["apple iphone 13", "apple iphone 13 pro", "Apple iPhone 13", "banana", "bananas"]}
    df = pd.DataFrame(data)
    
    def find_best_match(product_name, choices):
        result = process.extractOne(product_name, choices, scorer=fuzz.WRatio)
        return result[0] if result else None
    
    unique_names = df['product_name'].unique().tolist()
    df['standardized_name'] = df['product_name'].apply(lambda x: find_best_match(x, unique_names))
    
    print(df)
    
  • 与 NLP 库 (如 spaCy, NLTK) 结合进行语义相似度计算: 虽然 rapidfuzz 主要关注字符串的字面相似度,但可以结合 NLP 库进行预处理,例如提取关键词、进行词干化/词形还原等,然后再使用 rapidfuzz 进行模糊匹配,从而提升语义层面的匹配效果。

总结与展望: rapidfuzz 的无限可能

rapidfuzz 不仅仅是一个快速的模糊匹配库,更是一个强大的工具,可以帮助我们解决各种复杂的字符串处理问题。 通过深入理解其各种算法、灵活运用 process 模块的高级功能,并结合其他 Python 库,我们可以构建出更智能、更高效的应用。

希望这篇进阶文章能帮助你更深入地了解 rapidfuzz,并在实际项目中充分发挥它的潜力。 模糊匹配的世界还有很多值得探索的地方,rapidfuzz 将是你手中的利器,助你披荆斩棘,让字符串处理工作更加轻松高效!

行动起来!

  • 尝试在你的项目中应用本文介绍的进阶技巧。
  • 阅读 rapidfuzz 的官方文档,了解更多高级功能和参数。
  • 分享你在使用 rapidfuzz 过程中遇到的问题和心得,一起交流学习!

互动一下!

你还希望了解 rapidfuzz 的哪些进阶应用或技巧? 欢迎在评论区留言,我会尽力解答!


http://www.kler.cn/a/555404.html

相关文章:

  • 具身智能在智能巡检机器人中的应用——以开关柜带电操作机器人为例
  • Python 函数-调用函数
  • SearXNG——自建一个属于自己的免费搜索引擎平台
  • 软件需求类的论文无法量化评价的问题
  • 深度解读Grok-2:新一代AI大模型的崛起
  • 【OS安装与使用】part3-ubuntu安装Nvidia显卡驱动+CUDA 12.4
  • 【登月计划】 DAY2 中期:产品研发与设计验证(4-6)--《设计图纸如何从电脑飞进生产线?揭秘研发系统的 “暗箱操作”》
  • 苍穹外卖day8 地址上传 用户下单 订单支付
  • 网络安全-防御 第三次作业(图像配置和拓扑测试后续)
  • 接口测试-API测试中常用的协议(中)
  • 电脑连接wifi成功但上不了网 电脑网络故障解决方法
  • 什么是bundle?什么是chunk?什么是module?
  • HOW - 服务接口超时时间和建议策略
  • 新手向:SpringBoot后端查询到数据,前端404?(附联调时各传参方式注解总结-带你一文搞定联调参数)
  • Qt的QToolBox样式设置
  • 科普:“git“与“github“
  • 基于Spring Security 6的OAuth2 系列之十七 - 高级特性--设备授权码模式
  • Coze怎么发送消息到飞书
  • stm32hal库寻迹+蓝牙智能车(STM32F103C8T6)
  • HTML/CSS中交集选择器