BM25

简介

从Elasticsearch 5开始,Elasticsearch的默认相似度算法是Okapi BM25。Okapi BM25模型于1994年提出,BM25的BM是缩写自Best Match, 25是经过25次迭代调整之后得出的算法,该模型也是基于TF/IDF进化来的,Okapi信息检索系统是第一个实现此功能的系统,之后被广泛应用在不同系统里。

原理

BM25算法是一种计算句子与文档相关性的算法,它的原理十分简单:将输入的句子sentence进行分词,然后分别计算句子中每个词word与文档doc的相关度,然后进行加权求和。得到句子与文档的相关度评分。评分公式如下:
\(\operatorname{Score}(\mathrm{Q}, \mathrm{d})=\sum_{\mathrm{i}}^{\mathrm{n}} \mathrm{W}_{\mathrm{i}} \mathrm{R}\left(\mathrm{q}_{\mathrm{i}}, \mathrm{d}\right)\)
其中\(W_i\)是单词\(q_i\)的idf数值,表示权重;\(R(q_i, d)\)表示单词\(q_i\)与文档d的相关性。下面分别介绍这两个数值是如何计算的。

IDF

IDF:Inverse Document Frequency,表示逆文档频率。直观理解就是单词在越多文档出现,表示该单词越平凡,因此权重越低。
\(\operatorname{IDF}\left(\mathrm{q}_{\mathrm{i}}\right)=\log \left(\frac{\mathrm{N}-\mathrm{n}\left(\mathrm{q}_{\mathrm{i}}\right)+0.5}{\mathrm{n}\left(\mathrm{q}_{\mathrm{i}}\right)+0.5}\right)\)

其中\(n(q_{i})\)表示包含\(q_i\)的文档个数,N表示文档总数。

相关性

相关性得分的一般性公式如下:
\(R\left(q_{i}, d\right)=\frac{f_{i} \cdot\left(k_{1}+1\right)}{f_{i}+K} \cdot \frac{\mathrm{qf}_{i} \cdot\left(k_{2}+1\right)}{q_{f_{i}}+k_{2}}\)
\(\mathrm{K}=\mathrm{k} 1 \cdot\left(1-\mathrm{b}+\mathrm{b} \cdot \frac{\mathrm{dl}}{\mathrm{avgdl}}\right)\)
其中\(k_1, k_2, b\)为超参数,一般设置\(k_1 = 2, b = 0.75\)\(f_i\)表示\(q_i\)在文档d中的频率,\(qf_i\)表示\(q_i\)在sentence中的频率,dl表示d的长度。
一般单词仅在sentence中出现一次,因此\(qf_i\)均相等,于是可以将第二项等价为1。

因此综合来看,BM25得分计算方式如下:
\(\operatorname{Score}(Q, d)=\sum_{i}^{n} \operatorname{IDF}\left(q_{i}\right) \cdot \frac{f_{i} \cdot\left(k_{1}+1\right)}{f_{i}+k_{1} \cdot\left(1-b+b \cdot \frac{d l}{\operatorname{avgdl}}\right)}\)
单词越独特,idf数值越高->bm25得分越高
待匹配的文档越短,相关性越高->bm25得分越高

实现

from rank_bm25 import BM25Okapi

corpus = [
    "Hello there good man!",
    "It is quite windy in London",
    "How is the weather today?"
]

tokenized_corpus = [doc.split(" ") for doc in corpus]

bm25 = BM25Okapi(tokenized_corpus)
# <rank_bm25.BM25Okapi at 0x1047881d0>

query = "windy London"
tokenized_query = query.split(" ")

doc_scores = bm25.get_scores(tokenized_query)
# array([0.        , 0.93729472, 0.        ])

bm25.get_top_n(tokenized_query, corpus, n=1)
# ['It is quite windy in London']
posted @ 2022-11-22 20:10  hyserendipity  阅读(239)  评论(0编辑  收藏  举报