Lucene Scoring 评分机制
原文出处:http://blog.chenlb.com/2009/08/lucene-scoring-architecture.html
Lucene 评分体系/机制(lucene scoring)是 Lucene 出名的一核心部分。它对用户来说隐藏了很多复杂的细节,致使用户可以简单地使用 lucene。但个人觉得:如果要根据自己的应用调节评分(或结构排序),十分有必须深入了解 lucene 的评分机制。
Lucene scoring 组合使用了 信息检索的向量空间模型 和 布尔模型 。
首先来看下 lucene 的评分公式(在 Similarity 类里的说明)
|
其中:
- tf(t in d) 关联到项频率,项频率是指 项 t 在 文档 d 中出现的次数 frequency。默认的实现是:
tf(t in d) = frequency½ - idf(t) 关联到反转文档频率,文档频率指出现 项 t 的文档数 docFreq。docFreq 越少 idf 就越高(物以稀为贵),但在同一个查询下些值是相同的。默认实现:
idf(t) = 1 + log ( numDocs ––––––––– docFreq+1 ) - coord(q,d) 评分因子,是基于文档中出现查询项的个数。越多的查询项在一个文档中,说明些文档的匹配程序越高。默认是出现查询项的百分比。
- queryNorm(q)查询的标准查询,使不同查询之间可以比较。此因子不影响文档的排序,因为所有有文档都会使用此因子。默认值:
queryNorm(q) = queryNorm(sumOfSquaredWeights) = 1 –––––––––––––– sumOfSquaredWeights½ 每个查询项权重的平分方和(sumOfSquaredWeights)由 Weight 类完成。例如 BooleanQuery 地计算:
sumOfSquaredWeights = q.getBoost() 2 · ∑ ( idf(t) · t.getBoost() ) 2 t in q - t.getBoost()查询时期的 项 t 加权(如:java^1.2),或者由程序使用 setBoost()。
- norm(t,d)压缩几个索引期间的加权和长度因子:
- Document boost - 文档加权,在索引之前使用 doc.setBoost()
- Field boost - 字段加权,也在索引之前调用 field.setBoost()
- lengthNorm(field) - 由字段内的 Token 的个数来计算此值,字段越短,评分越高,在做索引的时候由 Similarity.lengthNorm 计算。
以上所有因子相乘得出 norm 值,如果文档中有相同的字段,它们的加权也会相乘:norm(t,d) = doc.getBoost() · lengthNorm(field) · ∏ f.getBoost() field f in d named as t 索引的时候,把 norm 值压缩(encode)成一个 byte 保存在索引中。搜索的时候再把索引中 norm 值解压(decode)成一个 float 值,这个 encode/decode 由 Similarity 提供。官方说:这个过程由于精度问题,以至不是可逆的,如:decode(encode(0.89)) = 0.75。
计算这个评分涉及到几个核心的类/接口:Similarity、Query、Weight、Scorer、Searcher,由它们或其子类来完成评分的计算。先来看下它们的类图:
lucene search score uml, 点击放大
搜索中,评分的过程:
- 创建一个查询对象 Query,传给 Searcher,具体来讲可能是 IndexSearcher。
- Searcher 根据 Query 创建一个对应的 Weight(是 Query 的内部特征表示),接着 Weight 会创建对应的 Scorer。
- Searcher 会创建 Hitcollector 并传到 Scorer,scorer 找到匹配的文档并计算评分,最后写到 Hitcollector 中。
Query、Weight、Scorer 三都关系十分密切,尤其是 Query 和 Weight。Weight 是计算查询权重和创建 Scorer 的。Query 为了可以重用把内部的特征抽象为 Weight,由子类去完成一些相关评分的计算。
任何 Searcher 依赖的状态都存储在 Weight 实现中,而不是在Query 中,这样可以重用 Query。
Weight 的生命周期(被使用):
- Weight 由顶层的 Query 创建。Query.createWeight(Searcher),创建的 Weight 给 Searcher 去使用。
- 当用 Similarity.queryNorm(float) 来计算查询标准化因子(query normalization)的时候,Weight.sumOfSquaredWeights() 会被调用。
- 查询标准化因子(query normalization)会传给 Weight.normalize(float)计算,这个时候权重(weighting)计算完成。
- 创建一个 Scorer。
自定义评分的计算
可以实现一个 Similarity 换掉默认的。它仅限于 Scorer、Weight 计算好的因子值再加工。要想对评分有更强的控制力,可以实现一套 Query、Weight、Scorer。
- Query 是用户信息需要的抽象
- Weight 是 Query 的内部特性表示的抽象
- Scorer 抽象公用的计算评分功能,提供计算评分和解说(explanation)评分的能力。
Query 子类实现的方法:
- createWeight(Searcher searcher) -- Weight 是 Query 内部代表,所以每个 Query 都必实现一个 Weight,此方法就是生成一个Query对应的Weight对象。
- rewrite(IndexReader reader) -- 重写查询为原始的查询,原始的查询有:TermQuery,BooleanQuery……
Weight 接口方法:
- Weight#getQuery() -- 指出代表 Weight 的 Query。
- Weight#getValue() -- Query 的权重,例如:TermQuery.TermWeight 的 value = idf^2 * boost * queryNorm
- Weight#sumOfSquaredWeights() -- 各查询项的平方和,如,TermWeight 的 = (idf * boost)^2
- Weight#normalize(float) -- 决定查询标准化的因子,查询标准化值可以在不同 Query 比较 score
- Weight#scorer(IndexReader) -- 创建 Query 对应的评分器 Scorer,它的责任是给 Query 匹配到的文档评分。
- Weight#explain(IndexReader, int) -- 给指定的文档详细解说评分值是怎么得来了。
Scorer 子类实现的方法:
- Scorer#next() -- 预取匹配到的下一文档,有才返回 true。
- Scorer#doc() -- 返回当前匹配到的文档id,它必须 next() 调用后才有效。
- Scorer#score() -- 返回当前文档的评分,此值可以由应用程序以任何适当的方式给出,如 TermScorer 返回 tf * Weight.getValue() * fieldNorm
- Scorer#skipTo(int) -- 跳到大于或等于 int 的匹配文档上。很多情况下,在结果集中 skipTo 比较循环更加快速高效。
- Scorer#explain(int) -- 给出评分产生的细节。
要实现一套 Query、Weight、Scorer,最好还是看下 TermQuery、TermWeight、TermScorer。
当 Lucene 中没有想要的查询时(包括不同的评分细节),自定义Query 可能帮得上忙。
重要参考资料:
Lucene Scoring 评分机制的更多相关文章
- Lucene 的 Scoring 评分机制
转自: http://www.oschina.net/question/5189_7707 Lucene 评分体系/机制(lucene scoring)是 Lucene 出名的一核心部分.它对用户来 ...
- lucene 的评分机制
lucene 的评分机制 elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的.评分就是我们搜索的短语和索引中每篇文档的相关度打分. 如果没有干预评分算法的时候,每次 ...
- Elasticseach的评分机制
lucene 的评分机制 elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的.评分就是我们搜索的短语和索引中每篇文档的相关度打分. 如果没有干预评分算法的时候,每次 ...
- Apache Lucene评分机制的内部工作原理
Apache Lucene评分机制的内部工作原理' 第5章
- Lucene的评分(score)机制研究
首先,需要学习Lucene的评分计算公式—— 分值计算方式为查询语句q中每个项t与文档d的匹配分值之和,当然还有权重的因素.其中每一项的意思如下表所示: 表3.5 评分公式中的因子 评分因子 描 述 ...
- Solr In Action 笔记(2) 之 评分机制(相似性计算)
Solr In Action 笔记(2) 之评分机制(相似性计算) 1 简述 我们对搜索引擎进行查询时候,很少会有人进行翻页操作.这就要求我们对索引的内容提取具有高度的匹配性,这就搜索引擎文档的相似性 ...
- ELASTICSEARCH 搜索的评分机制
从我们在elasticsearch复合框输入搜索语句到结果显示,展现给我们的是一个按score得分从高到底排好序的结果集.下面就来学习下elasticsearch怎样计算得分. Lucene(或 El ...
- Wifi 评分机制分析
从android N开始,引入了wifi评分机制,选择wifi的时候会通过评分来选择. android O源码 frameworks\opt\net\wifi\service\java\com\and ...
- Lucene TFIDFSimilarity评分公式详解
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/zteny/article/details/ ...
随机推荐
- python控制台输出颜色
python_控制台输出带颜色的文字方法在开发项目过程中,为了方便调试代码,经常会向stdout中输出一些日志,默认的这些日志就直接显示在了终端中.而一般的应用服务器,第三方库,甚至服务器的一些通告也 ...
- Worst Performing Queries
WITH TMP AS ( SELECT TOP 100 CAST(SUM(s.total_elapsed_time) / 1000000.0 AS DECIMAL(10, 2)) AS [Total ...
- EasyUI Resizable 可调整尺寸
通过 $.fn.resizable.defaults 重写默认的 defaults. 用法 通过标记创建可调整尺寸(resizable)对象. <div class="easyui-r ...
- synchronized修饰的方法之间相互调用
1:synchronized修饰的方法之间相互调用,执行结果为There hello ..因为两个方法(main,hello)的synchronized形成了互斥锁. 所以当main方法执行完之后 ...
- 关于ML的思考讲座-周zh-11.30日
1.深度神经网络 1.以往神经网络采用单或双隐层结构,虽然参照了生物上的神经元,但是从本质上来说还是数学,以函数嵌套形成. 2.通常使用的激活函数是连续可微(differentiable)的,sigm ...
- What do you think the coming adidas NMD Singapore
adidas NMD Singapore is surprising everybody with a lot of completely new NMD choices combined with ...
- C++中定义NULL的头文件
NULL不是C语言基本类型,其定义在stddef.h文件中,作为最基本的语言依赖宏存在.但是随着C/C++的发展,很多文件只要涉及了系统或者标准操作都会将NULL作为标准宏声明或者包含.所以几乎包含任 ...
- web前端几个小知识点笔记
1.css实现宽度是百分比的盒子为正方形 <div style="width:50%;padding-bottom:50%;height:0px;background:#ccc;&qu ...
- 自定义查询语句SpringData
虽然官方的API中给我们提供了很多关键字的查询,但是还是不够灵活,因为我们在项目中,会遇见奇葩的业务,我们需要用SpringData中的一个@Query注解. 使用@Query自定义查询 这种查询可以 ...
- HashSet、HashMap、Hashtable、TreeMap循环、区别
HashSet 循环 //可以为null HashSet<Object> hashSet =new HashSet<Object>(); hashSet.add(1); has ...