搜索算法相似度问题之BM25
在實踐中,無論是搜索問題,還是文本問題,如何找到相似的文本都是一個常見的場景,但TFIDF文本相似度計算用多了,年輕人往往會不記得曾經的經典。
畢業快4年了,最近準備梳理一下《我畢業這4年》,在整理文檔時看到了好久之前的一個比賽,想起了當時TFIDF、BERT的方案都沒在指標上贏過BM25的情景,本期我們來聊一聊相似文本搜索的相關知識點。
BM25是信息索引領域用來計算Query與文檔相似度得分的經典算法,不同于TFIDF,BM25的公式主要由三個部分組成:
- 對Query進行語素解析,生成語素qi;
- 對于每個搜索結果D,計算每個語素qi與D的相關性得分;
- 將qi相對于D的相關性得分進行加權求和,從而得到Query與D的相關性得分。
公式如下:
其中,Q表示Query,qi表示Q解析之后的一個語素,d表示一個搜索結果文檔,Wi表示語速qi的權重,R(qi,d)表示語素qi與文檔d的相關性得分。
class BM25:def __init__(self, corpus, tokenizer=None):self.corpus_size = len(corpus)self.avgdl = 0self.doc_freqs = []self.idf = {}self.doc_len = []self.tokenizer = tokenizerif tokenizer:corpus = self._tokenize_corpus(corpus)nd = self._initialize(corpus)self._calc_idf(nd)def _initialize(self, corpus):nd = {} # word -> number of documents with wordnum_doc = 0for document in corpus:self.doc_len.append(len(document))num_doc += len(document)frequencies = {}for word in document:if word not in frequencies:frequencies[word] = 0frequencies[word] += 1self.doc_freqs.append(frequencies)for word, freq in frequencies.items():try:nd[word]+=1except KeyError:nd[word] = 1self.avgdl = num_doc / self.corpus_sizereturn nddef _tokenize_corpus(self, corpus):pool = Pool(cpu_count())tokenized_corpus = pool.map(self.tokenizer, corpus)return tokenized_corpusdef _calc_idf(self, nd):raise NotImplementedError()def get_scores(self, query):raise NotImplementedError()def get_batch_scores(self, query, doc_ids):raise NotImplementedError()def get_top_n(self, query, documents, n=5):assert self.corpus_size == len(documents), "The documents given don't match the index corpus!"scores = self.get_scores(query)top_n = np.argsort(scores)[::-1][:n]return [documents[i] for i in top_n]在這里,用自己之前寫過的一個真實案例,來介紹一下。任務提供一個論文庫(約含20萬篇論文),同時提供對論文的描述段落,來自論文中對同類研究的介紹。任務需要為描述段落匹配三篇最相關的論文。
1.2 任務描述
本次比賽將提供一個論文庫(約含20萬篇論文),同時提供對論文的描述段落,來自論文中對同類研究的介紹。參賽選手需要為描述段落匹配三篇最相關的論文。
例子:
描述段落:
An efficient implementation based on BERT [1] and graph neural network (GNN) [2] is introduced.
相關論文:
[1] BERT: Pre-training of deep bidirectional transformers for language understanding.
[2] Relational inductive biases, deep learning, and graph networks.
1.3 評測方案
準確率(Precision): 提交結果的準確性通過 Mean Average Precision @ 3 (MAP@3) 打分,具體公式如下:
其中,|U|是需要預測的press_id總個數,P(k)是在k處的精度,n是paper個數。
2 題意分析
從任務描述中我們可以看到,該任務需要對描述段落匹配三篇最相關的論文。單從形式上可以理解為這是一個“完形填空”任務。但相較于在本文的相應位置上填上相應的詞語不同的是,這里需要填充的是一個Sentence,也就是論文的題目。但是如果你按照這個思路去尋求解決方案,你會發現在這個量級的文本數據上,一般算力是滿足不了的。
既然如此,那我們不如換一個思路來思考這個問題,“對描述段落匹配三篇最相關的論文”,其實最簡單的實現方式是計算描述段落和論文庫里所有論文的相似度,找出最相似的即可。但這同樣會存在一個問題,通過對數據進行探查你會發現“An efficient implementation based on BERT [1] and graph neural network (GNN) [2] is introduced.”這一描述段落,同時引用了兩篇文章,那么在計算相似度時,到底哪個位置該是哪篇文章呢?
基于分析中提到的問題和難點,本次比賽給出了以下解決方案。
3 建模核心思路
在解決本問題時,使用了兩種方式,其一是利用Wrod2Vec方法,將描述段落利用Word2Vec得到每個詞的詞向量,同時對句子中的詞使用IDF為權重進行加權得到Sentence Embedding,同時為了得到更好的效果,這里做了一個改進,即使用Smooth Inverse Frequency代替IDF作為每個詞的權重;其二是利用BM25得到Sentence Embedding。兩種方法各自計算余弦相似度得到3篇論文,去重后召回集中每個段落有3-6篇不等的召回論文。
在排序階段,我們利用Bi-LSTM對描述段落Description和論文文本PaperText組成句子對(Description,PaperText)進行編碼,在中間層對兩個向量進行差值和內積操作后,在輸出層經過Dense和Softmax層后得到概率值后排序。
4 算法核心思想
4.1 SIF Sentence Embedding
SIF Sentence Embedding 使用預訓練好的詞向量,使用加權平均的方法,對句子中所有詞對應的詞向量進行計算,得到整個句子的embedding向量。
SIF 的計算分為兩步:
1) 對句子中的每個詞向量,乘以一個獨特的權重b,權重b是一個常數 a除以a與該詞頻率的和,這種做法的會對出現頻率高詞進行降權,也就是說出現頻次越高,其權重也就越小;
2) 計算句向量矩陣的第一主成分u,讓每個Sentence Embedding減去它在u上的投影,具體參見論文[2];
這里,利用該方法做召回,在驗證集上的準確性要比其他兩種方式效果好。
(1)對句子中所有單詞求平均得到sentence embedding;
(2)對句子中所有單詞利用IDF值加權后求平均得到sentence embedding。
4.2 InferSent
InferSent相似度模型是Facebook提出了一種通過不同的encoder得到Sentence Embedding,然后計算兩個Sentence Embedding的差值、點乘得到交互向量,計算兩者之間的相似度。
這里,對原始論文方法做了兩處修改:
其一是針對這個問題對3-way softmax層(entailment,contradiction,neutral)做了相應的修改變為2-way softmax;
其二是中間層去掉了u和v,只使用差值和內積兩種特征表征方式;
同時在7中編碼器:1)LSTM, 2)GRU, 3)bi-GRU, 4)bi-LSTM(mean pooling), 5)bi-LSTM(max pooling), 6)self-attention, 7)CNN 中選用了Bi-LSTM MaxPooling的方式。
4.3 Others-BERT
當時,在BERT時代,解決方案的嘗試中少不了它的身影,這里我們用BERT嘗試了兩種方案,其一是利用BERT對Description和PaperText進行編碼后,計算文本的余弦相似度;其二是在上述整體模型中,用BERT替換InferSent部分。
參考文獻:
[1] Sanjeev Arora, Yingyu Liang, Tengyu Ma. A Simple but Tough-to-Beat Baseline for Sentence Embeddings, ICLR 2017
[2] Conneau A , Kiela D , Schwenk H , et al. Supervised Learning of Universal Sentence Representations from Natural Language Inference Data[J]. 2017.
[3] Devlin J , Chang M W , Lee K , et al. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding[J]. 2018.
總結
以上是生活随笔為你收集整理的搜索算法相似度问题之BM25的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: No Fine-Tuning, Only
- 下一篇: Prompt-Tuning这么好用?