NLP—文本相似度算法BM25

BM25算法,通常用來做檢索相關性評分。首先對一個查詢Query進行分詞得qi,對每個搜索結果文檔d,計算qi與文檔d的相關性得分。最後將所有的qi進行加權求和,從而得到查詢Query與文檔d的相關性得分。


公式中,Q表示查詢Query,qi表示查詢被解析得到的分詞qi,d表示搜索結果文檔d,Wi表示分詞qi的權重,R(qi,d)表示分詞qi與文檔d的相關性得分。定義一個詞與文檔相關性的權重方法有很多,較常用的有IDF。


其中N表示全部文檔數,n(qi)表示包含分詞qi的文檔數,從公式中可以發現當包含分詞qi的文檔數越多時,qi的權重越低,即當很多文檔都有單詞qi時,說明qi比較常用,沒有特別代表意義,所以分詞qi拿來做相關性判斷時重要性比較低。下面是qi與文檔d相關性得分R(qi,d)的計算公式。


式子中,k1、k2、b爲調節因子,通常根據經驗設置爲k1=2,b=0.75,fi爲qi在d中出現的頻率,qfi爲qi在查詢Query中出現的頻率。dl爲文檔d的長度,avgdl爲所有文檔的平均長度。在多數情況下qi只在查詢中出現一次,qfi=1,所以公式簡化爲:


從K的公式中發現,b越大文檔長度對相關性得分的影響也越大,而文檔的長度越長,K越大,則相關性得分越小。所以參數b用來控制文檔長度對相關性得分影響的大小。所以當文檔較長時,包含分詞qi的概率越大,因此同等頻率的情況下,長文檔與qi的相關性不如短文檔與qi的相關性高。綜上BM25文檔相關性計算公式:


def init(self):
        for doc in self.docs:
            tmp = {}
            for word in doc:
                if not word in tmp:
                    tmp[word] = 0
                tmp[word] += 1
            self.f.append(tmp)
            for k, v in tmp.items():
                if k not in self.df:
                    self.df[k] = 0
                self.df[k] += 1
        for k, v in self.df.items():
            self.idf[k] = math.log(self.D-v+0.5)-math.log(v+0.5)
##計算出每個詞的頻次來,然後利用之前的公式計算idf

def sim(self, doc, index):
        score = 0
        for word in doc:
            if word not in self.f[index]:
                continue
            d = len(self.docs[index])
            score += 
            (self.idf[word]*self.f[index][word]*(self.k1+1)/      (self.f[index][word]+self.k1*(1-self.b+self.b*d/ self.avgdl)))

            #利用之前的計算bm25的公式計算。
        return score
def simall(self, doc):#該doc(也就是之前提到的搜索預料)與預保存的文檔)逐個比較相似情況。返回相似值的列別。
        scores = []
        for index in range(self.D):
            score = self.sim(doc, index)
            scores.append(score)
        return scores

參考文檔:https://blog.csdn.net/kamendula/article/details/51756396

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章