Reference
- lucene实战 第2版 3.3节
每当搜索到匹配文档时, 该文档都会被赋予一定的分值,用以反映匹配程度。该分值会计算文档与查询之间的相似程度吗,更高的分值反映了更强的相似程度和匹配程度。
Lucene如何评分
- lucene对查询语句和对应匹配文档之间进行相似度评分。分值计算方式为查询语句(q)中每一项(t)与文档(d)的匹配分值之和。
∑t in q(tf(t in d)×idf(t)2×boost(t.field) in d)×lengthNorm(t.field in d)×coord(q,d)×queryNorm(q)) - 这样得到的评分只是原始得分,它是一个大于0.0的浮点数。通常,如果搜索程序要将评分呈现给用户的话,最好先将评分进行归一化处理,即用该条查询对应的评分除以最大评分。评分越大说明文档与查询之间的匹配越好。
- 下表说明评分公式的各个因子。
评分因子 | 描述 |
---|---|
tf(t in d) | 项频率因子——文档(d)中出现项(t)的频率 |
idf(t) | 项在倒排文件中出现的频率:它被用来衡量项的“唯一”性。出现频率较高的term具体较低的idf;出现较少的ter具有较高的idf |
boost(t.field in d) | 域和文档的加权,在索引期间设置。可以对某个域或文档进行静态加权,默认为1.0 |
lengthNorm(t.field in d) | 域的归一化(Normalization)值,表示域中包含的项数量。对于该因子,更短的域或更少的语汇单元能获得更大的加权 |
coord(q, d) | 协调因子(Coordination factor),基于文档中包含查询的项个数。该因子会对包含更多搜索项的文档进行类似AND的加权 |
queryNorm(q) | 每个查询的归一化,指每个查询项权重的平方和,默认为1.0 |
如果想改变这些因子,可以参考Similarity相关Java文档
使用explain() 查看结果评分过程
IndexSearcher类包含一个explain方法,调用该方法需要传入一个Query对象和一个文档ID,然后该方法会返回一个Explaination对象。
一个简单的示例程序:
//explain方法
//lucene5.1.0
//没有运行
//一般会有fieldWeight tf(termFreq) idf(docFreq, maxDocs) fieldNorm(field, doc)
class Explainer {
public static void explain(String indexDir, String queryExpression) throws Exception {
Directory directory = FSDirectory.open(Paths.get(indexDir));
IndexReader reader = DirectoryReader.open(directory);
IndexSearcher searcher = new IndexSearcher(reader);
//change "contents" to "..." to Search
QueryParser parser = new QueryParser("contents", new SimpleAnalyzer());
Query query = parser.parse(queryExpression);
System.out.println("Query: " + queryExpression);
TopDocs topdocs = searcher.search(query, 10);
for(ScoreDoc match : topdocs.scoreDocs) {
Explanation explanation = searcher.explain(query, match.doc);
System.out.println("--------------------------------------");
Document doc = searcher.doc(match.doc);
System.out.println(doc.get("title"));
System.out.println(explanation.toString());
}
reader.close();
directory.close();
}
}