转自: 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. c# winfrom实时获取斗鱼房间弹幕

    效果图如下: 通过webBrowser获取,时钟控件刷新弹幕,正则匹配数据,用第二个webBrowser显示弹幕内容.老话,并没完善.请自行完善.有个dll是用来屏蔽webBrowser的声音的,可能 ...

  2. [linux][shell]负载均衡下多个服务器代码同步方案

    说明: 服务器是腾讯的云服务器(腾讯用的是linux container),远程登陆云服务器需要使用代理,在服务器中不能访问外网,所以当时也就没有去想做svn 需求: 1. 把同样的代码同步到不同的服 ...

  3. 关于spring的applicationContext.xml配置文件的ref和value之自我想法

    今天在做SSH的一个项目的时候,因为需要定时操作,所以就再sping里面加入了一个quartz的小定时框架,结果在运行时候,发生了一个小bug. Caused by: org.springframew ...

  4. java获取时间段内的所有日期

        public static void main(String[] args) {        SimpleDateFormat dateFormat = new SimpleDateForm ...

  5. 给input文本框添加灰色提示文字,三种方法.

    1.这个是HTML5的属性. h5的好简单.... placeholder="这里输入文字" 2.HTML的: value="你的提示文字" onFocus=& ...

  6. SpringBean 定义继承

    Bean定义继承 bean定义可以包含很多的配置信息,包括构造函数的参数,属性值,容器的具体信息例如初始化方法,静态工厂方法名,等等.子bean的定义继承副定义的配置数据.子定义可以根据需要重写一些值 ...

  7. 详解MySQL第二篇—DML语句

    DML 语句: DML 操作是指对数据库中表记录的操作,主要包括表记录的插入(insert).更新(update).删除(delete)和查(select),是开发人员日常使用最频繁的操作.下面将依次 ...

  8. 20165324 Java实验四 Android程序设计

    20165324 Java实验四 Android程序设计 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:何春江 学号:20165324 指导教师:娄嘉鹏 实验日期:2018年5月1 ...

  9. Mac电脑下-nodejs安装卸载升级

    一.Mac 安装nodejs: 1:brew install node 2:官网上下载指定版本(.pkg)双击安装 二.Mac 卸载nodejs: 1: brew的安装方式的卸载:   brew un ...

  10. Selenium之使用PageFactory初始化pageobject

    使用PageFactory初始化pageobject有什么作用呢,下面举个例子来说明 public BaiduPage baiduPage = PageFactory.initElements(dri ...