ES學(xué)習(xí)之 打分策略

一、目的

一個(gè)搜索引擎使用的時(shí)候必定需要排序這個(gè)模塊,一般情況下在不選擇按照某一字段排序的情況下,都是按照打分的高低進(jìn)行一個(gè)默認(rèn)排序的,所以如果正式使用的話,必須對(duì)默認(rèn)排序的打分策略有一個(gè)詳細(xì)的了解才可以,否則被問起來為什么這個(gè)在前面,那個(gè)在后面不好辦,因此對(duì)Elasticsearch的打分策略詳細(xì)的看了下,雖然說還不是了解的很全部,但是大部分都看的差不多了,結(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來說,必須在分片是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ì)算公式如下所示:

[圖片上傳失敗...(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ù),例如查詢?cè)~為“無線通信”,使用默認(rèn)分詞器,如果文檔為“通知他們開會(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)行開方,這個(gè)沒什么可以講述的,實(shí)際打分也是如此

idf(t):

這個(gè)的意思是出現(xiàn)的逆詞頻數(shù),即召回的文檔在總文檔中出現(xiàn)過多少次,這個(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)值,沒仔細(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)重越大,例如搜索無線通信,一個(gè)是很長(zhǎng)的內(nèi)容,但都是包含這幾個(gè)字,但是并不是我們想要的,另外一個(gè)內(nèi)容很短,但是完整包含了無線通信,我們不能因?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í)候總是無法對(duì)上,查詢網(wǎng)上的資料說是在打分的時(shí)候?qū)⒔Y(jié)果先進(jìn)行壓縮,然后解壓縮,所以結(jié)果跟原始值對(duì)不上,個(gè)人理解有點(diǎn)像量化的過程,因?yàn)樵趯?shí)際explain的時(shí)候發(fā)現(xiàn)該值有一定的規(guī)律性

三、實(shí)際的打分explain

在實(shí)際的時(shí)候,例如搜索“無線通信”,如下圖所示,因?yàn)橐恍┧饺嗽?,將一些字段打碼,查詢的時(shí)候設(shè)置explain為true,如下圖所示:

image.png

因?yàn)槭褂玫氖悄J(rèn)的分詞器,所以最后的結(jié)果是將“無線通信”分成了四個(gè)字,并且認(rèn)為是四個(gè)term來進(jìn)行計(jì)算,最后將計(jì)算的結(jié)果進(jìn)行相加得到最后的得分0.7605926,這個(gè)分?jǐn)?shù)是“無”的得分+“線”的得分+“通”的得分+“信”的得分,四個(gè)term的得分如下圖所示:


image.png

[圖片上傳失敗...(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ì)算,以“無”為例進(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,說明在分片四里面共有1995個(gè)文檔,召回了包含“無”的309個(gè)文檔,因此為這個(gè)值

querynorm部分的計(jì)算:根據(jù)上面“無”“線”“通”“信”四個(gè)的分?jǐn)?shù)計(jì)算,可以看到,idf的值分別為

無: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)算過,在此不詳細(xì)敘述

tf的值是在此處出現(xiàn)3次,所以為√3=1.7320508

fieldnorm的值不知道如何計(jì)算,按照公式計(jì)算不出來explain的值,網(wǎng)上資料說是編解碼導(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í)記錄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容