Lucene的评分(score)机制的简单解释
来源:互联网 发布:大数据系统硬件 编辑:程序博客网 时间:2024/06/08 08:34
Lucene的评分(score)机制的简单解释- 博客分类:
- Lucene
lucene编程Apachethread
通过Searcher.explain(Query query, int doc)方法可以查看某个文档的得分的具体构成。
在Lucene中score简单说是由 tf * idf * boost * lengthNorm计算得出的。
tf:是查询的词在文档中出现的次数的平方根
idf:表示反转文档频率,观察了一下所有的文档都一样,所以那就没什么用处,不会起什么决定作用。
boost:激励因子,可以通过setBoost方法设置,需要说明的通过field和doc都可以设置,所设置的值会同时起作用
lengthNorm:是由搜索的field的长度决定了,越长文档的分值越低。
所以我们编程能够控制score的就是设置boost值。
还有个问题,为什么一次查询后最大的分值总是1.0呢?
因为Lucene会把计算后,最大分值超过1.0的分值作为分母,其他的文档的分值都除以这个最大值,计算出最终的得分。
下面用代码和运行结果来进行说明:
运行结果:
从结果中我们可以看到:
bc bc文档中bc出现了2次,tf为2的平方根,所以是1.4142135。而其他的两个文档出现了一次,所以是1.0
所有的三个文档的idf值都是一样的,是0.71231794
默认情况下,boost的值都是1.0,所以lengthNorm就是当前的fieldNorm的值。前两个文档的长度一致,为0.625,而排在最后的文档,因为长度要长一些,所以分值要低,为0.5
现在对f2这个字段增加激励因子:f2.setBoost(2.0f);
运行结果变为:
发现fieldNorm值有0.625变成了1.25,所以就是乘以了2.0
接下来再对第二个文档增加激励因子:doc2.setBoost(2.0f);
运行结果变为:
发现fieldNorm又乘以了2,所以说对于Document和Field的setBoost都会乘到一起。
因为该文档的最终的score超过了1.0变成1.7807949,所以其他的两个文档的最终得分都要除以该值,
分别变成:
相信通过上面的解释,大家就可以形象得理解Lucene的打分机制,同时也知道如何来改变文档的得分。
在Lucene中score简单说是由 tf * idf * boost * lengthNorm计算得出的。
tf:是查询的词在文档中出现的次数的平方根
idf:表示反转文档频率,观察了一下所有的文档都一样,所以那就没什么用处,不会起什么决定作用。
boost:激励因子,可以通过setBoost方法设置,需要说明的通过field和doc都可以设置,所设置的值会同时起作用
lengthNorm:是由搜索的field的长度决定了,越长文档的分值越低。
所以我们编程能够控制score的就是设置boost值。
还有个问题,为什么一次查询后最大的分值总是1.0呢?
因为Lucene会把计算后,最大分值超过1.0的分值作为分母,其他的文档的分值都除以这个最大值,计算出最终的得分。
下面用代码和运行结果来进行说明:
- public class ScoreSortTest {
- public final static String INDEX_STORE_PATH = "index";
- public static void main(String[] args) throws Exception {
- IndexWriter writer = new IndexWriter(INDEX_STORE_PATH, new StandardAnalyzer(), true);
- writer.setUseCompoundFile(false);
- Document doc1 = new Document();
- Document doc2 = new Document();
- Document doc3 = new Document();
- Field f1 = new Field("bookname","bc bc", Field.Store.YES, Field.Index.TOKENIZED);
- Field f2 = new Field("bookname","ab bc", Field.Store.YES, Field.Index.TOKENIZED);
- Field f3 = new Field("bookname","ab bc cd", Field.Store.YES, Field.Index.TOKENIZED);
- doc1.add(f1);
- doc2.add(f2);
- doc3.add(f3);
- writer.addDocument(doc1);
- writer.addDocument(doc2);
- writer.addDocument(doc3);
- writer.close();
- IndexSearcher searcher = new IndexSearcher(INDEX_STORE_PATH);
- TermQuery q = new TermQuery(new Term("bookname", "bc"));
- q.setBoost(2f);
- Hits hits = searcher.search(q);
- for(int i=0; i<hits.length();i++){
- Document doc = hits.doc(i);
- System.out.print(doc.get("bookname") + "\t\t");
- System.out.println(hits.score(i));
- System.out.println(searcher.explain(q, hits.id(i)));//
- }
- }
- }
运行结果:
引用
bc bc 0.629606
0.629606 = (MATCH) fieldWeight(bookname:bc in 0), product of:
1.4142135 = tf(termFreq(bookname:bc)=2)
0.71231794 = idf(docFreq=3, numDocs=3)
0.625 = fieldNorm(field=bookname, doc=0)
ab bc 0.4451987
0.4451987 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
0.625 = fieldNorm(field=bookname, doc=1)
ab bc cd 0.35615897
0.35615897 = (MATCH) fieldWeight(bookname:bc in 2), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
0.5 = fieldNorm(field=bookname, doc=2)
0.629606 = (MATCH) fieldWeight(bookname:bc in 0), product of:
1.4142135 = tf(termFreq(bookname:bc)=2)
0.71231794 = idf(docFreq=3, numDocs=3)
0.625 = fieldNorm(field=bookname, doc=0)
ab bc 0.4451987
0.4451987 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
0.625 = fieldNorm(field=bookname, doc=1)
ab bc cd 0.35615897
0.35615897 = (MATCH) fieldWeight(bookname:bc in 2), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
0.5 = fieldNorm(field=bookname, doc=2)
从结果中我们可以看到:
bc bc文档中bc出现了2次,tf为2的平方根,所以是1.4142135。而其他的两个文档出现了一次,所以是1.0
所有的三个文档的idf值都是一样的,是0.71231794
默认情况下,boost的值都是1.0,所以lengthNorm就是当前的fieldNorm的值。前两个文档的长度一致,为0.625,而排在最后的文档,因为长度要长一些,所以分值要低,为0.5
现在对f2这个字段增加激励因子:f2.setBoost(2.0f);
运行结果变为:
引用
ab bc 0.8903974
0.8903974 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
1.25 = fieldNorm(field=bookname, doc=1)
0.8903974 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
1.25 = fieldNorm(field=bookname, doc=1)
发现fieldNorm值有0.625变成了1.25,所以就是乘以了2.0
接下来再对第二个文档增加激励因子:doc2.setBoost(2.0f);
运行结果变为:
引用
ab bc 1.0
1.7807949 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
2.5 = fieldNorm(field=bookname, doc=1)
1.7807949 = (MATCH) fieldWeight(bookname:bc in 1), product of:
1.0 = tf(termFreq(bookname:bc)=1)
0.71231794 = idf(docFreq=3, numDocs=3)
2.5 = fieldNorm(field=bookname, doc=1)
发现fieldNorm又乘以了2,所以说对于Document和Field的setBoost都会乘到一起。
因为该文档的最终的score超过了1.0变成1.7807949,所以其他的两个文档的最终得分都要除以该值,
分别变成:
引用
bc bc 0.35355335
ab bc cd 0.19999999
ab bc cd 0.19999999
相信通过上面的解释,大家就可以形象得理解Lucene的打分机制,同时也知道如何来改变文档的得分。
0 0
- Lucene的评分(score)机制的简单解释
- Lucene的评分(score)机制的简单解释
- Lucene的评分(score)机制的简单解释
- Lucene的评分(score)机制的简单解释
- Lucene的评分机制
- Lucene的评分机制
- lucene 的评分机制
- 理解Lucene的评分机制
- Lucene 的 Scoring 评分机制
- Lucene 的 Scoring 评分机制
- lucene/es 的评分机制
- Lucene Similarity (Lucene 文档评分score机制详解)
- Lucene Similarity (Lucene 文档评分score机制详解
- Lucene Similarity (Lucene 文档评分score机制详解)
- Lucene评分score计算
- 小编辑 Lucene 的 Scoring 评分机制
- Lucene 评分(score)机制--Document Boost和Field Boost
- Lucene 评分(score)机制--Document Boost和Field Boost
- PyQt4及py2exe使用时的一些错误及解决方案
- java1200例-文字的探照灯效果
- 正则表达式
- iOS objection 依赖注入
- git修改ssh默认端口号
- Lucene的评分(score)机制的简单解释
- Spring MVC
- spring-对线程池的支持
- mfc CRgn 画椭圆对话框
- C# 中普通类、抽象类、接口之间的区别
- 关于TextWatcher编辑框监听器的参数问题
- 使用SIPP来进行SIP压力测试(一)
- 远程服务器上传文件
- Java中 Class.getSimpleName()的作用