【发布时间】:2012-03-11 22:02:47
【问题描述】:
我想使用具有以下评分逻辑的 Lucene: 当我索引我的文档时,我想为每个字段设置一个分数/权重。 当我查询我的索引时,我想为每个查询词设置一个分数/权重。
我永远不会索引或查询同一字段的多个实例——在每个查询(文档)中,都会有 0-1 个实例具有相同的字段名称。 我的字段/查询词没有被分析——它们已经由一个标记组成。
如果它们具有相同的值,我希望分数只是查询字段与文档字段之间的点积。
例如:
格式为(字段名称)(字段值)(字段分数)
查询:
1 AA 0.1
7 BB 0.2
8 CC 0.3
文档 1:
1 AA 0.2
2 DD 0.8
7 CC 0.999
10 FFF 0.1
文档 2:
7 BB 0.3
8 CC 0.5
分数应该是:
分数(q,d1) = FIELD_1_SCORE_Q * FILED_1_SCORE_D1 = 0.1 * 0.2 = 0.02
分数(q,d2) = FIELD_7_SCORE_Q * FILED_7_SCORE_D2 + FIELD_8_SCORE_Q * FILED_8_SCORE_D2 = (0.2 * 0.3) + (0.3 * 0.5)
实现它的最佳方式是什么?在准确性和性能方面(我不需要 TF 和 IDF 计算)。
我目前通过为字段和查询词设置提升来实现它。 然后我覆盖了 DefaultSimilarity 类并在索引/查询之前将其设置为默认值:
public class MySimilarity extends DefaultSimilarity {
@Override
public float computeNorm(String field, FieldInvertState state) {
return state.getBoost();
}
@Override
public float queryNorm(float sumOfSquaredWeights) {
return 1;
}
@Override
public float tf(float freq) {
return 1;
}
@Override
public float idf(int docFreq, int numDocs) {
return 1;
}
@Override
public float coord(int overlap, int maxOverlap) {
return 1;
}
}
并且基于 http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/scoring.html 这应该可以工作。
问题:
- 性能:我正在计算所有 TF/IDF 的东西和 NORMS 没什么……
- 我从 TopScoreDocCollector 得到的分数不是 和我从解释中得到的一样。
这是我的代码的一部分:
indexSearcher = new IndexSearcher(IndexReader.open(directory, true));
TopScoreDocCollector collector = TopScoreDocCollector.create(iTopN, true);
indexSearcher.search(query, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;
for (int i = 0; i < hits.length; ++i) {
int docId = hits[i].doc;
Document d = indexSearcher.doc(docId);
double score = hits[i].score;
String id = d.get(FIELD_ID);
Explanation explanation = indexSearcher.explain(query, docId);
}
谢谢!
【问题讨论】:
标签: java lucene similarity information-retrieval