1. 程式人生 > 其它 >Lucene中打分機制

Lucene中打分機制

技術標籤:搜尋

主要是個人學習使用,如有問題,煩請指正。

Elasticsearch 中explain評分分析:

  1. 解釋document評分怎麼來的。即query與doc匹配得分。

  2. 原理:
    綜合query中每個term與文件的打分。 對query, doc進行綜合打分排序。
    term 與query打分: 主要參考: term自身tfidf, doc自身特性, query特性。 總體為: query weight, field weight(這裡的field理解為doc可能更好些)
    文章末尾: https://www.cnblogs.com/forfuture1978/archive/2010/03/07/1680007.html。 通過向量餘玄計算,對lucene公式進行了推導,特別好。

  3. 公式解釋(lucene打分公示):此公式總科可分為兩部分:query weight, field weight。
    在這裡插入圖片描述

公式每部分介紹:
(1)queryNorm: 查詢歸一化
queryNorm(q) = 1/ sum of Squared wights
sum of Squared wights = idf(t1) * idf(t1) + idf(t2) * idf(t2) + … , 其中n為query中包含的term個數。 此處預設是在一個數據域中。如果是多個的話。
在這裡插入圖片描述

注意: 以上主要是對query做歸一化處理。反應每個query自身統計資訊。
(2)coord(q,d): 協調因此
coord(q, d) = overlap/maxoverlap . overlap: 文件d檢索命中query中term個數。 maxoverlap: query中term個數。 即, query中term覆蓋率。

(3)tf(t in d): term在文件中出現的個數:
tf(t in d) = √frequency。 出現的個數開方。
(4) idf(t) : 逆文件率
idf(t) = 1 + log ( numDocs / (docFreq + 1)) 。 docFreq : 包含該term的文件出. numDocs: 總文件數。log以e為低
(5)lengthNorm(t.field in d): 即norm(t, d)。 衡量 文件長度對打分的影響。
在這裡插入圖片描述

     此處假設文件越長,則該文件重要性越低。因此加了這個凸顯短文件,但感覺也不合理。所以lucene將該藉口開發,可以根據業務自由定義,文件長度term打分的影響
      
      , 
    各類Boost值

t.getBoost():查詢語句中每個詞的權重,可以在查詢中設定某個詞更加重要,common^4 hello
d.getBoost():文件權重,在索引階段寫入nrm檔案,表明某些文件比其他文件更重要。
f.getBoost():域的權重,在索引階段寫入nrm檔案,表明某些域比其他的域更重要
因為各種boost是先驗知識, 因次norm(t,d) 可減緩為lengthNorm(f) 。
因為在索引中,不同的文件長度不一樣,很顯然,對於任意一個term,在長的文件中的tf要大的多,因而分數也越高,這樣對小的文件不公平,舉一個極端的例子,在一篇1000萬個詞的鴻篇鉅著中,"lucene"這個詞出現了11次,而在一篇12個詞的短小文件中,"lucene"這個詞出現了10次,如果不考慮長度在內,當然鴻篇鉅著應該分數更高,然而顯然這篇小文件才是真正關注"lucene"的。
所以在Lucene中,Similarity的lengthNorm介面是開放出來,使用者可以根據自己應用的需要,改寫lengthNorm的計算公式。比如我想做一個經濟學論文的搜尋系統,經過一定時間的調研,發現大多數的經濟學論文的長度在8000到10000詞,因而lengthNorm的公式應該是一個倒拋物線型的,8000到 10000詞的論文分數最高,更短或更長的分數都應該偏低,方能夠返回給使用者最好的資料。
(6)boost(t.field in d) : t 在field中的重要性。

(7) 簡化後公式:

在這裡插入圖片描述

公式來源推導:
原理: score(q, d) 是query中每個term與doc的匹配得分和。 因此需要算每個term與doc的得分。
此處以“無線通訊” 為案例,基於分詞, 可分為 無,線,通,信,(t1, t2, t3, t4) 推導“無”score的由來,記為score(t1, d).
從而推匯出 score(q, d)即luence公示。
score(t1, d) = query weight * field weight.
query weight = idf(t1) * queryNorm(q)
idf(t1) = 1 + log ( numDocs / (docFreq(t1) + 1))。 doc Freq: 包含t1的doc數。 num Docs : 總doc數目。
queryNorm = idf(t1) * idf(t1) + idf(t2) * idf(t2) + idf(t3) * idf(t3) + idf(t4) * idf(t4)。 四個t的idf。 注意: query做歸一化, quer中所有term該值一樣
field weight= idf(t1) * tf(1) * fieldNorm()
idf(t1) : 上面已算出。
tf1(1): 當前文件包含t1的個數。然後開平方。
fieldNorm : 可用lengthNorm替代。
score(t1,d) = query weight * field weight = idf(t1) * queryNorm(q) * idf(t1) *tf(t1) * fieldNorm = tf(t1) * idf(t1)^2 * fieldNorm * queryNorm * coor(q,d)
因此score(q,d) = sum(tf(ti) * idf(ti)^2 * fieldNorm) * queryNorm * coor(q,d)
案例: 可參考https://blog.csdn.net/molong1208/article/details/50623948, 有具體案例說明。 挺具體的。
4. 參考說明:
https://www.cnblogs.com/forfuture1978/archive/2010/03/07/1680007.html
https://blog.csdn.net/molong1208/article/details/50623948
https://www.cnblogs.com/clonen/p/6674955.html?utm_source=itdadao&utm_medium=referral