2013-02-28 72 views
4

我試圖瞭解fieldNorm如何計算(在索引時間),然後在查詢時間使用(並明顯重新計算)。Lucene fieldNorm相似度計算和查詢時間值之間的差異

在所有示例中,我使用StandardAnalyzer並沒有停用詞。

Deugging的DefaultSimilaritycomputeNorm方法而索引的東西,我注意到2個特定文檔返回:

  • 0.5文件A(其具有4個令牌在其字段)
  • 0.70710677對於文檔B(其具有2個令牌在其字段)

它通過使用公式執行此:

state.getBoost() * ((float) (1.0/Math.sqrt(numTerms))); 

其中升壓始終爲1

之後,當我查詢這些文件我看到,在查詢說明我得到

  • 0.5 = fieldNorm(field=titre, doc=0)提交的A
  • 0.625 = fieldNorm(field=titre, doc=1)用於文檔B

這已經很奇怪了(對我來說,我確定這是我缺少的東西)。爲什麼我不能獲得與在指數時間計算的相同的現場標準值?這是「查詢正常化」的事情嗎?如果是這樣,它是如何工作的?

然而,這或多或少是OK,因爲這兩個查詢時間fieldNorms給予相同的順序那些在索引時間計算(帶有較短的值的字段具有在兩種情況下更高fieldNorm)

我已經然後做我自己的相似性類別,我已經實現了computeNorms方法,像這樣:

public float computeNorm(String pField, FieldInvertState state) { 
    norm = (float) (state.getBoost() + (1.0d/Math.sqrt(state.getLength()))); 
    return norm; 
} 

在索引時間我現在得到:

  • 1.5文檔A(其中有4個令牌在該領域)
  • 1.7071068文檔B(其在該領域2個令牌)

但是現在,當我查詢這些文件,我可以看到,它們都具有相同的字段標準由報道的解釋功能:

  • 1.5 = fieldNorm(field=titre, doc=0)對於文件A
  • 1.5 = fieldNorm(field=titre, doc=1)對於文檔B

對我來說,這現在真的很奇怪,如果我在索引時使用明顯很好的相似性來計算fieldNorm,這會在查詢時給出與令牌數成正比的適當值,所有這些都會丟失和查詢sais這兩個文件有相同的字段規範?

所以我的問題是:

  • 爲什麼所報告的相似的computeNorm方法的指數時間fieldNorm不能保持相同的查詢報告解釋一下嗎?
  • 爲什麼對於在索引時獲得的兩個不同的fieldNorm值(通過相似度computeNorm),我在查詢時獲得相同的fieldNorm值?

== UPDATE

好吧,我發現在Lucene's docs一些東西,一些澄清我的問題,但不是所有的:

然而,導致標準值被編碼爲一個單一的字節存儲之前。在搜索時,從索引目錄中讀取標準字節值並將其解碼回浮點標準值。這種編碼/解碼在減小索引尺寸的同時,會帶來精確損失的代價 - 不能保證decode(encode(x))= x。例如,解碼(編碼(0.89))= 0.75。

有多少精度損失?我們應該在不同的值之間存在一個最小的差距,以便即使在精密度損失重新計算之後它們仍然不同。

回答

4

encodeNormValue該文檔描述的編碼步驟(這是精度丟失),並且特別的價值的最終表示:

編碼使用一個三比特尾數,5位指數和15處的零指數點,因此表示從大約7x10^9到2x10^-9的值,具有大約一個十進制數字的精度。零也代表。負數被四捨五入爲零。太大以致不能表示的值向下舍入爲最大的可表示值。正面值太小不能代表四捨五入到最小的正面可表示值。

要理解尾數只有3位,這意味着精度是一個十位數的重要性。

上的合理性的重要注意事項涉及您的報價結束後的幾個句子,其中Lucene的文檔說:

支持範數值等有損壓縮的理由是考慮到困難(和不準確)的用戶通過查詢表達其真實的信息需求,只有很大的差異很重要

+0

謝謝,那正是我一直在尋找的。 – 2013-03-01 08:53:20