【Elasticsearch】打分策略详解与explain手把手计算
一、目的
一個(gè)搜索引擎使用的時(shí)候必定需要排序這個(gè)模塊,一般情況下在不選擇按照某一字段排序的情況下,都是按照打分的高低進(jìn)行一個(gè)默認(rèn)排序的,所以如果正式使用的話,必須對(duì)默認(rèn)排序的打分策略有一個(gè)詳細(xì)的了解才可以,否則被問(wèn)起來(lái)為什么這個(gè)在前面,那個(gè)在后面不好辦,因此對(duì)Elasticsearch的打分策略詳細(xì)的看了下,雖然說(shuō)還不是了解的很全部,但是大部分都看的差不多了,結(jié)合理論以及搜索的結(jié)果,做一個(gè)簡(jiǎn)單的介紹
二、Elasticsearch的打分公式
Elasticsearch的默認(rèn)打分公式是lucene的打分公式,主要分為兩部分的計(jì)算,一部分是計(jì)算query部分的得分,另一部分是計(jì)算field部分的得分,下面給出ES官網(wǎng)給出的打分公式:
?
score(q,d) =
queryNorm(q)
· coord(q,d)
· ∑ (
tf(t in d)
· idf(t)2
· t.getBoost()
· norm(t,d)
) (t in q)
在此給每一個(gè)部分做一個(gè)解釋
?
queryNorm(q):
對(duì)查詢進(jìn)行一個(gè)歸一化,不影響排序,因?yàn)閷?duì)于同一個(gè)查詢這個(gè)值是相同的,但是對(duì)term于ES來(lái)說(shuō),必須在分片是1的時(shí)候才不影響排序,否則的話,還是會(huì)有一些細(xì)小的區(qū)別,有幾個(gè)分片就會(huì)有幾個(gè)不同的queryNorm值
queryNorm(q)=1 / √sumOfSquaredWeights?
上述公式是ES官網(wǎng)的公式,這是在默認(rèn)query boost為1,并且在默認(rèn)term boost為1 的情況下的打分,其中
sumOfSquaredWeights?=idf(t1)*idf(t1)+idf(t2)*idf(t2)+...+idf(tn)*idf(tn)
其中n為在query里面切成term的個(gè)數(shù),但是上面全部是在默認(rèn)為1的情況下的計(jì)算,實(shí)際上的計(jì)算公式如下所示:
coord(q,d):
coord(q,d)是一個(gè)協(xié)調(diào)因子它的值如下:
?
coord(q,d)=overlap/maxoverlap其中overlap是檢索命中query中term的個(gè)數(shù),maxoverlap是query中總共的term個(gè)數(shù),例如查詢?cè)~為“無(wú)線通信”,使用默認(rèn)分詞器,如果文檔為“通知他們開(kāi)會(huì)”,只會(huì)有一個(gè)“通”命中,這個(gè)時(shí)候它的值就是1/4=0.25
?
tf(t in d):
即term t在文檔中出現(xiàn)的個(gè)數(shù),它的計(jì)算公式官網(wǎng)給出的是:
?
tf(t in d) = √frequency即出現(xiàn)的個(gè)數(shù)進(jìn)行開(kāi)方,這個(gè)沒(méi)什么可以講述的,實(shí)際打分也是如此
?
idf(t):
這個(gè)的意思是出現(xiàn)的逆詞頻數(shù),即召回的文檔在總文檔中出現(xiàn)過(guò)多少次,這個(gè)的計(jì)算在ES中與lucene中有些區(qū)別,只有在分片數(shù)為1的情況下,與lucene的計(jì)算是一致的,如果不唯一,那么每一個(gè)分片都有一個(gè)不同的idf的值,它的計(jì)算方式如下所示:
?
idf(t) = 1 + log ( numDocs / (docFreq + 1))其中,log是以e為底的,不是以10或者以2為底,這點(diǎn)需要注意,numDocs是指所有的文檔個(gè)數(shù),如果有分片的話,就是指的是在當(dāng)前分片下總的文檔個(gè)數(shù),docFreq是指召回文檔的個(gè)數(shù),如果有分片對(duì)應(yīng)的也是在當(dāng)前分片下召回的個(gè)數(shù),這點(diǎn)是計(jì)算的時(shí)候與lucene不同之處,如果想驗(yàn)證是否正確,只需將分片shard的個(gè)數(shù)設(shè)置為1即可。
?
t.getboost():
對(duì)于每一個(gè)term的權(quán)值,沒(méi)仔細(xì)研究這個(gè)項(xiàng),個(gè)人理解的是,如果對(duì)一個(gè)field設(shè)置boost,那么如果在這個(gè)boost召回的話,每一個(gè)term的boost都是該field的boost
norm(t,d):
對(duì)于field的標(biāo)準(zhǔn)化因子,在官方給的解釋是field越短,如果召回的話權(quán)重越大,例如搜索無(wú)線通信,一個(gè)是很長(zhǎng)的內(nèi)容,但都是包含這幾個(gè)字,但是并不是我們想要的,另外一個(gè)內(nèi)容很短,但是完整包含了無(wú)線通信,我們不能因?yàn)楹竺娴闹怀霈F(xiàn)了一次就認(rèn)為權(quán)重是低的,相反,權(quán)重應(yīng)當(dāng)是更高的,其計(jì)算公式如下所示:
其中d.getboost表明如果該文檔權(quán)重越大那么久越重要
f.getboost表明該field的權(quán)值越大,越重要
lengthnorm表示該field越長(zhǎng),越不重要,越短,越重要,在官方文檔給出的公式中,默認(rèn)boost全部為1,在此給出官方文檔的打分公式:
?
norm(d) = 1 / √numTerms該值在計(jì)算的時(shí)候總是無(wú)法對(duì)上,查詢網(wǎng)上的資料說(shuō)是在打分的時(shí)候?qū)⒔Y(jié)果先進(jìn)行壓縮,然后解壓縮,所以結(jié)果跟原始值對(duì)不上,個(gè)人理解有點(diǎn)像量化的過(guò)程,因?yàn)樵趯?shí)際explain的時(shí)候發(fā)現(xiàn)該值有一定的規(guī)律性
?
三、實(shí)際的打分explain
在實(shí)際的時(shí)候,例如搜索“無(wú)線通信”,如下圖所示,因?yàn)橐恍┧饺嗽?#xff0c;將一些字段打碼,查詢的時(shí)候設(shè)置explain為true,如下圖所示:
?
因?yàn)槭褂玫氖悄J(rèn)的分詞器,所以最后的結(jié)果是將“無(wú)線通信”分成了四個(gè)字,并且認(rèn)為是四個(gè)term來(lái)進(jìn)行計(jì)算,最后將計(jì)算的結(jié)果進(jìn)行相加得到最后的得分0.7605926,這個(gè)分?jǐn)?shù)是“無(wú)”的得分+“線”的得分+“通”的得分+“信”的得分,四個(gè)term的得分如下圖所示:
最后的得分是0.7605926=0.118954286+0.1808154+0.14515185+0.31567,與上述符合,因?yàn)樗膫€(gè)詞都出現(xiàn)了所以在這里面的coord=1,總分?jǐn)?shù)的計(jì)算知道后,我們單看每一部分的得分的計(jì)算,以“無(wú)”為例進(jìn)行介紹:
其中每一個(gè)term內(nèi)部分為兩部分的分?jǐn)?shù),一部分是queryweight,一部分是fieldweight,其中總分?jǐn)?shù)=queryweight*fieldweight
例如此處queryweight=0.51195854,fieldWeight=0.2323514,所以總的分?jǐn)?shù)就是0.118954286
queryweigth計(jì)算:
對(duì)于queryweight部分的計(jì)算分為兩個(gè)部分idf和querynorm,其中idf的值是2.8618271,這個(gè)值是如何計(jì)算的呢
idf=1+ln(1995/(309+1))=2.8618271,說(shuō)明在分片四里面共有1995個(gè)文檔,召回了包含“無(wú)”的309個(gè)文檔,因此為這個(gè)值
querynorm部分的計(jì)算:根據(jù)上面“無(wú)”“線”“通”“信”四個(gè)的分?jǐn)?shù)計(jì)算,可以看到,idf的值分別為
無(wú):2.8618271
線:3.1053379
通:2.235371
信:2.901306
所以按照計(jì)算公式
?
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
再次總結(jié)下此處的公式:queryweight=idf*queryNorm(d)
fieldweight部分計(jì)算:
idf的計(jì)算上邊已經(jīng)算過(guò),在此不詳細(xì)敘述
tf的值是在此處出現(xiàn)3次,所以為√3=1.7320508
fieldnorm的值不知道如何計(jì)算,按照公式計(jì)算不出來(lái)explain的值,網(wǎng)上資料說(shuō)是編解碼導(dǎo)致的,哪位朋友知道如何計(jì)算麻煩回復(fù)下,多謝
總結(jié)下fieldweight部分的計(jì)算公式:fieldweight=idf*tf*fieldnorm=1.7320508*2.8618271*0.046875=0.2323514
所以總體的計(jì)算就是
score=queryweight*fieldweight=idf*queryNorm(d)*idf*tf*fieldnorm=coord*queryNorm(d)*tf*idf^2*fieldnorm四、參考文檔
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
總結(jié)
以上是生活随笔為你收集整理的【Elasticsearch】打分策略详解与explain手把手计算的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 使用Elasticsearch实现推荐系
- 下一篇: Elasticsearch java a