Lucene的评分(score)机制的简单解释

转载 2016年05月31日 09:40:40

Lucene的评分(score)机制的简单解释 博客分类: Lucene
通过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的分值作为分母,其他的文档的分值都除以这个最大值,计算出最终的得分。

下面用代码和运行结果来进行说明:
Java代码 复制代码 收藏代码
  1. public class ScoreSortTest {  
  2.     public final static String INDEX_STORE_PATH = "index";  
  3.     public static void main(String[] args) throws Exception {  
  4.         IndexWriter writer = new IndexWriter(INDEX_STORE_PATH, new StandardAnalyzer(), true);  
  5.         writer.setUseCompoundFile(false);  
  6.           
  7.         Document doc1 = new Document();  
  8.         Document doc2 = new Document();  
  9.         Document doc3 = new Document();  
  10.           
  11.         Field f1 = new Field("bookname","bc bc", Field.Store.YES, Field.Index.TOKENIZED);  
  12.         Field f2 = new Field("bookname","ab bc", Field.Store.YES, Field.Index.TOKENIZED);  
  13.         Field f3 = new Field("bookname","ab bc cd", Field.Store.YES, Field.Index.TOKENIZED);  
  14.           
  15.         doc1.add(f1);  
  16.         doc2.add(f2);  
  17.         doc3.add(f3);  
  18.           
  19.         writer.addDocument(doc1);  
  20.         writer.addDocument(doc2);  
  21.         writer.addDocument(doc3);  
  22.           
  23.         writer.close();  
  24.           
  25.         IndexSearcher searcher = new IndexSearcher(INDEX_STORE_PATH);  
  26.         TermQuery q = new TermQuery(new Term("bookname""bc"));  
  27.         q.setBoost(2f);  
  28.         Hits hits = searcher.search(q);  
  29.         for(int i=0; i<hits.length();i++){  
  30.             Document doc = hits.doc(i);  
  31.             System.out.print(doc.get("bookname") + "\t\t");  
  32.             System.out.println(hits.score(i));  
  33.             System.out.println(searcher.explain(q, hits.id(i)));//  
  34.         }  
  35.     }  
  36. }  

运行结果:
引用
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)

从结果中我们可以看到:
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)

发现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)

发现fieldNorm又乘以了2,所以说对于Document和Field的setBoost都会乘到一起。

因为该文档的最终的score超过了1.0变成1.7807949,所以其他的两个文档的最终得分都要除以该值,
分别变成:
引用
bc bc 0.35355335
ab bc cd 0.19999999



相信通过上面的解释,大家就可以形象得理解Lucene的打分机制,同时也知道如何来改变文档的得分。

Lucene4.10使用教程(七):Lucene的自定义评分

自定义评分的第一种实现方式,详细内容可以查看代码注释 package com.johnny.lucene04.advance_search.selfScore; import java.io.IOE...
  • seven_zhao
  • seven_zhao
  • 2015年01月14日 13:56
  • 8289

理解和学习Solr的score机制

参考:http://www.cnblogs.com/rcfeng/p/4067896.html http://www.cnblogs.com/forfuture1978/archive/2010/...
  • clamaa
  • clamaa
  • 2017年04月11日 10:02
  • 1288

lucene/es 的评分机制

lucene 的评分机制 elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的。评分就是我们搜索的短语和索引中每篇文档的相关度打分。 如果没有干预评分算法的时...
  • sd4015700
  • sd4015700
  • 2015年12月29日 16:31
  • 1692

Lucene的评分(score)机制的简单解释

引自http://www.javaeye.com/wiki/Lucene/1526-lucene-39-s-score-score-a-simple-mechanism-to-explain 通过Se...
  • duck_genuine
  • duck_genuine
  • 2011年01月27日 15:15
  • 1873

Lucene Similarity (Lucene 文档评分score机制详解

转自:http://hi.baidu.com/lewutian/blog/item/3a60a2faad97c912a8d3111a.html 文档的分值代表了该文档在特定查询词下对应的相关性高低,...
  • woaizhoulichao1
  • woaizhoulichao1
  • 2011年08月05日 15:16
  • 397

Lucene评分score计算

文档Document和域Field加权 调用set
  • doublecj
  • doublecj
  • 2014年11月17日 10:01
  • 892

SolrJ 对 solr 及 solrCloud 的连接、简单查询和facet聚合查询的简单样例以及显示数据评分score

导语:使用Solr为Java提供的api,SolrJ对solr及solrCloud的连接、简单查询和facet聚合查询的简单样例,目前使用的是solr4.10.3。 1.对solrJ的介绍    S...
  • liuqinshouss
  • liuqinshouss
  • 2017年08月06日 14:18
  • 836

Lucene评分规则机制

最近部门把公司的搜索业务接过来了,搜索使用的solr,需要研究下solr的评分机制,solr评分规则引用的是Lucene,简单整理了下Lucene评分规则,如下。 1      简介 Lucene...
  • a822631129
  • a822631129
  • 2017年11月16日 14:01
  • 143

lucene/es 的评分机制

lucene 的评分机制 elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的。评分就是我们搜索的短语和索引中每篇文档的相关度打分。 如果没有干预评分算法的时...
  • sd4015700
  • sd4015700
  • 2015年12月29日 16:31
  • 1692

小编辑 Lucene 的 Scoring 评分机制

Lucene 评分体系/机制(lucene scoring)是 Lucene 出名的一核心部分。它对用户来说隐藏了很多复杂的细节,致使用户可以简单地使用 lucene。但个人觉得:如果要根据自己的应用...
  • chenhaiyang_ok
  • chenhaiyang_ok
  • 2012年10月10日 16:13
  • 225
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Lucene的评分(score)机制的简单解释
举报原因:
原因补充:

(最多只允许输入30个字)