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/ ...
随机推荐
- django-mvc
而对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序.服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理.应用程序则负责具体的逻辑处 ...
- Python-Select/Poll/Epoll使用
select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使 ...
- Ubuntu18.04 英文系统下安装中文输入法
今天尝试了Ubuntu18.04LTS(依旧装的英文版)发现按照之前的方法( http://www.cnblogs.com/asmer-stone/p/5227188.html)安装中文输入法不行了, ...
- AndroidManifest.xml的targetSdkVersion 与 project.properties中target
(1)minSdkVersion与maxSdkVersion :在安装程序的时候,如果目标设备的API < minSdkVersion,或者目标设备的API > maxSdkVersion ...
- centos DNS服务搭建 DNS原理 使用bind搭建DNS服务器 配置DNS转发 配置主从 安装dig工具 DHCP dhclient 各种域名解析记录 mydns DNS动态更新 第三十节课
centos DNS服务搭建 DNS原理 使用bind搭建DNS服务器 配置DNS转发 配置主从 安装dig工具 DHCP dhclient 各种域名解析记录 mydns DNS动态更 ...
- 深入理解Nginx
nginx概述 nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行网站的发布处理,另外 ...
- BabelMap 10.0.0.3 汉化版已经发布
新的 BabelMap 在日前发布. 新版本增加了字符书签的管理功能,以及将窗口最小化到系统通知栏(时钟区域)的功能. 请点击主页左上角进入下载页面下载.
- HDU1059 二进制拆分优化多重背包
/*问你能不能将给出的资源平分成两半,那么我们就以一半为背包,运行多重背包模版 但是注意了,由于个数过大,直接运行会超时,所以要用二进制拆分每种的个数*/ #include<stdio.h> ...
- 常用php操作redis命令整理(二)哈希类型
HSET将哈希表key中的域field的值设为value;如果field是哈希表中的一个新建域,并且值设置成功,返回1;如果哈希表中域field已经存在且旧值已被新值覆盖,返回0. <?php ...
- 用 Python 和 OpenCV 检测图片上的条形码(转载)
原文地址:http://python.jobbole.com/80448/ 假设我们要检测下图中的条形码: # load the image and convert it to grayscale 1 ...