據我所知,給定文檔的字段長度是在給定文檔的字段中索引的術語數。但是,似乎字段長度永遠不是整數。例如,我在內容字段中看到一個包含兩個詞語的文檔,但由Solr計算的內容字段長度實際上是2.56,而不是我所期望的。如何在Solr/Lucene中真正計算字段長度?如何在Solr/Lucene中定義字段長度?
我指的是根據BM25相似度函數計算得分時使用的字段長度,但我認爲字段長度正在爲其他排名方案計算。
據我所知,給定文檔的字段長度是在給定文檔的字段中索引的術語數。但是,似乎字段長度永遠不是整數。例如,我在內容字段中看到一個包含兩個詞語的文檔,但由Solr計算的內容字段長度實際上是2.56,而不是我所期望的。如何在Solr/Lucene中真正計算字段長度?如何在Solr/Lucene中定義字段長度?
我指的是根據BM25相似度函數計算得分時使用的字段長度,但我認爲字段長度正在爲其他排名方案計算。
正如我在BM25Similarity代碼中看到:
public final long computeNorm(FieldInvertState state) {
final int numTerms = discountOverlaps ? state.getLength() - state.getNumOverlap() : state.getLength();
return encodeNormValue(state.getBoost(), numTerms);
}
其中狀態#的getLength()是:
/**
* Get total number of terms in this field.
* @return the length
*/
public int getLength() {
return length;
}
實際上,它是一個整數。你能告訴,你在哪裏看到非整數值? SolrAdmin用戶界面?哪裏?現在
,爲您發佈的輸出,我找到了地方,它來源於: source
看看這個:
private Explanation explainTFNorm(int doc, Explanation freq, BM25Stats stats, NumericDocValues norms) {
List<Explanation> subs = new ArrayList<>();
subs.add(freq);
subs.add(Explanation.match(k1, "parameter k1"));
if (norms == null) {
subs.add(Explanation.match(0, "parameter b (norms omitted for field)"));
return Explanation.match(
(freq.getValue() * (k1 + 1))/(freq.getValue() + k1),
"tfNorm, computed from:", subs);
} else {
float doclen = decodeNormValue((byte)norms.get(doc));
subs.add(Explanation.match(b, "parameter b"));
subs.add(Explanation.match(stats.avgdl, "avgFieldLength"));
subs.add(Explanation.match(doclen, "fieldLength"));
return Explanation.match(
(freq.getValue() * (k1 + 1))/(freq.getValue() + k1 * (1 - b + b * doclen/stats.avgdl)),
"tfNorm, computed from:", subs);
}
}
因此,由字段長度他們輸出:float doclen = decodeNormValue((byte)norms.get(doc));
/** The default implementation returns <code>1/f<sup>2</sup></code>
* where <code>f</code> is {@link SmallFloat#byte315ToFloat(byte)}. */
protected float decodeNormValue(byte b) {
return NORM_TABLE[b & 0xFF];
}
/** Cache of decoded bytes. */
private static final float[] NORM_TABLE = new float[256];
static {
for (int i = 1; i < 256; i++) {
float f = SmallFloat.byte315ToFloat((byte)i);
NORM_TABLE[i] = 1.0f/(f*f);
}
NORM_TABLE[0] = 1.0f/NORM_TABLE[255]; // otherwise inf
}
事實上,看着這wikipedia應該docLen是
a | D |在文檔d中的話
闡述以前的答案「FieldLength參數」的長度是通過複雜的數學正常化(編碼/解碼)式計算(基本上壓縮32個整數爲8位以節省磁盤空間,同時存儲數據)放在SmallFloat.java類中。
這是decodeNormValue()函數的描述,其計算在FieldLength參數BM25:
默認評分執行哪個{@link encodeNormValue(浮點) 編碼}範數值爲存儲前一個字節。在搜索 時,從索引中讀取標準字節值{org.apache.lucene.store.Directory directory}並將{decode decodeNormValue(long)}解碼}返回到浮點數標準的值。這種編碼/解碼在減少索引尺寸的同時,還帶有精確損失的價格 - 不保證解碼(編碼(x))= x。例如,解碼(編碼(0.89))= 0.875
希望這有助於。
我看到非整數值與解釋:2。56 = fieldLength – mossaab
@mossaab您能否將解釋的完整輸出添加到您的問題中?因爲通常它包含fieldNorm或fieldWeigth而不是fieldLength。 –
23.637165 =的總和: 10.065297 =體重(標題:GOOGL在401658357)[BM25Similarity]的結果是: 10.065297 =得分(DOC = 401658357,FREQ = 1.0 = termFreq = 1.0 ),產品的: 7.3866553 = IDF (docFreq = 414179,docCount = 668609139) 1.3626325 = tfNorm,從計算: 1.0 = termFreq = 1.0 1.2 =參數K1 0.75 =參數b 7.3254013 = avgFieldLength 2.56 = FieldLength參數 13.571868 =體重(標題:聚會在401658357)[BM25Similarity],結果爲: 13.571868 =評分(doc = 401658357,freq = 1.0 = termFreq = 1.0 ),乘積: [TRUNCA TED] – mossaab