說明:本文章使用的ES版本是:6.2.4
html
在上一篇文章Elasticsearch搜索過程詳解中,介紹了ES的搜索過程。git
接下來咱們具體的看一下ES搜索時,是如何計算文檔相關性得分並用於排序的。github
在介紹ES計算文檔得分以前,先來看一下TF-IDF
算法。算法
TF-IDF
(Term Frequency–Inverse Document Frequency)是一種用於信息檢索與文本挖掘的經常使用加權算法。它是一種統計方法,用以評估一字詞對於一個文件集或一個語料庫中的其中一份文件的重要程度。字詞的重要性隨着它在文件中出現的次數成正比增長,但同時會隨着它在語料庫中出現的頻率成反比降低。apache
TF-IDF
其實是兩個算法TF
和IDF
的乘積。api
詞頻的所在對象是一個具體的文檔,是指一個文檔中出現某個單詞(Term)的頻率(Frequency)。這裏用的是頻率而不是次數,是爲了防止文檔內容過長從而致使某些單詞出現過多。爲了正確評價一個單詞在一個文檔中的重要程度,須要將出現次數歸一化,其算法以下:搜索引擎
$$ tf_i=\frac{n_i}{\sum\nolimits_{k=1}^nn_k} $$人工智能
上面式子中n_i
是該詞在文件中的出現次數,而分母code
$$ \sum _{k=1}^nn_k $$orm
則是在文件中全部字詞的出現次數之和。
逆向文件頻率描述的對象是一個文檔集合中,包含某個單詞的文檔數量。它表示的是一個單詞在一個文檔集合中的廣泛重要程度。將其歸一化的算法入下:
$$ {idf_{i}} =\lg {\frac {|D|}{1+|\{j:t_{i}\in d_{j}\}|}} $$
其中
t_i
的文件數目(即n_i≠0
的文件數目)若是詞語不在數據中,就致使分母爲零,所以通常狀況下使用分母加了一個1最後
$$ tfidf_i=tf_i\times idf_i $$
某一特定文件內的高詞語頻率,以及該詞語在整個文件集合中的低文件頻率,能夠產生出高權重的tf-idf。所以,tf-idf傾向於過濾掉常見的詞語,保留重要的詞語。
用上面的公式,計算一個例子。
假如一篇文件的總詞語數是100個,而詞語「學校」出現了5次,那麼「學校」一詞在該文件中的詞頻(tf)就是
$$ tf_i=5/100=0.05 $$
「學校」一詞在1,000份文件出現過,而文件總數是1,000,000份的話,其逆向文件頻率就是
$$ idf_i = lg(1,000,000 / 1,000)=3 $$
最後的tf-idf的分數爲
$$ tfidf_i = tf_i\times idf_i = 0.05 \times 3= 0.15 $$
BM25(Best Match25)是在信息檢索系統中根據提出的query對document進行評分的算法。
TF-IDF
算法是一個可用的算法,但並不太完美。它給出了一個基於統計學的相關分數算法,而BM25算法則是在此之上作出改進以後的算法。(爲何要改進呢?TF-IDF
不完美的地方在哪裏?)
TF-IDF
算法,A的tf
得分是:0.01,B的tf
得分是0.02。得分上B比A多了一倍,可是兩篇文章都是再說人工智能,tf
分數不該該相差這麼多。可見單純統計的tf
算法在文本內容多的時候是不可靠的tf
算法的結果也影響很大,因此須要將文本的長度也考慮到算法當中去基於上面兩點,BM25算法作出了改進,最終該算法公式以下:
$$ {\displaystyle {\text{score}}(D,Q)=\sum _{i=1}^{n}{\text{IDF}}(q_{i})\cdot {\frac {f(q_{i},D)\cdot (k_{1}+1)}{f(q_{i},D)+k_{1}\cdot \left(1-b+b\cdot {\frac {|D|}{\text{avgdl}}}\right)}}} $$
其中:
q_{i}
在文檔集合Q的IDF值q_{i}
在文檔D中的TF值注:ES版本6.2.4所用的Lucene jar包版本是:7.2.1
在瞭解了TF-IDF
算法以後,再來了解Lucene中的相關性算法就很好理解了。
Lucene中,相關性算法以下:
$$ score(t, q, d)={\sum\nolimits_{t}^n (idf(t) * boost(t) * tfNorm(t, d))} $$
其中:
score(t, q, d)
:表示包含查詢詞t的文檔d在文檔集合q中的相關性得分idf(t)
:逆向文件頻率,ES中,逆向文件頻率的算法是:$$ {idf_{t}} =\ln {(1 + \frac {docCount-docFreq+0.5}{docFreq+0.5})} $$
docCount:表示文檔總數,docFreq:表示包含單詞t的文檔數量。
boost(t)
:查詢時,指定的單詞的權重,不指定時爲1tfNorm(t, d)
:單詞頻率權重,它用BM25替代了簡單的TF算法,ES中,其算法以下:$$ {\displaystyle {\text{tfNorm}}(t,d)={\frac {f(t, d)\cdot (k_{1}+1)}{f(t, d)+k_{1}\cdot \left(1-b+b\cdot {\frac {|D|}{\text{avgdl}}}\right)}}} $$
tfNorm(t, d)
:單詞t在文檔d中的頻率權重f(t, d)
:單詞t在文檔d中的出現次數ES在搜索過程當中,拿到文檔ID以後,就會根據搜索詞,計算每篇文檔的相關性得分,用其進行排序。
參考資料: