概述
score在ES中有着很重要的作用,有了它才有了rank,是驗證文檔相關性的關鍵數據,score越大代表匹配到的文檔相關性越大
官方解釋
查詢的時候可以用explain來展示score的計算過程,也可以增加format=yaml來講json轉成yaml方便閱讀
類似xxx/_search?explain&format=yaml
下圖是通過explain看到的一部分json,其實這個解釋中就展示出了計算公式,不得不說ES在這點上還是很人性化的
計算方式
常說的相關性是指計算一個全文(full-text)字段的內容與全文查詢字符串的相似程度的算法。
這個算法默認是BM25,一個基於TF-IDF(term frequency/inverse document frequency)的算法。
TF-IDF
首先是TF(term frequency),顧名思義,term在field出現的頻率越高,則該term與field的相關性越高。
公式:
sqrt(TF)
然后是IDF(inverse document frequency),term在整個index出現的頻率越高,則該term與該document的相關性越低。
公式:
Log(numDocs / docFreq + 1) + 1
BM25
BM全稱(Best Match),這個名稱不得不說有點過分,這個算法也同樣有TF和IDF。
TF,BM25把TF的影響范圍減小了,不像TF-IDF一樣沒有邊界
公式:
(k+1)* tf /(k + tf),k一般是個常量,[1.2,2],通過k可以改變回歸的速度。
IDF幾乎一樣,只是多加了1(為了提高其整體影響比重)
BM25新加了另一個特征,Field-length norm,field的長度有多少,如果field的長度越長,則該term與field的相關性越低(分母越大,概率越小)。
公式:
|d|/avgDl(本文檔的長度除以平均文檔的長度)
下圖為不同文檔長度對應相同tf所影響最終tf的曲線。
公式:
(k + 1)* tf / k * ( 1.0 - b + b - L + tf) (其中b為常數)
BM25 Field-length norm之間的對比
TF-IDF和BM25對比
在TF角度的對比
計算流程
Score的計算過程依賴query clause(查詢子條件),例如:
1.模糊查詢計算匹配到的word和原來的word(匹配前的word)的相似度
2.term查詢會包含找到該term所占的百分比
個別查詢會結合TF-IDF的socre和其它因素,越多的query clause(查詢子條件)匹配到,那么score就越高,具體來說,是query clause匹配得到的score聯合起來計算出最終的score。
需要注意的是,TF-IDF默認是基於shard來計算的,假設1個index有5個shards,則就有5個TF-IDF的結果,也就是5個score,然后score再匯聚到request node,做排序后得到最終結果。所以這有產生了另一個問題,當index的documents數量較少時,score的結果會不准確,畢竟不是全局的,shard也只是通過hash來區分,有很大的隨機性和偶然性。針對這種情況,ES給出了DFS Query Then Fetch(默認是采用Query Then Fetch)這種解決方案,采用全局計算TF-IDF的方式,解決這個問題,在查詢的時候可以這么設置
search_type=dfs_query_then_fetch
(不過會影響效率,畢竟是全局計算,多了幾次socket傳輸)。其實還有一種解決方法,直接把index的shard設置成1,這樣自己就代表了全局。
Query Then Fetch
稍微解釋一下Query Then Fetch,顧名思義,是先查詢后獲取。
查詢流程如下
score as percentage
剛接觸score的時候,總有疑惑,為什么不是一個百分比,這樣可能更加直觀的表現出匹配到正確的概率,也就是術語”normalized socre”。
這么想是錯誤的!
Score的意義僅僅在於對比一次查詢的多個結果的對比,起到rank作用,並不能代表匹配到的概率,更不能拿幾個匹配到的概率做比較,比如:當一個document本身沒有發生變化,但是index發生變化,就會影響匹配到document的sorce。這樣的概率是沒什么意義的,雖然你可以強行造出一個概率。
另外
在做業務的過程中領悟到,搜索系統和推薦系統不是一個系統(之前沒想過這個問題),重要區別之一就是主動和被動,詳細看這篇博客吧,說的很詳細了
http://blog.csdn.net/cserchen/article/details/50422553
參考資料
//官方對相關性的解釋,也就是score的計算標准
https://www.elastic.co/guide/en/elasticsearch/guide/master/relevance-intro.html
//當你的數據很少時,請用DFS Query Then Fetch搜索方法
https://www.elastic.co/blog/understanding-query-then-fetch-vs-dfs-query-then-fetch
//ES的兩個搜索方法
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-search-type.html
//ES官方解釋的BM25和TF-IDF區別
https://www.elastic.co/blog/found-similarity-in-elasticsearch
//外國友人對BM25和TF-IDF的解讀
http://opensourceconnections.com/blog/2015/10/16/bm25-the-next-generation-of-lucene-relevation/
//外國友人吐槽 當score變成percentage的后果