转自: http://www.oschina.net/question/5189_7707 

Lucene 评分体系/机制(lucene scoring)是 Lucene 出名的一核心部分。它对用户来说隐藏了很多复杂的细节,致使用户可以简单地使用 lucene。但个人觉得:如果要根据自己的应用调节评分(或结构排序),十分有必须深入了解 lucene 的评分机制。

Lucene scoring 组合使用了 信 息检索的向量空间模型布尔模型

首先来看下 lucene 的评分公式(在 Similarity 类里的说明)

其中:

  1. tf(t in d) 关联到项频率,项频率是指 项 t 在 文档 d 中出现的次数 frequency。默认的实现是:

    tf(t in d) =frequency½

  2. idf(t) 关联到反转文档频率,文档频率指出现 项 t 的文档数 docFreq。docFreq 越少 idf 就越高(物以稀为贵),但在同一个查询下些值是相同的。默认实现:


  3. coord(q,d) 评分因子,是基于文档中出现查询项的个数。越多的查询项在一个文档中,说明些文档的匹 配程序越高。默认是出现查询项的百分比。
  4. queryNorm(q)查询的标准查询,使不同查询之间可以比较。此因子不影响文档的排序,因为所有有文档 都会使用此因子。默认值:

    每个查询项权重的平分方和(sumOfSquaredWeights)由 Weight 类完成。例如 BooleanQuery 地计算:

  5. t.getBoost()查询时期的 项 t 加权(如:java^1.2),或者由程序使用 setBoost()。
  6. norm(t,d)压缩几个索引期间的加权和长度因子:
    • Document boost - 文档加权,在索引之前使用 doc.setBoost()
    • Field boost - 字段加权,也在索引之前调用 field.setBoost()
    • lengthNorm(field) - 由字段内的 Token 的个数来计算此值,字段越短,评分越高,在做索引的时候由 Similarity.lengthNorm 计算。

    以上所有因子相乘得出 norm 值,如果文档中有相同的字段,它们的加权也会相乘:

       

 

       索引的时候,把 norm 值压缩(encode)成一个 byte 保存在索引中。搜索的时候再把索引中 norm 值解压(decode)成一个 float 值,这个 encode/decode 由 Similarity 提供。官方说:这个过程由于精度问题,以至不是可逆的,如:decode(encode(0.89)) = 0.75。

      计算这个评分涉及到几个核心的类/接口:Similarity、Query、Weight、Scorer、Searcher,由它们或其子类来完成 评分的计算。先来看下它们   的类图:

lucene search score uml, 点击放大

搜索中,评分的过程:

  1. 创建一个查询对象 Query,传给 Searcher,具体来讲可能是 IndexSearcher。
  2. Searcher 根据 Query 创建一个对应的 Weight(是 Query 的内部特征表示),接着 Weight 会创建对应的 Scorer。
  3. Searcher 会创建 Hitcollector 并传到 Scorer,scorer 找到匹配的文档并计算评分,最后写到 Hitcollector 中。

Query、Weight、Scorer 三都关系十分密切,尤其是 Query 和 Weight。Weight 是计算查询权重和创建 Scorer 的。Query 为了可以重用把内部的特征抽象为 Weight,由子类去完成一些相关评分的计算。

任何 Searcher 依赖的状态都存储在 Weight 实现中,而不是在Query 中,这样可以重用 Query。

Weight 的生命周期(被使用):

  1. Weight 由顶层的 Query 创建。Query.createWeight(Searcher),创建的 Weight 给 Searcher 去使用。
  2. 当用 Similarity.queryNorm(float) 来计算查询标准化因子(query normalization)的时候,Weight.sumOfSquaredWeights() 会被调用。
  3. 查询标准化因子(query normalization)会传给 Weight.normalize(float)计算,这个时候权重(weighting)计算完成。
  4. 创建一个 Scorer。

自定义评分的计算

可以实现一个 Similarity 换掉默认的。它仅限于 Scorer、Weight 计算好的因子值再加工。要想对评分有更强的控制力,可以实现一套 Query、Weight、Scorer。

  • Query 是用户信息需要的抽象
  • Weight 是 Query 的内部特性表示的抽象
  • Scorer 抽象公用的计算评分功能,提供计算评分和解说(explanation)评分的能力。

Query 子类实现的方法:

  1. createWeight(Searcher searcher) -- Weight 是 Query 内部代表,所以每个 Query 都必实现一个 Weight,此方法就是生成一个Query对应的Weight对象。
  2. rewrite(IndexReader reader) -- 重写查询为原始的查询,原始的查询有:TermQuery,BooleanQuery……

Weight 接口方法:

  1. Weight#getQuery() -- 指出代表 Weight 的 Query。
  2. Weight#getValue() -- Query 的权重,例如:TermQuery.TermWeight 的 value = idf^2 * boost * queryNorm
  3. Weight#sumOfSquaredWeights() -- 各查询项的平方和,如,TermWeight 的 = (idf * boost)^2
  4. Weight#normalize(float) -- 决定查询标准化的因子,查询标准化值可以在不同 Query 比较 score
  5. Weight#scorer(IndexReader) -- 创建 Query 对应的评分器 Scorer,它的责任是给 Query 匹配到的文档评分。
  6. Weight#explain(IndexReader, int) -- 给指定的文档详细解说评分值是怎么得来了。

Scorer 子类实现的方法:

  1. Scorer#next() -- 预取匹配到的下一文档,有才返回 true。
  2. Scorer#doc() -- 返回当前匹配到的文档id,它必须 next() 调用后才有效。
  3. Scorer#score() -- 返回当前文档的评分,此值可以由应用程序以任何适当的方式给出,如 TermScorer 返回 tf * Weight.getValue() * fieldNorm
  4. Scorer#skipTo(int) -- 跳到大于或等于 int 的匹配文档上。很多情况下,在结果集中 skipTo 比较循环更加快速高效。
  5. Scorer#explain(int) -- 给出评分产生的细节。

要实现一套 Query、Weight、Scorer,最好还是看下 TermQuery、TermWeight、TermScorer。

当 Lucene 中没有想要的查询时(包括不同的评分细节),自定义Query 可能帮得上忙。

Lucene 的 Scoring 评分机制的更多相关文章

  1. Lucene Scoring 评分机制

    原文出处:http://blog.chenlb.com/2009/08/lucene-scoring-architecture.html Lucene 评分体系/机制(lucene scoring)是 ...

  2. lucene 的评分机制

    lucene 的评分机制 elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的.评分就是我们搜索的短语和索引中每篇文档的相关度打分. 如果没有干预评分算法的时候,每次 ...

  3. Apache Lucene评分机制的内部工作原理

    Apache Lucene评分机制的内部工作原理' 第5章

  4. Solr In Action 笔记(2) 之 评分机制(相似性计算)

    Solr In Action 笔记(2) 之评分机制(相似性计算) 1 简述 我们对搜索引擎进行查询时候,很少会有人进行翻页操作.这就要求我们对索引的内容提取具有高度的匹配性,这就搜索引擎文档的相似性 ...

  5. Elasticseach的评分机制

    lucene 的评分机制 elasticsearch是基于lucene的,所以他的评分机制也是基于lucene的.评分就是我们搜索的短语和索引中每篇文档的相关度打分. 如果没有干预评分算法的时候,每次 ...

  6. Wifi 评分机制分析

    从android N开始,引入了wifi评分机制,选择wifi的时候会通过评分来选择. android O源码 frameworks\opt\net\wifi\service\java\com\and ...

  7. Android 8.0/9.0 wifi 自动连接评分机制

    前言 Android N wifi auto connect流程分析 Android N selectQualifiedNetwork分析 Wifi自动连接时的评分机制 今天了解了一下Wifi自动连接 ...

  8. Lucene 评分机制一

    1. 评分公式 1.1 公式介绍 这个公式是Lucene实际计算时使用的公式,是由原型公式推导而来 tf(t in d) 表示某个term的出现频率,定义了term t出现在当前document d的 ...

  9. Lucene 评分机制二 Payload

    这里使用的Lucene4.7.0和Lucene3.X稍有不同 有下面三段内容,我想对船一系列的搜索进行加分 bike car jeep truck bus boat train car ship bo ...

随机推荐

  1. H5应用程序缓存 - Cache manifest

    一.作用 离线浏览 - 根据文件规则把资源缓存在本地,脱机依然能够访问资源,联网会直接使用缓存在本地的文件.优化加载速度,节约服务器资源. 二.适用场景 正如 manifest 英译的名字:离线应用程 ...

  2. post 传递参数中包含 html 代码解决办法,js加密,.net解密

    今天遇到一个问题,就是用post方式传递参数,程序在vs中完美调试,但是在iis中,就无法运行了,显示传递的参数获取不到,报错了,查看浏览器请求情况,错误500,服务器内部错误,当时第一想法是接收方式 ...

  3. css冲突2 要关闭的css在项目代码以外,但是是通过<link>标签引入的css(例如bootstrap):解决方法,在APP.css中使用全局样式

    css冲突,导致html字体过小. 通过浏览器检查发现,导致字体过小的css来自bootstrap. 现要关闭bootstrap的css: 直接在APP.css中添加: html{ font-size ...

  4. ssh无密码登录设置

    为啥要设置ssh无密码登录? 我们先来看一下分布式系统的一键启动流程, 在matser机器上运行脚本,脚本检测有多少slavers,然后通过ssh登录到slavers,进入到相同的目录(或者通过$XX ...

  5. spring MVC学习(二)---配置相关的东西

    1.在上一节中我们提到过每一个DispatcherServlet都会有一个上下文 (WebApplictionContext),并且继承了这些上下文中的bean,其中以一些"特殊" ...

  6. 将 ssh (security shell) 移植到 vxworks

    openssh 依赖 openssl,这两个东西主要针对posix系统,移植到 vxworks 等实时系统有相当的难度. 可以考虑移植如下的库(ssh server): dropbear: https ...

  7. java 多线程 day14 Semaphore 线程信号灯

    import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.c ...

  8. SQL Server 2008 添加登录账户并配置权限

    首先打开数据库,并以windows身份验证模式进入数据库. 然后在左侧的[对象资源管理器中]展开[安全性]节点,鼠标右键点击节点中的[登录名],在弹出的菜单中单击[新建登录名],弹出一个对话框. 1. ...

  9. 专项训练错题整理-nowcoder-算法

    一.排序 1.快速排序在下列哪种情况下最易发挥其长处? 答案是: 被排序的数据完全无序. 在数据基本有序的情况下,会退化为冒泡排序,复杂度会退化为O(n^2). ①[因为,如果是基本有序的话, 那么每 ...

  10. AngularJS 笔记系列(四)控制器和表达式

    控制器:在 Angular 中控制器是一个函数,用来向作用域中添加额外的功能.我们用它来给作用域对象设置初始状态,并添加自定义行为. 使用方法: var app = angualr.module('a ...