BM25(Best Matching 25)算法基本思想

  BM25(Best Matching 25)是一种用于信息检索(Information Retrieval)和文本挖掘的算法,它被广泛应用于搜索引擎和相关领域。BM25 基于 TF-IDF(Term Frequency-Inverse Document Frequency)的思想,但对其进行了改进以考虑文档的长度等因素。

一.基本思想

  以下是 BM25 算法的基本思想:

  1. TF-IDF 的改进: BM25 通过对文档中的每个词项引入饱和函数(saturation function)和文档长度因子,改进了 TF-IDF 的计算。
  2. 饱和函数: 在 BM25 中,对于词项的出现次数(TF),引入了一个饱和函数来调整其权重。这是为了防止某个词项在文档中出现次数过多导致权重过大。
  3. 文档长度因子: BM25 考虑了文档的长度,引入了文档长度因子,使得文档长度对权重的影响不是线性的。这样可以更好地适应不同长度的文档。

二.计算方程

  BM25 的具体计算公式如下:

BM25 ( D , Q ) = ∑ i = 1 n IDF ( q i ) ⋅ f ( q i , D ) ⋅ ( k 1 + 1 ) f ( q i , D ) + k 1 ⋅ ( 1 − b + b ⋅ len ( D ) avg_len ) \text{BM25}(D, Q) = \sum_{i=1}^{n} \text{IDF}(q_i) \cdot \frac{{f(q_i, D) \cdot (k_1 + 1)}}{{f(q_i, D) + k_1 \cdot \left(1 - b + b \cdot \frac{{\text{len}(D)}}{{\text{avg\_len}}}\right)}} BM25(D,Q)=i=1nIDF(qi)f(qi,D)+k1(1b+bavg_lenlen(D))f(qi,D)(k1+1)

其中:

  • n n n是查询中的词项数。
  • q i q_i qi是查询中的第 i i i个词项。
  • IDF ( q i ) \text{IDF}(q_i) IDF(qi)是逆文档频率,计算方式通常是 log ⁡ N − n ( q i ) + 0.5 n ( q i ) + 0.5 \log\frac{{N - n(q_i) + 0.5}}{{n(q_i) + 0.5}} logn(qi)+0.5Nn(qi)+0.5,其中 N N N是文档总数, n ( q i ) n(q_i) n(qi) 是包含词项 q i q_i qi的文档数。
  • f ( q i , D ) f(q_i, D) f(qi,D)是词项 q i q_i qi在文档 D D D 中的出现次数(TF)。
  • len ( D ) \text{len}(D) len(D) 是文档 D D D 的长度。
  • avg_len \text{avg\_len} avg_len 是所有文档的平均长度。
  • k 1 k_1 k1 b b b 是调整参数,通常设置为 k 1 = 1.5 k_1 = 1.5 k1=1.5 b = 0.75 b = 0.75 b=0.75

  BM25 算法的实现通常用于排序文档,使得与查询更相关的文档排名更靠前。在信息检索领域,BM25 已经成为一个经典的算法。

三.Python 实现

  以下是一个简单的 Python 实现 BM25 算法的例子。请注意,实际应用中可能需要进行更复杂的文本预处理,例如去除停用词、词干化等。

import math
from collections import Counterclass BM25:def __init__(self, corpus, k1=1.5, b=0.75):self.k1 = k1self.b = bself.corpus = corpusself.doc_lengths = [len(doc) for doc in corpus]self.avg_doc_length = sum(self.doc_lengths) / len(self.doc_lengths)self.doc_count = len(corpus)self.doc_term_freqs = [Counter(doc) for doc in corpus]self.inverted_index = self.build_inverted_index()def build_inverted_index(self):inverted_index = {}for doc_id, doc_term_freq in enumerate(self.doc_term_freqs):for term, freq in doc_term_freq.items():if term not in inverted_index:inverted_index[term] = []inverted_index[term].append((doc_id, freq))return inverted_indexdef idf(self, term):doc_freq = len(self.inverted_index.get(term, []))if doc_freq == 0:return 0return math.log((self.doc_count - doc_freq + 0.5) / (doc_freq + 0.5) + 1.0)def bm25_score(self, query_terms, doc_id):score = 0doc_length = self.doc_lengths[doc_id]for term in query_terms:tf = self.doc_term_freqs[doc_id].get(term, 0)idf = self.idf(term)numerator = tf * (self.k1 + 1)denominator = tf + self.k1 * (1 - self.b + self.b * (doc_length / self.avg_doc_length))score += idf * (numerator / denominator)return scoredef rank_documents(self, query):query_terms = query.split()scores = [(doc_id, self.bm25_score(query_terms, doc_id)) for doc_id in range(self.doc_count)]sorted_scores = sorted(scores, key=lambda x: x[1], reverse=True)return sorted_scores# Example usage
corpus = ["The quick brown fox jumps over the lazy dog","A quick brown dog outpaces a swift fox","The dog is lazy but the fox is swift","Lazy dogs and swift foxes"
]bm25 = BM25(corpus)
query = "quick brown dog"
result = bm25.rank_documents(query)print("BM25 Scores for the query '{}':".format(query))
for doc_id, score in result:print("Document {}: {}".format(doc_id, score))

  此代码创建了一个简单的 BM25 类,通过给定的语料库计算查询与文档的相关性得分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/622540.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Spring Boot集成中间件:Elasticsearch基础->提高篇

使用Spring Boot集成中间件:Elasticsearch基础->提高篇 导言 Elasticsearch是一个开源的分布式搜索和分析引擎,广泛用于构建实时的搜索和分析应用。在本篇博客中,我们将深入讲解如何使用Spring Boot集成Elasticsearch,实现数…

C++ 对象模型 | 关于对象

一、C 对象模型 1、对象内存布局 在C中,有两种数据成员:static和nonstatic,以及三种成员方法static、nonstatic、virtual,下面从虚函数、非虚函数、静态成员变量、非静态成员变量等维度来分析,类对象的内存布局。例如…

多线程(1)

1.实现多线程 1.1简单了解多线程【理解】 是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能。 1.2并发和并行【理解】 并行:在同一时刻,有多个指令在多个CPU上…

【打卡】牛客网:BM87 合并两个有序的数组

思想: 简单粗暴的方法是先合并、再排序。没有技术含量。 此外,很容易想到是用归并方法。问题是对A[]从前往后赋值,会覆盖A[]中有用的数值。 模板的巧妙之处是,从后往前赋值,完美避开覆盖问题。 我看了模板的之后写…

js let和var的区别

在JavaScript中,let和var都是用来声明变量的关键字,但它们之间存在一些重要的区别: 作用域:var声明的变量具有函数作用域或全局作用域,这意味着它们的作用域范围在函数内或全局范围内。相比之下,let声明的…

Centos创建一个Python虚拟环境

在 CentOS 上创建一个 Python 虚拟环境,可以使用 virtualenv 工具。以下是创建和激活虚拟环境的基本步骤: 1.安装virtualenv 如果还没有安装 virtualenv,可以使用以下命令安装: sudo yum install python3-virtualenv请注意&…

聚道云软件连接器助力知名企业,提升合同管理效率

一、客户介绍 某服饰股份有限公司是一家集服装设计、生产、销售及品牌建设于一体的企业。该公司的产品线涵盖男装、女装、童装等多个领域,设计风格时尚、简约、大方,深受消费者喜爱。公司注重产品研发,不断推陈出新,紧跟时尚潮流…

【linux笔记】vim

【linux笔记】vim 启动和退出 启动 vi退出 q强制退出 q!编辑模式 vi foo.txt创建一个文件,启动后,是命令模式,是不能编辑的,键盘上的按键对应不同的命令。 插入模式 按键盘上的i,进入插入模式 保…

Redis(概述、应用场景、线程模式、数据持久化、数据一致、事务、集群、哨兵、key过期策略、缓存穿透、击穿、雪崩)

目录 Redis概述 应用场景 Redis的线程模式 数据持久化 1.Rdb(Redis DataBase) 2.Aof(Append Only File) mysql与redis保持数据一致 redis事务 主从复制(Redis集群) 哨兵模式 key过期策略 缓存穿透、击穿、…

剑指offer面试题5 从尾到头打印链表

考察点 链表知识点 数组和链表都属于线性表。线性表在计算机中有俩种存储方式,按照顺序存储的就是数组,按照链式存储的就是链表,二者最大的区别在于一个是顺序存储(地址空间连续)一个是链式存储(地址空间不连续)。因此数组元素只包含元素值…

iToF wiggling校正技术

iToF技术中,wiggling是一种校正处理方法。在iToF模组获取深度图后,会进行一系列的补偿和校正处理,wiggling校正就是其中之一。这样的校正处理有助于最终获得更准确的3D数据。 wiggling校正技术有哪些应用场景 wiggling校正技术主要应用在间接飞行时间测量(iToF)装置中,…

【大厂秘籍】 - Java多线程面试题

Java多线程面试题 友情提示,看完此文,在Java多线程这块,基本上可以吊打面试官了 线程和进程的区别 进程是资源分配的最小单位,线程是CPU调度的最小单位 线程是进程的子集,一个进程可以有很多线程,每条线…

分享八个常用的 JavaScript 库

今天给大家分享8个常用的 JavaScript 库,掌握这些 JavaScript 工具库,让你的项目看起来很棒。 专家与普通人的重要区别在于他们善于使用工具,留出更多的时间用于计划和思考。编写代码也是如此。有了合适的工具,你就有更多的时间来…

UDS 诊断通讯

UDS有哪些车型支持 UDS(统一诊断服务)协议被广泛应用于汽车行业中,支持多种车型。具体来说,UDS协议被用于汽车电子控制单元(ECU)之间的通讯,以实现故障诊断、标定、编程和监控等功能。 支持UDS协议的车型包括但不限于以下几种: 奥迪(Audi)车型:包括A3、A4、A5、A6…

239.【2023年华为OD机试真题(C卷)】求幸存者之和(模拟跳数-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-求幸存数之和二.解题思路三.题解代码Python题解…

剑指offer题解合集——Week3day7

文章目录 剑指offerWeek3周七:分行从上往下打印二叉树AC代码思路: 周日:之字形打印二叉树AC代码思路: 剑指offerWeek3 周七:分行从上往下打印二叉树 题目链接:分行从上往下打印二叉树 从上到下按层打印…

JDK8终将走进历史,Oracle宣布JDK继续免费

目录 前言Oracle 已免费提供 JDKOracle Java SE 产品最新动态 为什么业界中用JDK8那么多Java SE 8 公共更新结束总结 前言 今天想到上个月无意中听闻到的一句话:JDK8之后收费了,所以大家都用JDK8。当时只觉得这个话说得不对,但因为和说话的人…

Django数据库选移的preserve_default=False是什么意思?

有下面的迁移命令: migrations.AddField(model_namemovie,namemov_group,fieldmodels.CharField(defaultdjango.utils.timezone.now, max_length30),preserve_defaultFalse,),迁移命令中的preserve_defaultFalse是什么意思呢? 答:如果模型定…

点击随机红点的简单游戏(pygame)

import pygame import sys import random# 初始化 Pygame pygame.init()# 设置窗口大小 width, height 800, 600 screen pygame.display.set_mode((width, height)) pygame.display.set_caption("Click the Red Dot")# 定义颜色 black (0, 0, 0) red (255, 0, 0)…

Apache POI 导出Excel报表

大家好我是苏麟 , 今天聊聊Apache POI . Apache POI 介绍 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。 一般情况下,POI 都是用于操作 E…