在进行Lucene的搜索过程解析之前,有必要单独的一张把Lucene score公式的推导,各部分的意义阐述一下。因为Lucene的搜索过程,很重要的一个步骤就是逐步的计算各部分的分数。
Lucene的打分公式非常复杂,如下:
在推导之前,先逐个介绍每部分的意义:
- t:Term,这里的Term是指包含域信息的Term,也即title:hello和content:hello是不同的Term
- coord(q,d):一次搜索可能包含多个搜索词,而一篇文档中也可能包含多个搜索词,此项表示,当一篇文档中包含的搜索词越多,则此文档则打分越高。
- queryNorm(q):计算每个查询条目的方差和,此值并不影响排序,而仅仅使得不同的query之间的分数可以比较。其公式如下:
- tf(t in d):Term t在文档d中出现的词频
- idf(t):Term t在几篇文档中出现过
- norm(t, d):标准化因子,它包括三个参数:
- Document boost:此值越大,说明此文档越重要。
- Field boost:此域越大,说明此域越重要。
- lengthNorm(field) = (1.0 / Math.sqrt(numTerms)):一个域中包含的Term总数越多,也即文档越长,此值越小,文档越短,此值越大。
- 各类Boost值
- t.getBoost():查询语句中每个词的权重,可以在查询中设定某个词更加重要,common^4 hello
- d.getBoost():文档权重,在索引阶段写入nrm文件,表明某些文档比其他文档更重要。
- f.getBoost():域的权重,在索引阶段写入nrm文件,表明某些域比其他的域更重要。
以上在Lucene的文档中已经详细提到,并在很多文章中也被阐述过,如何调整上面的各部分,以影响文档的打分,请参考有关Lucene的问题(4):影响Lucene对文档打分的四种方式一文。
然而上面各部分为什么要这样计算在一起呢?这么复杂的公式是怎么得出来的呢?下面我们来推导。
首先,将以上各部分代入score(q, d)公式,将得到一个非常复杂的公式,让我们忽略所有的boost,因为这些属于人为的调整,也省略coord,这和公式所要表达的原理无关。得到下面的公式:
然后,有Lucene学习总结之一:全文检索的基本原理中的描述我们知道,Lucene的打分机制是采用向量空间模型的:
我们把文档看作一系列词(Term),每一个词(Term)都有一个权重(Term weight),不同的词(Term)根据自己在文档中的权重来影响文档相关性的打分计算。
于是我们把所有此文档中词(term)的权重(term weight) 看作一个向量。
Document = {term1, term2, …… ,term N}
Document Vector = {weight1, weight2, …… ,weight N}
同样我们把查询语句看作一个简单的文档,也用向量来表示。
Query = {term1, term 2, …… , term N}
Query Vector = {weight1, weight2, …… , weight N}
我们把所有搜索出的文档向量及查询向量放到一个N维空间中,每个词(term)是一维。
我们认为两个向量之间的夹角越小,相关性越大。
所以我们计算夹角的余弦值作为相关性的打分,夹角越小,余弦值越大,打分越高,相关性越大。
余弦公式如下:
下面我们假设:
查询向量为Vq = <w(t1, q), w(t2, q), ……, w(tn, q)>
文档向量为Vd = <w(t1, d), w(t2, d), ……, w(tn, d)>
向量空间维数为n,是查询语句和文档的并集的长度,当某个Term不在查询语句中出现的时候,w(t, q)为零,当某个Term不在文档中出现的时候,w(t, d)为零。
w代表weight,计算公式一般为tf*idf。
我们首先计算余弦公式的分子部分,也即两个向量的点积:
Vq*Vd = w(t1, q)*w(t1, d) + w(t2, q)*w(t2, d) + …… + w(tn ,q)*w(tn, d)
把w的公式代入,则为
Vq*Vd = tf(t1, q)*idf(t1, q)*tf(t1, d)*idf(t1, d) + tf(t2, q)*idf(t2, q)*tf(t2, d)*idf(t2, d) + …… + tf(tn ,q)*idf(tn, q)*tf(tn, d)*idf(tn, d)
在这里有三点需要指出:
- 由于是点积,则此处的t1, t2, ……, tn只有查询语句和文档的并集有非零值,只在查询语句出现的或只在文档中出现的Term的项的值为零。
- 在查询的时候,很少有人会在查询语句中输入同样的词,因而可以假设tf(t, q)都为1
- idf是指Term在多少篇文档中出现过,其中也包括查询语句这篇小文档,因而idf(t, q)和idf(t, d)其实是一样的,是索引中的文档总数加一,当索引中的文档总数足够大的时候,查询语句这篇小文档可以忽略,因而可以假设idf(t, q) = idf(t, d) = idf(t)
基于上述三点,点积公式为:
Vq*Vd = tf(t1, d) * idf(t1) * idf(t1) + tf(t2, d) * idf(t2) * idf(t2) + …… + tf(tn, d) * idf(tn) * idf(tn)
所以余弦公式变为:
下面要推导的就是查询语句的长度了。
由上面的讨论,查询语句中tf都为1,idf都忽略查询语句这篇小文档,得到如下公式
所以余弦公式变为:
下面推导的就是文档的长度了,本来文档长度的公式应该如下:
这里需要讨论的是,为什么在打分过程中,需要除以文档的长度呢?
因为在索引中,不同的文档长度不一样,很显然,对于任意一个term,在长的文档中的tf要大的多,因而分数也越高,这样对小的文档不公平,举一个极端的例子,在一篇1000万个词的鸿篇巨著中,"lucene"这个词出现了11次,而在一篇12个词的短小文档中,"lucene"这个词出现了10次,如果不考虑长度在内,当然鸿篇巨著应该分数更高,然而显然这篇小文档才是真正关注"lucene"的。
然而如果按照标准的余弦计算公式,完全消除文档长度的影响,则又对长文档不公平(毕竟它是包含了更多的信息),偏向于首先返回短小的文档的,这样在实际应用中使得搜索结果很难看。
所以在Lucene中,Similarity的lengthNorm接口是开放出来,用户可以根据自己应用的需要,改写lengthNorm的计算公式。比如我想做一个经济学论文的搜索系统,经过一定时间的调研,发现大多数的经济学论文的长度在8000到10000词,因而lengthNorm的公式应该是一个倒抛物线型的,8000到 10000词的论文分数最高,更短或更长的分数都应该偏低,方能够返回给用户最好的数据。
在默认状况下,Lucene采用DefaultSimilarity,认为在计算文档的向量长度的时候,每个Term的权重就不再考虑在内了,而是全部为一。
而从Term的定义我们可以知道,Term是包含域信息的,也即title:hello和content:hello是不同的Term,也即一个Term只可能在文档中的一个域中出现。
所以文档长度的公式为:
代入余弦公式:
再加上各种boost和coord,则可得出Lucene的打分计算公式。
相关推荐
lucene打分公式解释,非常详细,帮助理解搜索ranking.
它的核心功能之一是根据用户查询与文档的相关性进行打分,这个过程涉及到一个关键的概念——评分公式。本文将深入探讨Lucene的评分公式,理解其工作原理,并探讨如何通过自定义评分公式来影响搜索结果的排序。 首先...
文档中还提及了Lucene打分公式的数学推导。评分算法中使用的一个重要数学模型是向量空间模型(Vector Space Model,VSM),它根据词项的权重和文档间的相似度进行计算,影响着最终的搜索结果。 总体而言,该文档为...
而搜索过程的解析涉及到打分公式的数学推导和搜索过程的代码实现细节。 整个Lucene的工作流程表明,它将文档处理、索引构建、搜索算法和打分机制集成为一个功能强大的全文搜索引擎,其内部实现包含了复杂的算法和...
然而,Lucene 的默认评分机制可能无法满足所有场景下的需求,这就需要我们对其进行自定义评分来实现特定的权重分配。本文将深入探讨如何在 Lucene 中实现自定义评分,以及它对提高搜索质量的重要性。 在 Lucene 中...
这一过程涉及到了《Lucene打分公式的数学推导》,包括TF-IDF、BM25等算法,这些分数决定了搜索结果的排序。 最后,我们要关注的是《Lucene的段合并》。段是Lucene索引的基本单位,随着时间的推移,新的段会被添加到...
6. **打分公式推导** Lucene的打分公式基于TF-IDF(词频-逆文档频率)模型,同时考虑了词频、文档长度、查询词的稀有程度等因素。影响打分的四种主要方式包括词频、文档频率、字段长度 norm 和查询权重。 7. **...
lucene,lucene教程,lucene讲解。 为了对文档进行索引,Lucene 提供了五个基础的类 public class IndexWriter org.apache.lucene.index.IndexWriter public abstract class Directory org.apache.lucene.store....
lucene3.0 lucene3.0 lucene3.0 lucene3.0 lucene3.0
#### 六、Lucene 打分公式的数学推导 Lucene 使用TF-IDF(Term Frequency-Inverse Document Frequency)算法来计算文档的相关性得分。TF-IDF 是一种统计方法,用来评估一个词条在一个文档中的重要程度。公式如下: ...
综上所述,**Lucene 3.0 原理与代码分析**覆盖了全文检索的基础理论、Lucene 的总体架构、索引文件格式、索引过程、段合并过程、打分公式、搜索过程、查询语法、查询对象、分词器等多个方面,为开发者提供了深入理解...
2. **搜索算法**:Lucene实现了布尔、短语、模糊、评分等高级搜索算法,使得用户可以灵活地构造复杂的查询条件。 3. **高性能**:Lucene通过内存缓存、位向量和优化的数据结构来提高搜索速度。同时,它支持多线程...
Lucene打分公式的数学推导则涉及到算法层面的内容,这些算法是根据文档和查询语句的相关性进行文档排序的基础。Lucene提供了多种打分算法,如TF-IDF、BM25等,这些算法会计算出每个词对文档的相关性贡献度,并据此给...
《Lucene in Action》是关于Apache Lucene的权威指南,这本书深入浅出地介绍了全文搜索引擎的构建和优化。Lucene是一个高性能、全文本搜索库,它允许开发人员在应用程序中轻松实现复杂的搜索功能。这本书主要面向...
搜索过程涉及到了评分函数、排序等高级特性。 5. **内存缓存与过滤器**:Lucene提供`Filter`类来处理如文档过滤、高亮显示等功能。同时,`BitSet`类用于在内存中高效地存储和操作文档集。 6. **倒排索引的优化**:...
5. **排序和评分**:Lucene提供TF-IDF等算法对搜索结果进行评分,可以根据评分进行排序。 6. **结果展示**:将搜索结果转换为用户友好的格式展示给用户。 在实际应用中,Lucene通常与Solr或Elasticsearch等工具结合...
3. **评分(Scoring)**:Lucene使用TF-IDF算法来评估文档与查询的相关性,给出一个评分。评分高的文档在搜索结果中优先显示。 4. **结果集(Hit)**:搜索返回一个`TopDocs`对象,包含匹配文档的总数和最高评分的...
7. **评分(Scoring)**:Lucene会根据文档与查询的相关性来为搜索结果打分,最相关的文档会首先返回。 **二、Lucene的工作流程** 1. **创建索引**:首先,你需要创建一个Analyzer来定义如何分词,然后使用...
**Lucene 2.0 API 和 Lucene 3.0 API 深度解析** Lucene 是一个由 Apache 软件基金会开发的全文搜索引擎库,它为开发者提供了在 Java 应用程序中实现高性能、可扩展的全文搜索功能的能力。Lucene 的 API 设计得相当...