美文网首页
BM25介绍和代码实现

BM25介绍和代码实现

作者: 骆旺达 | 来源:发表于2021-07-02 19:47 被阅读0次
    一、基础介绍

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

    二、计算公式

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

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

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

    Score(Q,d) = \sum_{i=1}^t w_i * R(q_i,d)

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

    (4)针对w_i权值
    w_i的计算方法很多,一般用IDF来表示,但这里的IDF计算和上面的有所不同:
    w_i = IDF(q_i) = log{\frac {N-n(q_i)+0.5}{n(q_i)+0.5}}

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

    (5)R(q_i,d)的计算公式

    R(q_i,d) = \frac{f_i*(k_1+1)}{f_i+K} * \frac{qf_2 (k_2+1)}{qf_2+k_2}

    其中,K=k_1*(1-b+b*\frac{dl}{artel})

    式子中,f_i为词q_i在文本d中出现的频率,qf_i为词q_iQ中出现的频率,k_1,k_2,b都是可调节的参数(超参),dl,avgdl分别为文本d的长度和文本集D中所有文本的平均长度。

    通常qf_i=1,k_2=0,这样可以去除后面一项,将R(q_i,d)编程:
    R(q_i,d) = \frac{f_i*(k_1+1)}{f_i+K}

    三、代码实现

    参考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)
    # <rank_bm25.BM25Okapi at 0x1047881d0>
    

    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介绍和代码实现

          本文链接:https://www.haomeiwen.com/subject/jqujultx.html