`

<转>Lucene Scoring 评分机制

阅读更多

原文出处:http://blog.chenlb.com/2009/08/lucene-scoring-architecture.html

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

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

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

score(q,d)   =   coord(q,d) ·  queryNorm(q) · ( tf(t in d) ·  idf(t)2 ·  t.getBoost() ·  norm(t,d) )
  t in q  

其中:

  1. tf(t in d) 关联到项频率,项频率是指  t 在 文档 d 中出现的次数 frequency。默认的实现是:
    tf(t in d) = frequency½
  2. idf(t) 关联到反转文档频率,文档频率指出现  t 的文档数 docFreq。docFreq 越少 idf 就越高(物以稀为贵),但在同一个查询下些值是相同的。默认实现:
    idf(t) = 1 + log (
    numDocs
    –––––––––
    docFreq+1
    )
  3. coord(q,d) 评分因子,是基于文档中出现查询项的个数。越多的查询项在一个文档中,说明些文档的匹配程序越高。默认是出现查询项的百分比。
  4. queryNorm(q)查询的标准查询,使不同查询之间可以比较。此因子不影响文档的排序,因为所有有文档都会使用此因子。默认值:
    queryNorm(q)   =   queryNorm(sumOfSquaredWeights) =
    1
    ––––––––––––––
    sumOfSquaredWeights½

     

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

    sumOfSquaredWeights =   q.getBoost() 2 · ( idf(t) ·  t.getBoost() 2
      t in q  
  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(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

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 可能帮得上忙。

分享到:
评论

相关推荐

    Java搜索引擎的研究与实现(含文档+源码)

    11&lt;br&gt;3.2.5网络机器人的代码分析 12&lt;br&gt;3.3小节 14&lt;br&gt;第四章 基于lucene的索引与搜索 15&lt;br&gt;4.1什么是Lucene全文检索 15&lt;br&gt;4.2 Lucene的原理分析 15&lt;br&gt;4.2.1全文检索的实现机制 15&lt;br&gt;4.2.2 Lucene的索引效率 ...

    java文集

    正则表达式&lt;br&gt;lucene索引合并&lt;br&gt;探查Weblogic JDBC Multipool 问题 &lt;br&gt;struts通用Exception处理 &lt;br&gt;Grails中默认数据库HSQLDB点滴&lt;br&gt;从request获取各种路径总结&lt;br&gt;DIV实现的表格自动伸张与收缩&lt;br&gt;java 邮件...

    jive.chm

    &lt;br&gt;全文搜索&lt;br&gt; 1 使您的Jive搜索支持中文 &lt;br&gt; 2 关于Jive2中的中文搜索 &lt;br&gt; 3 基于JAVA的全文索引引擎Lucene简介 &lt;br&gt;&lt;br&gt; &lt;br&gt; &lt;br&gt;安全认证&lt;br&gt; 1 Jive2.1.1 License保护原理分析 &lt;br&gt; 2 用Java的加密机制来...

    Lucene中文分词器包

    &lt;br&gt;1. 正向全切分算法,42万汉字字符/每秒的处理能力(IBM ThinkPad 酷睿I 1.6G 1G内存 WinXP)&lt;br&gt;2. 对数量词、地名、路名的优化处理&lt;br&gt;3. 对未知词汇采用自识别结合二元切分算法,确保搜索召回率&lt;br&gt;(使用方法...

    X3-BLOG 0.8beta

    * 增加个人档案&lt;br&gt; * 加入相册评论和评论管理&lt;br&gt; * 增加了日志的快速收藏功能&lt;br&gt; * 优化了模拟下拉列表和窗口拖动代码&lt;br&gt; * 评论的验证码设定为点击验证码输入框时才载入,节省服务器资源&lt;br&gt; * 调整了DataSource...

    Lucene:基于Java的全文检索引擎简介

    &lt;br&gt;Lucene的作者:Lucene的贡献者Doug Cutting是一位资深全文索引/检索专家,曾经是V-Twin搜索引擎(Apple的Copland操作系统的成就之一)的主要开发者,后在Excite担任高级系统架构设计师,目前从事于一些INTERNET...

    Lucene查询工具LQT.zip

    --analyzer &lt;arg&gt; for query, (KeywordAnalyzer | StandardAnalyzer) (defaults to KeywordAnalyzer) --fields &lt;arg&gt; fields to include in output (defaults to all) -i,--index &lt;arg&gt; index (required) --...

    lucene-pdf:一个能够轻松对 PDF 文本和元数据进行 Lucene 索引的库

    将它添加到您的 Maven 项目的pom.xml : &lt; dependency&gt; &lt; groupId&gt;com.snowtide&lt;/ groupId&gt; &lt; artifactId&gt;lucene-pdf&lt;/ artifactId&gt; &lt; version&gt;3.0.0&lt;/ version&gt;&lt;/ dependency&gt; 或者,将上述 Maven 工件坐标添加到...

    compass包及相关学习资料

    Compass是一个强大的,事务的,高性能的对象/搜索引擎映射...内容包括compass的jar包及从网上搜集的相关学习资料.&lt;br&gt;附两个不错的资料地址:&lt;br&gt;http://www.blogjava.net/hellboys/archive/2006/05/31/49311.aspx&lt;br&gt;...

    LoremIpsumSearch:包含与 lucene 和 solr 一起使用的搜索算法

    LoremIpsum搜索 包含与 lucene 和 solr 一起使用的搜索算法... export CLASSPATH="&lt;lucene&gt;/lucene/replicator/lib/*:&lt;nutch&gt;/build/*:&lt;nutch&gt;/build/lib/*:&lt;lucene&gt;/solr/dist/*:&lt;lucene&gt;/solr/ dist/solrj-lib/*:*:.

    lucene-1.4.3

    包括lucene-1.4.3.src和lucene-1.4.3.zip&lt;br&gt;其中lucene-1.4.3.zip中含有lucene-1.4.3.jar&lt;br&gt;

    semantic-vectors-lucene-tools:用于为语义向量建立Lucene索引的工具

    用于语义向量的Lucene工具允许根据有关Seldon MySQL数据库中项目(例如电影,文章)的元数据创建Lucene索引。...item-limit &lt;item&gt; -jdbc &lt;JDBC&gt;&lt;lucene&gt; :在其中重新创建lucene索引的文件夹&lt;attr&gt;

    BBS-CS 天乙社区 v6.0.1(含源码)

    &lt;br&gt; 4、全文检索:天乙社区6.0采用Lucene全文检索,并支持完全国际化多语言的全文检索。 &lt;br&gt; 5、MVC框架:天乙社区6.0继续了5.x的Struts框架,但经过优化,WEB端更加简洁高效。 &lt;br&gt; 6、集群支持:系统可以运行在...

    russianmorphology-fork

    Java的俄语和英语形态叉 这是Alexander.A.Kuznetsov编写的针对Java和Lucene 3.0框架的俄语和英语形态的分支。 它已更新为可与Lucene 4.0及更高版本一起使用。... &lt;groupId&gt;org.motovs.lucene.morpholo

    开发自己的搜索引擎《lucene2.0+heritrix》一书对应的源码资料

    开发自己的搜索引擎《lucene2.0+heritrix》一书对应的源码资料,总共有30M,只上传了几个例子.&lt;br&gt;ch2-lucene入门小例子&lt;br&gt;myReserch-可用的网络搜索引擎

    Lucene下调试通过的简单程序

    自已在Lucene下调试通过的简单程序, 能完成文档的的索引和搜索.&lt;br&gt;代码很简单,未加文档,不过能看懂. &lt;br&gt;在Lucene2.2.0下调试通过

    vn-lucene-analyzer:一个基于enet CaoMạnh的工作的Lucene Analyzer插件。 更改为Maven项目并更新了依赖项。 原始项目

    笔记: 该项目需要一个依赖项,即截至撰写本文时,该依赖项还不在公共Maven存储库中:&lt;dependency&gt;&lt;groupId&gt;vn.hus&lt;/groupId&gt;&lt;artifactId&gt;nlp-tokenizer&lt;/artifactId&gt;&lt;version&gt;4.1.1&lt;/version&gt;&lt;/dependency&gt; 在将其...

    LuceneDB:各种基于db的lucene

    基于KVS库的Lucene 特征 提供的Lucene Base地图。 通过使用MMap,NIO目录等,可以处理大量数据。... &lt;id&gt;ksgwr-repo&lt;/id&gt; &lt;url&gt;http://ksgwr.github.io/mvn-repo/&lt;/url&gt; &lt;/repository&gt; &lt;/repositories&gt; &lt;depende

    深入 Lucene 索引机制深入 Lucene 索引机制

    深入 Lucene 索引机制深入 Lucene 索引机制深入 Lucene 索引机制深入 Lucene 索引机制深入 Lucene 索引机制深入 Lucene 索引机制

    lucene 自定义评分

    lucene 自定义评分 实现 增加自定义的权重

Global site tag (gtag.js) - Google Analytics