阿帕奇>Lucene公司
 

Apache Lucene-得分

介绍

Lucene得分是我们都喜欢Lucene的核心原因。它的速度极快,几乎对用户隐藏了所有的复杂性。简而言之,它是有效的。至少,那是,直到它不起作用,或者没有像人们期望的那样起作用工作。然后我们就只能深入研究Lucene的内部结构或寻求帮助java-user@lucene.apache.org找出为什么一个文档包含五个查询词得分低于仅包含一个查询词的不同文档。

虽然本文档不会回答您的具体评分问题,但希望它能为您指出可以帮助您了解Lucene得分的原因。

Lucene评分使用以下组合信息的向量空间模型(VSM)检索布尔模型以确定给定文档与用户查询的相关性。一般来说,VSM背后的理念是查询词出现在文档中的时间术语在集合中所有文档中出现的次数,与文档是对查询的。它使用布尔模型首先缩小需要根据查询规范中布尔逻辑的使用进行评分。Lucene还添加了一些功能和对该模型的改进,以支持布尔和模糊搜索,但它本质上仍然是一个基于VSM的系统。有关VSM和IR的一些有价值参考,请参阅Lucene Wiki IR参考.

本文件的其余部分将涵盖评分基础知识以及如何改变您的相似性。接下来,它将涵盖您可以使用的方法在中定制Lucene内部组件更改您的得分--专家级别它提供了实现您自己的查询类和相关功能。最后,我们将在附录.

评分

评分在很大程度上取决于文档索引的方式,因此,理解索引很重要(请参见Apache Lucene-入门指南和Lucene文件格式继续本节之前。)还假设读者知道如何使用Searcher.explain(查询查询,int文档)功能,这对解释为什么返回分数有很大帮助。

字段和文档

在Lucene中,我们评分的对象是文件。文档是集合属于领域。每个字段都有关于如何它被创建和存储(即标记化、非标记化、原始数据、压缩等)请注意,Lucene计分在Fields上起作用,然后将结果合并为返回Documents。这是重要的是,两个文档的内容完全相同,但其中一个文档在两个字段中包含内容而一个字段中的另一个字段由于长度归一化会返回同一查询的不同分数(假设默认相似性(在字段上)。

分数提升

Lucene允许通过在多个级别上“提升”来影响搜索结果:

  • 文档级别提升-索引时-通过调用document.setBoost()在将文档添加到索引之前。
  • 文档的字段级别提升-索引时-通过调用字段.setBoost()将字段添加到文档之前(以及将文档添加到索引之前)。
  • 查询级别提升-在搜索期间,通过对查询子句设置boost,调用查询.setBoost().

索引时间的增加经过预处理以提高存储效率并写入目录(写入文档时)为单字节(!),如下所示:对于文档的每个字段,该字段的所有提升(即该单据中相同字段名称下的所有提升)相乘。结果乘以文档的增强,并乘以“字段长度规范”值表示该文档中该字段的长度(因此较短的字段会自动增加)。结果被解码为单个字节(当然会有一些精度损失)并存储在目录中。索引时有效的相似性对象计算字段的长度形式。

规范的1字节表示的这种组合(即字段boost&docboost&field-length-norm的索引时间乘法)在中有很好的描述可字段.setBoost().

类的静态方法相似性:编码规范()decodeNorm().由于精度损失,无法保证解码(编码(x))=x,例如,解码(编码(0.89))=0.75。在评分(搜索)时,该标准被纳入文档评分中作为范数(t,d),如中的公式所示相似性.

了解评分公式

该评分公式在相似性类。请花点时间研究这个公式,因为它包含了很多关于Lucene评分工作的基础知识,尤其是词查询.

大局

好的,那么tf-idf公式和相似性对理解Lucene得分的基本知识很有帮助,但真正推动Lucene评分的是the use and interactions between the查询类,由中的每个应用程序创建响应用户的信息需求。

在这方面,Lucene提供了多种查询实现,其中大多数在org.apache.lucene.search网站包裹。这些实现可以通过多种方式进行组合,以提供复杂的查询功能以及有关匹配在文档集合中发生的位置的信息。这个查询下面的部分重点介绍了一些更重要的Query类。有关其他选项的信息,请参阅程序包摘要有关实施的详细信息您自己的Query类,请参阅更改您的得分--专家级下面。

创建查询并提交给索引搜索器,计分过程开始。(请参阅附录算法部分,了解有关过程的更多注释。)在一些基础设施设置之后,控件最终传递给重量实现及其记分员实例。对于任何类型的布尔查询,计分由布尔权重2(链接指向包含BooleanWeight2内部类的ViewVC BooleanQuery java代码)或布尔权重(链接指向ViewVC BooleanQuery java代码,其中包含BooleanWeight内部类)。

假设使用布尔权重2BooleanScorer2是通过将所有的记分员来自BooleanQuery的子子句。当要求BooleanScorer2评分时,它会根据类型将其工作委托给内部评分器查询中的子句。这个内部记分器基本上循环子记分器并对分数进行求和由每个计分员提供,同时考虑coord()分数。

查询类

有关查询类的信息,请参阅搜索包javadocs

更改相似性

改变Lucene评分特征的方法之一是改变相似度因子。有关的信息如何做到这一点,请参阅搜索包javadocs

改变你的得分——专家级

在更深层次上,可以通过实现自己的Query类(以及相关的评分类)来影响评分有关如何执行此操作,请参阅搜索包javadocs

附录

算法

本节主要是关于逐步完成评分过程的注释,用作前几节的肥料。

在典型的搜索应用程序中查询传递给搜索者,开始计分过程。

进入搜索器后收藏家用于对搜索结果进行评分和排序。搜索涉及以下重要对象:

  1. 这个重量查询的对象。Weight对象是查询的内部表示允许搜索者重用查询。
  2. 发起呼叫的搜索者。
  3. A类过滤器用于限制结果集。注意,过滤器可能为空。
  4. A类排序对象,用于指定如果标准的基于分数的排序方法不是渴望的。

假设我们没有排序(因为排序没有影响原始Lucene分数),我们调用Searcher的一种搜索方法,传入重量由Searcher.createWeight(Query)创建的对象,过滤器以及我们想要的结果数量。这个方法返回一个热门文档对象,这是搜索结果的内部集合。搜索器创建一个TopScoreDocCollector排名靠前并将其与Weight、Filter一起传递给另一个专家搜索方法(有关收藏家机制,请参见搜索者.)TopDocCollector使用优先级队列以收集搜索的热门结果。

如果正在使用筛选器,则会进行一些初始设置以确定要包含哪些文档。否则,我们要求重量记分员对于索引管理器我们继续调用上的score方法记分员.

最后,我们实际上要对一些文件进行评分。记分法采用收集器(很可能是TopScoreDocCollector或TopFieldCollector)并开展业务。当然,这里涉及到一些事情。这个记分员由返回的重量对象取决于提交的查询类型。在大多数具有多个查询词,这个记分员将成为布尔记分2(有关更改的信息,请参阅自定义评分部分。)

假设使用BooleanScorer2记分器,我们首先初始化Coordinator,它用于应用坐标()系数。然后我们根据查询的必需、可选和禁止部分获取内部记分器。使用此内部记分器,布尔记分器2继续到基于Scorer#next()方法的while循环中。next()方法前进到下一个文档匹配查询。这是一个Scorer类中的抽象方法,因此被所有派生的实现。如果您有一个简单的OR查询您的内部记分器很可能是DisjunctionSumScorer,它本质上是将记分器组合在一起的来自手术室条款的副计分员。