BM25介绍和代码实现

一、基础介绍

BM25 是一种用来评价搜索词和文档之间相关性的算法。通常用来做搜索相关性评分的,也是ES(弹性搜索)中的搜索算法。通常用来计算搜索和文本集合中每篇文本之间的相关性,并返回对应分数。

二、计算公式

(1) 用Q表示query,在这里Q一般是搜索词条(一个句子)。在此,需要对Q进行语素解析(中文一般是jieba分词),在这里以分词为例,我们对Q进行分词,得到q1,q2,......,qt这样一个词序列。

(2)给定文本d∈D,d属于文档集合中的一个子文档。

(3) 则,基于BM25获得Query与文档集合中d的分数计算表达式如下所示:

上式中,表示的权重,R(,d)为和d的相关性,就是每个词和d的相关性加权和。

(4)针对权值
的计算方法很多,一般用IDF来表示,但这里的IDF计算和上面的有所不同:

其中,表示预料集大小、表示包含词的文档集个数,0.5主要目的是作平滑;

(5)的计算公式

其中,

式子中,为词在文本中出现的频率,为词在中出现的频率,都是可调节的参数(超参),分别为文本的长度和文本集中所有文本的平均长度。

通常,这样可以去除后面一项,将编程:

三、代码实现

参考github代码:https://github.com/dorianbrown/rank_bm25

3.1 库下载

pip install rank_bm25

3.2 库引用

from rank_bm25 import BM25Okapi

3.3 BM25初始化(构建搜索语料库)

from rank_bm25 import BM25Okapi

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

# 分割成字(中文相当于分词)
# "Hello there good man!",=》 ['Hello','there','good','man']
tokenized_corpus = [doc.split(" ") for doc in corpus]

bm25 = BM25Okapi(tokenized_corpus)
# 

3.4 文档搜索得分(新词条搜索)

# 输入Query搜索词条
query = "windy London"

# 分词
tokenized_query = query.split(" ")

# query与每一个语料库文档的得分
doc_scores = bm25.get_scores(tokenized_query)
# array([0.        , 0.93729472, 0.        ])

3.5 文档最高得分n个句子,参数n可以调选择top几数据

bm25.get_top_n(tokenized_query, corpus, n=1)
# ['It is quite windy in London']

3.6 文档最高得分n个句子的id,参数n可以调选择top几数据

scores = self.get_scores(query)
top_n = np.argsort(scores)[::-1][:n]
return top_n

四、缺陷

100W数据3个小时,数据量太大的话,真的很慢!!!

优化选择可以做bm25倒排,或faiss 和局部敏感哈希

五、参考文献

1、https://www.cnblogs.com/jiangxinyang/p/10516302.html
2、https://github.com/dorianbrown/rank_bm25

你可能感兴趣的:(BM25介绍和代码实现)