【Elasticsearch】打分策略詳解與explain手把手計算

1、目的

一個搜索引擎使用的時候一定須要排序這個模塊,通常狀況下在不選擇按照某一字段排序的狀況下,都是按照打分的高低進行一個默認排序的,因此若是正式使用的話,必須對默認排序的打分策略有一個詳細的瞭解才能夠,不然被問起來爲何這個在前面,那個在後面很差辦,所以對Elasticsearch的打分策略詳細的看了下,雖說還不是瞭解的很所有,可是大部分都看的差很少了,結合理論以及搜索的結果,作一個簡單的介紹html

2、Elasticsearch的打分公式

Elasticsearch的默認打分公式是lucene的打分公式,主要分爲兩部分的計算,一部分是計算query部分的得分,另外一部分是計算field部分的得分,下面給出ES官網給出的打分公式:java

 

[java] view plain copyapp

 

  1. score(q,d)  =    
  2.             queryNorm(q)    
  3.           · coord(q,d)      
  4.           · ∑ (             
  5.                 tf(t in d)     
  6.               · idf(t)²        
  7.               · t.getBoost()   
  8.               · norm(t,d)      
  9.             ) (t in q)      

在此給每個部分作一個解釋elasticsearch

 

queryNorm(q):

對查詢進行一個歸一化,不影響排序,由於對於同一個查詢這個值是相同的,可是對term於ES來講,必須在分片是1的時候纔不影響排序,不然的話,仍是會有一些細小的區別,有幾個分片就會有幾個不一樣的queryNorm值ide

queryNorm(q)=1 / √sumOfSquaredWeights ui

上述公式是ES官網的公式,這是在默認query boost爲1,而且在默認term boost爲1 的狀況下的打分,其中搜索引擎

sumOfSquaredWeights =idf(t1)*idf(t1)+idf(t2)*idf(t2)+...+idf(tn)*idf(tn)spa

其中n爲在query裏面切成term的個數,可是上面所有是在默認爲1的狀況下的計算,實際上的計算公式以下所示:.net

coord(q,d):

coord(q,d)是一個協調因子它的值以下:3d

 

[java] view plain copy

 

  1. coord(q,d)=overlap/maxoverlap  

其中overlap是檢索命中query中term的個數,maxoverlap是query中總共的term個數,例如查詢詞爲「無線通訊」,使用默認分詞器,若是文檔爲「通知他們開會」,只會有一個「通」命中,這個時候它的值就是1/4=0.25

 

tf(t in d):

即term t在文檔中出現的個數,它的計算公式官網給出的是:

 

[java] view plain copy

 

  1. tf(t in d) = √frequency  

即出現的個數進行開方,這個沒什麼能夠講述的,實際打分也是如此

 

idf(t):

這個的意思是出現的逆詞頻數,即召回的文檔在總文檔中出現過多少次,這個的計算在ES中與lucene中有些區別,只有在分片數爲1的狀況下,與lucene的計算是一致的,若是不惟一,那麼每個分片都有一個不一樣的idf的值,它的計算方式以下所示:

 

[java] view plain copy

 

  1. idf(t) = 1 + log ( numDocs / (docFreq + 1))  

其中,log是以e爲底的,不是以10或者以2爲底,這點須要注意,numDocs是指全部的文檔個數,若是有分片的話,就是指的是在當前分片下總的文檔個數,docFreq是指召回文檔的個數,若是有分片對應的也是在當前分片下召回的個數,這點是計算的時候與lucene不一樣之處,若是想驗證是否正確,只需將分片shard的個數設置爲1便可。

 

t.getboost():

對於每個term的權值,沒仔細研究這個項,我的理解的是,若是對一個field設置boost,那麼若是在這個boost召回的話,每個term的boost都是該field的boost

norm(t,d):

對於field的標準化因子,在官方給的解釋是field越短,若是召回的話權重越大,例如搜索無線通訊,一個是很長的內容,但都是包含這幾個字,可是並非咱們想要的,另一個內容很短,可是完整包含了無線通訊,咱們不能由於後面的只出現了一次就認爲權重是低的,相反,權重應當是更高的,其計算公式以下所示:



其中d.getboost代表若是該文檔權重越大那麼久越重要

f.getboost代表該field的權值越大,越重要

lengthnorm表示該field越長,越不重要,越短,越重要,在官方文檔給出的公式中,默認boost所有爲1,在此給出官方文檔的打分公式:

 

[java] view plain copy

 

  1. norm(d) = 1 / √numTerms   

該值在計算的時候老是沒法對上,查詢網上的資料說是在打分的時候將結果先進行壓縮,而後解壓縮,因此結果跟原始值對不上,我的理解有點像量化的過程,由於在實際explain的時候發現該值有必定的規律性

 

3、實際的打分explain

在實際的時候,例如搜索「無線通訊」,以下圖所示,由於一些私人緣由,將一些字段打碼,查詢的時候設置explain爲true,以下圖所示:


 

由於使用的是默認的分詞器,因此最後的結果是將「無線通訊」分紅了四個字,而且認爲是四個term來進行計算,最後將計算的結果進行相加獲得最後的得分0.7605926,這個分數是「無」的得分+「線」的得分+「通」的得分+「信」的得分,四個term的得分以下圖所示:

最後的得分是0.7605926=0.118954286+0.1808154+0.14515185+0.31567,與上述符合,由於四個詞都出現了因此在這裏面的coord=1,總分數的計算知道後,咱們單看每一部分的得分的計算,以「無」爲例進行介紹:

其中每個term內部分爲兩部分的分數,一部分是queryweight,一部分是fieldweight,其中總分數=queryweight*fieldweight

例如此處queryweight=0.51195854,fieldWeight=0.2323514,因此總的分數就是0.118954286

queryweigth計算:

對於queryweight部分的計算分爲兩個部分idf和querynorm,其中idf的值是2.8618271,這個值是如何計算的呢

idf=1+ln(1995/(309+1))=2.8618271,說明在分片四里面共有1995個文檔,召回了包含「無」的309個文檔,所以爲這個值

querynorm部分的計算:根據上面「無」「線」「通」「信」四個的分數計算,能夠看到,idf的值分別爲

無:2.8618271

線:3.1053379

通:2.235371

信:2.901306

因此按照計算公式

 

[java] view plain copy

 

  1. querynorm=1 / √2.8618271*2.8618271+3.1053379*3.1053379+2.235371*2.235371+2.901306*2.901306=0.1788922  

 

因此queryweight部分的值是0.1788922*2.8618271=0.51195854

再次總結下此處的公式:queryweight=idf*queryNorm(d)

fieldweight部分計算:

idf的計算上邊已經算過,在此不詳細敘述

tf的值是在此處出現3次,因此爲√3=1.7320508

fieldnorm的值不知道如何計算,按照公式計算不出來explain的值,網上資料說是編解碼致使的,哪位朋友知道如何計算麻煩回覆下,多謝

總結下fieldweight部分的計算公式:fieldweight=idf*tf*fieldnorm=1.7320508*2.8618271*0.046875=0.2323514

因此整體的計算就是

[java] view plain copy

 

  1. score=queryweight*fieldweight=idf*queryNorm(d)*idf*tf*fieldnorm=coord*queryNorm(d)*tf*idf^2*fieldnorm  

4、參考文檔

http://www.cnblogs.com/forfuture1978/archive/2010/03/07/1680007.html

https://www.elastic.co/guide/en/elasticsearch/guide/current/scoring-theory.html#field-norm

版權聲明:本文爲博主原創文章,轉載請註明出處:http://blog.csdn.net/molong1208 https://blog.csdn.net/molong1208/article/details/50623948

文章標籤: Elasticsearch score explain TFIDF 打分

我的分類: elasticsearch

所屬專欄: Elasticsearch專欄

相關文章
相關標籤/搜索