引言

Okapi BM25,一般简称 BM25 算法,在 20 世纪 70 年代到 80 年代,由英国一批信息检索领域的计算机科学家发明。这里的 BM 是“最佳匹配”(Best Match)的缩写,Okapi 是第一个使用这种方法的信息获取系统的名称。在信息检索领域,BM25 算法是工程实践中举足轻重的重要的 Baseline 算法。迄今为止距 BM25 的提出已经过去三十多年,但是这个算法依然在很多信息检索的任务中表现优异,是很多工程师首选的算法之一。

今天我们就来谈谈 BM25 算法,和它后续的比较重要的推广、变种,以及相关应用实例。

BM25

首先,简单概括 BM25 究竟作何用途。BM25 算法实质上是一个用于信息检索中,对给定查询(query)和若干“相关”文档(document)进行相关性排序打分的排序函数。严格来讲,这不是一个打分函数,而是一个家族的一系列评分函数,因为它的提出并非一蹴而就的事情,它的发明经过了若干试验迭代演进。一般情况下,这个相关性打分是一个类似 TF-IDF 的基于统计计数的无监督学习过程。

BM25 算法其主要思想可简述如下:对 query 进行特征提取分解,生成若干特征项(词)\(q_i\);然后对于每个搜索结果 \(D\),计算每个特征 \(q_i\) 与 \(D\) 的相关性得分,最后,将 \(q_i\) 相对于 \(D\) 的相关性得分进行加权求和,从而得到 query 与 \(D\) 的相关性得分。

BM25 算法的一般表示可简写为如下形式:

\[score(q, d) = \sum_{i} W_i \cdot R(q_i, d)
\]

其中,\(q\) 表示 query, \(q_i\) 表示 \(q\) 分解之后的一个特征项(对中文而言我们可以把对 query 的分词作为基本特征项),\(d\) 表示一个搜索结果文档;\(W_i\) 表示特征 \(q_i\) 的权重;\(R(q_i, d)\) 表示特征项 \(q_i\) 与文档 \(d\) 的相关性得分。

上面这个一般的式子里的 \(W_i\) 和 \(R(q_i, d)\) 的具体计算,都是基于词袋方法的词频计数,它不考虑多个搜索词在文档里的关联性,只考虑它们各自的出现次数。

下面我们来考察以上得分函数的两个量 \(W_i\) 和 \(R(q_i, d)\) 该如何设计和计算。

首先来看如何定义 \(W_i\),考察一个特征词的权重,方法比较多,较常用的是 IDF,BM25 选择的是 Robertson-Sparck Jones IDF:

\[\text{IDF}(q_i) = \log \frac{N - n(q_i) + 0.5}{n(q_i) + 0.5}
\]

其中,\(N\) 为文档集合中的全部文档数,\(n(q_i)\) 为包含 \(q_i\) 的文档数。IDF 公式指出,\(q_i\) 出现在越多的文档中,则 \(q_i\) 的权重则越低。这里个定义有个问题,那就是,如果一个词在超过半数的文档里出现,则 IDF 为负值,于是这个词对 BM25 分数的贡献是负的。一般不希望这样的特性,所以当 IDF 为负数时,可将其置为 \(0\),或者一个比较小的正数,或者改用一种平滑过渡到 \(0\) 的函数形式。

我们再来考察特征项 \(q_i\) 与文档 \(d\) 的相关性得分 \(R(q_i, d)\)。

比较朴素的考虑可以用特征词的文档词频来简单表示 \(R(q_i, d)\),但这种直观的想法不可避免导致长文本中,词的频度普遍较高,最终相关性得分会过度倾向于长文本,显然不尽合理;另一方面,不难想象到,某个词对文档的贡献不应该无限度地随词频增长而线性增加,当该词的词频高于某个程度就应该趋于饱和,而不应该让其得分贡献无限度增大,从而在整个得分求和式子中占支配地位。

基于以上两方面的考虑,BM25 采取了以下方式来计算 \(R(q_i, d)\):

\[R(q_i, d) = \frac{(k_1 + 1) \cdot \tilde{tf}(q_i, d)}{k_1 + \tilde{tf}(q_i, d)}
\]

\[\tilde{tf}(q_i, d) = \frac{tf(q_i, d)}{1+ b(\frac{L_d}{L_{avg}} - 1)}
\]

这里,\(f(q_i, d)\) 为 \(q_i\) 在 \(d\) 中的文档频率,\(L_d\) 为文档长度,\(L_{avg}\) 为文档集合中的平均长度,\(k_1\) 和 \(b\) 为可自由调节的超参数,一般取值范围是 \(k_1 \in [1.2,\;2.0]\),\(b = 0.75\)。\(R(q_i, d)\) 关于 \(\tilde{tf}(q_i, d)\) 的函数是一个“饱和”的递增函数,使得文档词频增长对相关性得分增长成为非线性的。

从 \(\tilde{tf}(q_i, d)\) 的定义中不难看出,超参数 \(k_1\) 起着调节特征词文本频率尺度的作用,\(k_1\) 取 \(0\) 意味着算法退化为二元模型(不考虑词频),而取较大的值则近似于只用原始的特征词频。超参数 \(b\) 一般称作文本长度的规范化,作用是调整文档长度对相关性影响的大小。\(b\) 越大,文档长度的对相关性得分的影响越大,而文档的相对长度越长,\(\tilde{tf}(q_i, d)\) 值将越大,则相关性得分会越小。这可以理解为,当文档相对较长时,包含 \(q_i\) 的机会越大,因此,同等 \(tf(q_i, d)\) 的情况下,长文档与 \(q_i\) 的相关性应该比短文档与 \(q_i\) 的相关性弱。

至此,综合上述讨论,BM25 的一般形式可完整表示如下:

\[score(q, d) = \sum_i \log \frac{N - n(q_i) + 0.5}{n(q_i) + 0.5} \cdot \frac{(k_1 + 1) \cdot tf(q_i, d)}{k_1(1 - b + b\cdot \frac{L_d}{L_{avg}}) + tf(q_i, d)}
\]

此外,若 query 比较长,且某些 term 在 query 中出现频率较高,我们理应考虑这些 term 的重要性也该相应提高,但同样应该有类似 term 相对文档的饱和增长设置来约束 query 中的 term 频率增长。这里我们将类似的权重策略用于 query 中的特征项,得到:

\[score(q, d) = \sum_i \log \frac{N - n(q_i) + 0.5}{n(q_i) + 0.5} \cdot \frac{(k_1 + 1) \cdot tf(q_i, d)}{k_1(1 - b + b\cdot \frac{L_d}{L_{avg}}) + tf(q_i, d)} \cdot \frac{(k_3 + 1)\cdot tf(q_i, q)}{k_3 + tf(q_i, q)}
\]

其中,\(tf(q_i, q)\) 为特征项 \(q_i\) 在查询 \(q\) 中的频率,超参数 \(k_3\) 的作用依然是调节特征词在 query 文本频率尺度,此时对 query 进行长度规范化却是不必要的,因为对所有候选检索结果而言,query 是先有的固定好的。

从以上对 BM25 的完整讨论,我们知道了 BM25 其实是一个(准确说,是一系列)经验公式,这里面的每一个环节都是经过很多研究者的迭代而逐步发现的。很多研究在理论上对 BM25 进行了建模,从“概率相关模型”(Probabilistic Relevance Model)入手,推导出 BM25 其实是对某一类概率相关模型的逼近,对此我还没有详尽研究,就无法进一步展开论述了。从结果上看,我们应该明了 BM25 权重计算公式,已经在众多的数据集和搜索任务上,被极其高频广泛和成功地使用。

BM25 的变种和改进

BM25 算法公式,通过使用不同的特征项的分析方法、特征项权重判定方法,以及特征项与文档的相关度计算方法,都留有较强的灵活性,自然会促使后续的研究者在此基础上,提出更具个性化的不同的搜索相关性得分算法。

所有 BM25 后续改进中,Lv & Zhai 两位研究者的工作最为深入和全面。

  1. BM25L

Lv & Zhai 观察到 BM25 公式中的文本长度规范化项(\(L_d/L_{avg}\))使得模型得分过于偏好长度较短的文档。他们在“When documents are very long, BM25 fails!”一文中提出了 BM25L 算法,用来弥补 BM25 的这一不足。

首先,BM25L 对特征词的 IDF 权重项也做了小小改变,让这一项不会取到负值:

\[\text{IDF}(q_i) = \log \frac{N + 1}{n(q_i) + 0.5}
\]

然而,BM25L 更感兴趣的是调节 BM25 中 \(\tilde{tf}(q_i, d)\) 这一项,以避免算法对过长文本的惩罚。Lv & Zhai 通过对 \(\tilde{tf}(q_i, d)\) 加上一个正值的常数 \(\delta\) 来实现这一点,只需这一个小操作便可以起到让 \(\tilde{tf}(q_i, d)\) 与之前比较,向偏好取更小的值转移(即较大的分母,较长的文本)。

因此,可将 BM25L 算法写作如下:

\[score(q, d) = \sum_i \log \frac{N + 1}{n(q_i) + 0.5} \cdot \frac{(k_1 + 1) \cdot (\tilde{tf}(q_i, d) + \delta )}{k_1 + \tilde{tf}(q_i, d) + \delta}
\]

同 BM25 公式记号保持一致,这里

\[\tilde{tf}(q_i, d) = \frac{tf(q_i, d)}{1+ b(\frac{L_d}{L_{avg}} - 1)}
\]

  1. BM25+

Lv & Zhai 进一步发现对过长文本的惩罚不止出现在 BM25 算法中,还出现在许多其他的排序函数中,他们为此提出了一个一般性的解决方案,即为每一个 query 中出现于文本的特征项相关性得分设置一个下界。此时,不论文本多长,某个搜索特征项至少贡献了一个正的常数相关性得分。他们这个做法略不同于之前的 BM25L,而是在乘 IDF 之前对整个 \(R(q_i, d)\) 加上一个常数 \(\delta\):

\[score(q, d) = \sum_i \log \frac{N + 1}{n(q_i) + 0.5} \cdot \left(\frac{(k_1 + 1) \cdot \tilde{tf}(q_i, d)}{k_1 + \tilde{tf}(q_i, d)} + \delta \right)
\]

  1. BM25-adpt

之前的 BM25 算法和相关改进,都忽略了对超参数 \(k_1\) 的考察。Lv & Zhai 在不同的 BM25 相关研究工作中,发现对实际应用而言,全局的 \(k_1\) 参数不及特征项相关的(term-specific)\(k_1\) 参数使用起来高效。他们用随机理论中的信息增益和散度等概念,实现了 \(k_1\) 去“超参化”的目标,即 \(k_1\) 跟随 term 不同而变化,可以直接计算获得,这个算法被称为 BM25-adpt。BM25-adpt 的具体推导比上面的 BM25 变种算法要稍微复杂一些,要讲清楚其中的想法和细节,需要另辟篇幅,只好以后得空的时候补缀上,这里就不能多加介绍了。

除了以上探讨的几种 BM25 的衍化算法,其他重要的变种还有 BM25T、\(\text{TF}_{1\circ\delta\circ p}\times \text{IDF}\)、BM25F 等等,在许多不同的场景都表现除了优于原始 BM25 算法的效果。当然,这些表现的优越性因具体数据集和相应 search 任务场景而异。

小结

这篇文档相对完整地介绍了信息检索和推荐系统领域的重要相关性打分算法 BM25,以及相关衍生算法。我们了解到,BM25 算法公式由三个主要的模块构成,包括词在文档中相关度、词在查询关键字中的相关度以及词的权重。BM25 即是一个长期积累的经验公式,又有很深的理论支持,是一个简洁高效的基础非监督学习文本排序算法。

参考文献

[1]. wikipedia: Okapi_BM25, https://en.wikipedia.org/wiki/Okapi_BM25.
[2]. Okapi BM25: a non-binary model, https://nlp.stanford.edu/IR-book/html/htmledition/okapi-bm25-a-non-binary-model-1.html.
[3]. Trotman, A., Puurula, A. Burgess, B., Improvements to BM25 and Language Models Examined.
[4]. Lv, Y., C. Zhai, When documents are very long, BM25 fails! SIGIR 2011, p. 1103-1104.
[5]. Lv, Y., C. Zhai, Lower-bounding term frequency normalization, CIKM 2011, p. 7-16.
[6]. Lv, Y., C. Zhai, Adaptive term frequency normalization for BM25, CIKM 2011, p. 1985-1988.

Okapi BM25算法的更多相关文章

  1. Solr相似度算法二:Okapi BM25

    地址:https://en.wikipedia.org/wiki/Okapi_BM25   In information retrieval, Okapi BM25 (BM stands for Be ...

  2. 文本相似度 — TF-IDF和BM25算法

    1,$TF-IDF$算法 $TF$是指归一化后的词频,$IDF$是指逆文档频率.给定一个文档集合$D$,有$d_1, d_2, d_3, ......, d_n \in D$.文档集合总共包含$m$个 ...

  3. 文本相似度-BM25算法

    BM25 is a bag-of-words retrieval function that ranks a set of documents based on the query terms app ...

  4. Project2--Lucene的Ranking算法修改:BM25算法

    原文出自:http://blog.csdn.net/wbia2010lkl/article/details/6046661 1.       BM25算法 BM25是二元独立模型的扩展,其得分函数有很 ...

  5. Okapi BM25 (BM stands for Best Matching)

    Okapi BM25 - Wikipedia https://en.wikipedia.org/wiki/Okapi_BM25 In information retrieval, Okapi BM25 ...

  6. NLP传统基础(1)---BM25算法---计算文档和query相关性

    一.简介:TF-IDF 的改进算法 https://blog.csdn.net/weixin_41090915/article/details/79053584 bm25 是一种用来评价搜索词和文档之 ...

  7. Elastic Stack-Elasticsearch使用介绍(二)

    一.前言     写博客,更要努力写博客! 二.Mapping介绍 Mapping类似于数据库中的表结构的定义:这里我们试想一下表结构定义需要那些: 1.字段和字段类型,在Elasticsearch中 ...

  8. 相关度算法BM25

    BM25算法,通常用来作搜索相关性平分.一句话概况其主要思想:对Query进行语素解析,生成语素qi:然后,对于每个搜索结果D,计算每个语素qi与D的相关性得分,最后,将qi相对于D的相关性得分进行加 ...

  9. ES BM25 TF-IDF相似度算法设置——

    Pluggable Similarity Algorithms Before we move on from relevance and scoring, we will finish this ch ...

随机推荐

  1. vue父子组件之间相互传值

    1. 子组件使用父组件方法,并向父组件传值 子组件代码 <template> <div class="menu"> <div class=" ...

  2. 初涉WebGL

    之前一直在捣鼓Vue和React栈,对组件化架构项目有了些理解和体会.今天尝尝WebGL,当然,并不打算现在深入,只是略作了解,我知道这个坑很深. js的图形库.3d库也有好几款比较流行的,如游戏开发 ...

  3. git init 后关联github仓库是发生错误:

    : failed to push some refs to 'git@github.com:AlanKnightly/reactC.git'hint: Updates were rejected be ...

  4. DOM面试题

    1.利用冒泡和不利用冒泡的差别 答案: 1.绑定位置不同:不利用冒泡绑定在目标元素上,利用冒泡绑定在父元素上. 2.监听对象的个数不同:不利用冒泡会反复创建多个监听,利用冒泡始终只有 一个监听. 3. ...

  5. MySQL常见面试题索引、表设计

    正确使用索引的条件 1.建立索引的列的重复度不能太高 2.条件列不能参与计算 3.不能使用函数 4.条件中不能使用范围 5.不要使用like '%c' 6.条件中用or a=0 or b=1 or c ...

  6. Django操作cookie

    浏览器清空cookie快捷键:ctrl+shift+delete,cookie中包含csrf认证信息 获取Cookie request.COOKIES['key'] request.COOKIES.g ...

  7. 蓝桥杯 试题 历届试题 对局匹配 DP解决

    问题描述 小明喜欢在一个围棋网站上找别人在线对弈.这个网站上所有注册用户都有一个积分,代表他的围棋水平. 小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起.如果两人分差 ...

  8. Poj1753 翻转棋子

    这个题就是用枚举举遍所有情况,然后一个一个深搜看看是不是符合条件,符合条件直接退出,不符合则继续, 由于表格只有16个所以可以得知最多的步数只能是16,所以可以根据步数从0到16依次枚举, 第一个符合 ...

  9. JNPF低代码开发框架代码生成器设计

    1.代码生成器目录下有通用开发模板.单表开发模板.多表开发模板.流程表单模板.移动开发模板等: ①代码生成器录下通用开发模板页面,有搜索.上步.下步.下载代码功能操作: ②输入查询条件表名关键字进行搜 ...

  10. UIAutomator2的API文档(一)

    检查并维持设备端守护进程处于运行状态,应该是重启了atx守护进程:d.healthcheck() 1.隐式等待 import uiautomator2 as u2serialno = '7f3dec6 ...