一、目的
一個(gè)搜索引擎使用的時(shí)候必定需要排序這個(gè)模塊氓奈,一般情況下在不選擇按照某一字段排序的情況下痹籍,都是按照打分的高低進(jìn)行一個(gè)默認(rèn)排序的,所以如果正式使用的話(huà)贷屎,必須對(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ì)查詢(xún)進(jìn)行一個(gè)歸一化硅确,不影響排序,因?yàn)閷?duì)于同一個(gè)查詢(xún)這個(gè)值是相同的明肮,但是對(duì)term于ES來(lái)說(shuō)菱农,必須在分片是1的時(shí)候才不影響排序,否則的話(huà)柿估,還是會(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ì)算公式如下所示:
[圖片上傳失敗...(image-76f0eb-1531707755914)]
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ù),例如查詢(xún)?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ù),如果有分片的話(huà)甩苛,就是指的是在當(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召回的話(huà),每一個(gè)term的boost都是該field的boost
norm(t,d):
對(duì)于field的標(biāo)準(zhǔn)化因子辆雾,在官方給的解釋是field越短肪笋,如果召回的話(huà)權(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ì)算公式如下所示:
[圖片上傳失敗...(image-1f3f8e-1531707755914)]
[圖片上傳失敗...(image-d59e87-1531707755914)]
其中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ì)上胡桨,查詢(xún)網(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)橐恍┧饺嗽蛳谙铮瑢⒁恍┳侄未虼a,查詢(xún)的時(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的得分如下圖所示:
[圖片上傳失敗...(image-335552-1531707755914)]
[圖片上傳失敗...(image-d9c603-1531707755914)]
[圖片上傳失敗...(image-149c75-1531707755914)]
最后的得分是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)行介紹:
[圖片上傳失敗...(image-36020a-1531707755914)]
其中每一個(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=idftffieldnorm=1.73205082.86182710.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
本文摘自 CSDN https://blog.csdn.net/molong1208/article/details/50623948/ 這兒僅做學(xué)習(xí)記錄手蝎。