尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Whoosh自定义评分算法:从BM25F到专属Weighting的完整指南

Whoosh自定义评分算法:从BM25F到专属Weighting的完整指南 Whoosh自定义评分算法从BM25F到专属Weighting的完整指南【免费下载链接】whooshPure-Python full-text search library项目地址: https://gitcode.com/gh_mirrors/who/whooshWhoosh 是一个纯 Python 编写的全文搜索库它的默认评分算法 BM25F 已经能应对大多数检索场景。但当你想让搜索结果排序更贴合自己的业务——比如让最新发布的文章排名更靠前、让标题命中比正文命中更重要时就需要学习 Whoosh 自定义评分算法了。本文将带你从理解内置的 BM25F 开始一步步写出专属的 Weighting 评分模型全程有代码、有路径、有思路新手也能轻松上手。为什么默认的 BM25F 评分算法不够用Whoosh 默认使用 Okapi BM25F 作为评分算法它综合了词频TF、逆文档频率IDF和字段长度三个因素公式大致是score idf * (tf * (K1 1)) / (tf K1 * ((1 - B) B * fl / avgfl))这个公式的效果已经相当不错但它有两个痛点它不认识你的业务BM25F 不知道发布时间越近越重要也不知道VIP 用户的内容该加权。它对所有字段一视同仁标题和正文的长度差异只靠参数 B 微调很难做到标题命中权重翻倍。如果你遇到以上情况恭喜你你已经有了自定义评分算法的需求。实现代码都在 scoring.py 这个模块里下面我们一层层剥开它。认识 Whoosh 的评分体系WeightingModel 与 Scorer在动手之前先花一分钟理解 Whoosh 评分算法的两个核心角色WeightingModel权重模型负责配置保存算法的各种参数如 BM25F 的 B 和 K1并负责创建 Scorer。WeightingModel 基类Scorer打分器负责执行对每一个匹配的文档返回一个浮点分数。BaseScorer 基类使用方式非常简单——在创建 Searcher 时传入 weighting 参数即可from whoosh import scoring with myindex.searcher(weightingscoring.TF_IDF()) as s: results s.search(query)Whoosh 内置了 BM25F、TF_IDF、Frequency、DFree、PL2 等多种算法默认是 BM25F。接下来我们看三种自定义方式从简单到进阶。三种自定义评分算法的方式最简单用 FunctionWeighting 写函数评分如果你的需求只是一个简单的打分函数完全没必要写类。Whoosh 提供了FunctionWeighting只要写一个纯函数即可from whoosh import scoring def pos_score_fn(searcher, fieldname, text, matcher): # 关键词出现得越靠前分数越高 poses matcher.value_as(positions) return 1.0 / (poses[0] 1) pos_weighting scoring.FunctionWeighting(pos_score_fn) with myindex.searcher(weightingpos_weighting) as s: results s.search(query)这个例子出自官方 recipes.rst关键词在文档中出现得越早得分越高。适合摘要置顶首段命中优先这类需求。注意如果需要使用全局统计信息如文档总数记得用searcher.get_parent()获取顶层 searcher。最灵活继承 WeightingModel 写专属评分算法当你的评分规则复杂、需要缓存统计信息时就应该写完整的模型。核心是继承WeightingModel实现scorer()方法返回一个 ScorerScorer 再实现score()方法。利用现成的WeightLengthScorer基类它已经帮你处理了词频和字段长度代码量可以压到最少from whoosh import scoring class MyWeighting(scoring.WeightingModel): def __init__(self, boost2.0): self.boost boost # 自定义参数 def scorer(self, searcher, fieldname, text, qf1): return MyScorer(searcher, fieldname, text, self.boost) class MyScorer(scoring.WeightLengthScorer): def __init__(self, searcher, fieldname, text, boost): self.boost boost self.setup(searcher, fieldname, text) def _score(self, weight, length): # 词频越高分越高字段越短分越高再乘上你的业务权重 return (weight / (length 1)) * self.boost继承WeightLengthScorer时只需重写_score(weight, length)这一个方法参考 WeightLengthScorer 基类剩下的字段长度查询、最大质量计算等脏活累活它都替你干了。最省事用 MultiWeighting 按字段混搭算法如果你不想写任何新算法只是想不同字段用不同算法MultiWeighting是你的最佳选择——它可以为不同字段指定不同的权重模型from whoosh import scoring mw scoring.MultiWeighting( scoring.BM25F(), # 默认字段用 BM25F idscoring.Frequency(), # id 字段按词频 keysscoring.TF_IDF(), # 关键词字段用 TF-IDF ) with myindex.searcher(weightingmw) as s: results s.search(query)这个工具类定义在 scoring.py 的 MultiWeighting适合标题用 BM25F、标签用 TF_IDF这种混合检索场景。同类的还有ReverseWeighting反转分数用于找最不相关的结果和Weighting兼容旧版自定义打分器。BM25F 参数调优技巧不写代码也能改评分如果你不想自定义算法只想微调 BM25F 的效果好消息是它本身就有两个免费参数可以直接调K1控制词频饱和程度。K1 越大词频对分数的贡献越线性K1 越小词频再高分数也涨不动。B控制字段长度归一化的强度。B0 时完全忽略长度B1 时完全按长度归一化。更贴心的是BM25F 支持按字段设置 B 值通过字段名_B这种关键字参数传入即可from whoosh import scoring # 标题字段更看重命中B 调小正文按常规处理 w scoring.BM25F(B0.75, content_B1.0, K11.5) with myindex.searcher(weightingw) as s: results s.search(query)这个特性在 BM25F 类的文档字符串中有明确说明。修改前记得先记录基准搜索结果的排序改完参数对比一下调参才有意义。final() 方法文档级的评分调整技巧有些业务规则是文档级的——比如付费内容整体加分最新文章加权。这时可以用final()方法对每篇文档的最终分数做二次加工from whoosh.scoring import BM25F class MyWeighting(BM25F): use_final True # 必须设置为 True def final(self, searcher, docnum, score): # 让文档编号越大越新写入的文档分数越高 return score docnum * 10注意两点官方在 1.0 版本说明中强调过必须把use_final设为 True否则 Whoosh 会跳过final()调用以启用块级优化设置后 Whoosh 会对每个匹配文档都执行 final()性能会有所下降请谨慎使用。实战如何选择适合你的评分方案最后给你一张决策表按需取用你的需求推荐方案参考资料简单函数规则如按关键词位置FunctionWeightingrecipes.rst不同字段用不同算法MultiWeightingscoring.py只调 BM25F 的手感调整 B、K1、字段级_Bscoring.py完整的自定义评分算法继承WeightingModelWeightLengthScorerscoring.py文档级整体加权final()use_final Truereleases/1_0.rst小结Whoosh 作为一款纯 Python 全文搜索库其评分体系的扩展性做得非常出色FunctionWeighting让你 5 分钟搞定简单需求继承WeightingModel让你拥有完全自由的专属评分算法而MultiWeighting和final()则提供了混搭与兜底的灵活性。记住核心入口在 scoring.py所有内置算法的实现都是你最好的学习范本。下次再为搜索结果排序发愁时试着写一个属于你自己的 Whoosh 评分算法吧【免费下载链接】whooshPure-Python full-text search library项目地址: https://gitcode.com/gh_mirrors/who/whoosh创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表