从TF-IDF 到BM25, BM25+,一文彻底理解文本相关度
相关性描述的是⼀个⽂档和查询语句匹配的程度。我们从搜索引擎召回时,肯定希望召回相关性高的数据,那么如何来量化相关度呢。
首先,我们定义,一个文档doc,由多个词语 term 组成。
最早,通过最简单的TF-IDF来衡量。
TF-IDF
朴素的思想,相关度应该是词语权重、文档权重的融合。
- 词频 TF(Term Frequency)朴素的理解,一个词语term在一个doc中出现的频率越高,那么doc的相关性也越高。
$$ \text{TF}(t, d) = \frac{\text{词t在文档d中的出现次数}}{\text{文档d的总词数}} $$
- 逆向文档频率 IDF(Inverse Document Frequency),通俗的解释每个检索词在索引中出现的频率,频率越高,相关性越低。 比如"的“ 这样的词语,可能每个doc都有,相反一些专业术语出现的文档数很少,这些文档的权重就很高。
$$ \text{IDF}(t, D) = \log\left(\frac{\text{文档集合D的总文档数}}{\text{包含词t的文档数} + 1}\right) $$
- TF和IDF结合起来计算一个词的TF-IDF值,公式为:
$$ \text{TF-IDF}(t, d, D) = \text{TF}(t, d) \times \text{IDF}(t, D) $$
TF-IDF的优点在于简单有效,但它也有一些局限性,例如不考虑词序和上下文信息。
BM25(Best Matching 25)
BM25是一种用于文本信息检索的算法,是BM(Best Matching)系列中的一员。它在信息检索领域中广泛应用,特别是在搜索引擎中用于排序搜索结果。整体而言BM25 就是对 TF-IDF 算法的改进**,以下是BM25算法的公式:
$$ \text{BM25}(D, Q) = \sum_{i=1}^{n} \frac{{(k+1) \cdot f_i}}{{f_i + k \cdot (1 - b + b \cdot \frac{{\lvert D \rvert}}{{\text{avgdl}}})}} \cdot \log\left(\frac{{N - n_i + 0.5}}{{n_i + 0.5}}\right) $$
- D:文档
- Q:查询
- n:查询中的term数
- N:文档集中的文档数
- fi:文档中term i的频率
- ni:包含术语 term i 的文档数
- DL:文档长度(term数)
- AVG_DL:文档集的平均长度(term数量)
对于 TF-IDF 算法,TF(t) 部分的值越大,整个公式返回的值就会越大,如果一个doc文章很长,词语很多,tf频率就会很大。BM25 针对这个问题做了优化,通过b参数,对文档长度进行打压,随着TF(t) 的逐步加大,该算法的返回值会趋于一个数值。

BM25的优势在于它对于长文本和短文本的处理更为灵活,并且能够适应不同查询的特征。这些可调整的参数使得BM25能够通过调整来适应不同的信息检索场景。
b 参数 ,b 默认 0.75(经验值),主要是对长文档做惩罚,如果不希望文档长度更大的相似度搜索更好,可以把 b 设置得更大,如果设置为 0,文档的长度将与分数无关。从下图可以看到,b=0时,L与分数无关,b=1时,L越大,分数打压越厉害。

k 参数, 默认值 1.2,会影响词语在文档中出现的次数对于得分的重要性,如果希望词语出现次数越大,文档越相关,这个参数可以设置更大。
BM25+
BM只考虑了term和doc的维度,对query 里term的频率没有考虑,BM25+(Best Matching 25 Plus)正是基于这一点,来改进BM25算法,以下是BM25+的公式,以及每个参数的含义:
$$ \text{BM25+}(D, Q) = \sum_{i=1}^{n} \frac{{(k_1+1) \cdot f_i \cdot (k_3+1) \cdot qf}}{{(f_i + k_1 \cdot (1 - b + b \cdot \frac{{\lvert D \rvert}}{{\text{avgdl}}})) \cdot (k_3 + qf)}} \cdot \log\left(\frac{{N - n_i + 0.5}}{{n_i + 0.5}}\right) $$
相比BM25,增加k3 和qf,
其中:
- qf:查询中词项的频率(Query Term Frequency)
- k3:控制查询中词项频率对得分的影响程度的参数,下面是不同的k3,在不同的query weight情况下,对分数的影响
![[Pasted image 20240202151809.png]]
- 注意k1就是BM25里的k
这里的qf,我们可以当做term weight来使用,训练term weight模型,来对重点的term做激励。
谷歌的End-to-End Query Term Weighting
谷歌在2023年发布了一篇论文,介绍如何端到端学习term weighting。
背景是term based recall的方法相对于embedding recall来说很繁琐,好处就是时延低且对基建要求低,向量召回会遇到分不清楚query中哪个词是核心词的问题,导致召回出现了非核心词的结果。
谷歌论文

在左侧,展示了传统的信息检索(IR),所有的term都是默认的权重,在右侧,我们插入了一个BERT模型来评估term的权重,BM25+ 打分时将这个weighting作为query freq,就是上面说的qf。
可以看谷歌论文的打分:

上面的$f(T_i, T,w)$ 就是模型学习的权重。
附录
可视化不同参数变化,BM25分数的变化
import numpy as np
import matplotlib.pyplot as plt
def calculate_bm25(tf, term_weight, corpus_freq, total_docs,
k1=1.5, k3=8, doc_len=100, avg_doc_len=120, b=0.75):
idf = np.log((total_docs - corpus_freq + 0.5) / (corpus_freq + 0.5) + 1) # IDF计算
K = k1 * ((1.0 - b) + b * doc_len / avg_doc_len + tf)
tf_term = tf * (k3 + 1) * term_weight / (K * (k3 + term_weight)) # TF计算
return idf * tf_term # BM25计算
def visualize_bm25_scores_k3(term_weight_values, tf_values, corpus_freq, total_docs, k1=1.5):
# Plotting
plt.figure(figsize=(12, 8))
for k3 in np.linspace(2, 10, 5):
scores = [calculate_bm25(5, query_weight, corpus_freq, total_docs, k1=k1, k3=k3)
for query_weight in term_weight_values]
plt.plot(term_weight_values, scores, label=f'k3={k3}')
plt.title('BM25 Scores with Different Query_freq Values (b=0)')
plt.xlabel('Query weight')
plt.ylabel('BM25 Score')
plt.legend()
plt.show()
def visualize_bm25_scores_b(term_weight_values, tf_values, corpus_freq, total_docs, k1=1.5):
# b 用于惩罚文档长度
plt.figure(figsize=(12, 8))
doc_lens = np.linspace(100, 1000, 10)
avg_doc_len = 100
L = [doc_len /avg_doc_len for doc_len in doc_lens]
for b in [0, 0.5, 0.75, 1.0]:
scores = [calculate_bm25(5, 1, corpus_freq, total_docs, k1=k1, b=b, doc_len=doc_len)
for doc_len in doc_lens]
plt.plot(L, scores, label=f'b={b}')
plt.title('BM25 Scores with Different b')
plt.xlabel('L(doc_length/avg_doc_length')
plt.ylabel('BM25 Score')
plt.legend()
plt.show()
term_weight_values = np.linspace(0.1, 10, 10) # query weight
corpus_freq = 500 # 包含term的文档数量,文档频率
total_docs = 5000000 # 总文档数量
tf_values = list(range(1, 101))
visualize_bm25_scores_k3(term_weight_values, tf_values, corpus_freq, total_docs)
visualize_bm25_scores_b(term_weight_values, tf_values, corpus_freq, total_docs)
从TF-IDF 到BM25, BM25+,一文彻底理解文本相关度的更多相关文章
- TF/IDF(term frequency/inverse document frequency)
TF/IDF(term frequency/inverse document frequency) 的概念被公认为信息检索中最重要的发明. 一. TF/IDF描述单个term与特定document的相 ...
- tf–idf算法解释及其python代码实现(下)
tf–idf算法python代码实现 这是我写的一个tf-idf的简单实现的代码,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四 ...
- tf–idf算法解释及其python代码实现(上)
tf–idf算法解释 tf–idf, 是term frequency–inverse document frequency的缩写,它通常用来衡量一个词对在一个语料库中对它所在的文档有多重要,常用在信息 ...
- 文本分类学习(三) 特征权重(TF/IDF)和特征提取
上一篇中,主要说的就是词袋模型.回顾一下,在进行文本分类之前,我们需要把待分类文本先用词袋模型进行文本表示.首先是将训练集中的所有单词经过去停用词之后组合成一个词袋,或者叫做字典,实际上一个维度很大的 ...
- 信息检索中的TF/IDF概念与算法的解释
https://blog.csdn.net/class_brick/article/details/79135909 概念 TF-IDF(term frequency–inverse document ...
- Elasticsearch学习之相关度评分TF&IDF
relevance score算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度 Elasticsearch使用的是 term frequency/inverse doc ...
- 55.TF/IDF算法
主要知识点: TF/IDF算法介绍 查看es计算_source的过程及各词条的分数 查看一个document是如何被匹配到的 一.算法介绍 relevance score算法,简单来说 ...
- Elasticsearch由浅入深(十)搜索引擎:相关度评分 TF&IDF算法、doc value正排索引、解密query、fetch phrase原理、Bouncing Results问题、基于scoll技术滚动搜索大量数据
相关度评分 TF&IDF算法 Elasticsearch的相关度评分(relevance score)算法采用的是term frequency/inverse document frequen ...
- tf–idf算法解释及其python代码
tf–idf算法python代码实现 这是我写的一个tf-idf的简单实现的代码,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四 ...
- 基于TF/IDF的聚类算法原理
一.TF/IDF描述单个term与特定document的相关性TF(Term Frequency): 表示一个term与某个document的相关性. 公式为这个term在document中出 ...
随机推荐
- Vue-pdf实现在线预览PDF文件
前言 在大多数项目中都会遇到在线预览PDF文件,项目使用的是element ui,使用vue-pdf实现. 安装依赖 npm install --save vue-pdf 相关参数 参数介绍: url ...
- LLM面面观之Prefix LM vs Causal LM
1. 背景 关于Prefix LM和Causal LM的区别,本qiang在网上逛了一翻,发现多数客官只给出了结论,但对于懵懵的本qiang,结果仍是懵懵... 因此,消遣了多半天,从原理及出处,交出 ...
- Meta AI新发布的超大规模语言模型-OPT-175B
Meta AI在2022年5月3日新发布的OPT-175B模型,该模型是现阶段第一个模型参数超过千亿级别的开放模型,其次该模型与GPT-3相比,更加开放及便于访问. 具体开放性表现在如下几个方面: ...
- APB Slave设计
APB Slave位置 实现通过CPU对于APB Slave读写模块进行读写操作 规格说明 不支持反压,即它反馈给APB的pready信号始终为1 不支持错误传输,就是说他反馈给APB总线的PSLVE ...
- 2. 成功使用SQL Plus完成连接,但在使用Oracle SQL Developer连接时,发生报错ORA-12526: TNS:listener: all appropriate instances are in restricted mode
经了解后得知,错误原因:ORA-12526: TNS: 监听程序: 所有适用例程都处于受限模式. 解决办法:使用系统管理员身份运行以下一段代码 ALTER SYSTEM DISABLE RESTRIC ...
- [转帖]查看oracle中表的索引
oracle中表的索引信息存在 user_indexes 和 user_ind_columns 两张表里面,其中 user_indexes 系统视图存放是索引的名称以及该索引是否是唯一索引等信息, u ...
- [转帖]ESX/ESXi 主机上的每个插槽中安装了多少内存
https://www.cnblogs.com/reachos/p/11242302.html 要确定在 ESX/ESXi 主机上的每个插槽中安装了多少内存,请执行以下操作: 1. 启动ssh服务 2 ...
- 【转帖】读懂什么是RDMA
一.什么是RDMA1.RDMA主要体现 2.如何理解RDMA和TCP技术的区别?3.使用RDMA的好处包括: 二.什么是RoCE?1. RDMA协议包含:Infiniband(IB)2. 为什 ...
- [转帖]nginx的luajit安装luarocks并安装luafilesystem
nginx的luajit安装luarocks并安装luafilesystem by admin on 2015-07-11 08:05:23 in , 69次 标题有点绕口.我尽量把关键词都贴进去.之 ...
- mysql8 部分信息总结
0. 我这边环境需要的配置参数 datadir=/var/lib/mysqlsocket=/var/lib/mysql/mysql.socklog-error=/var/log/mysqld.logp ...