Lucene打分公式的推导

栏目: 编程工具 · 发布时间: 7年前

内容简介:Lucene打分公式的推导

lucene 介绍

lucene是一个高效的,基于 Java 的全文检索库,利用lucene可以很方便加入到现有应用中来提供全文检索的功能。比如分布式搜索引擎Elastic Search底层的搜索就是使用lucene。(全文检索是从大量的现有的文档中,搜索出与查询语句最相关的文档集的过程)

为了更高效的完成全文检索的过程,lucene使用倒排索引来完成查询词到文档查找。lucene全文检索的过程主要由创建索引和搜索索引,本文主要介绍文档相关性 排序 部分。

lucene中相关概念:

  • document:lucene存储的基本单位,类似于 mysql 数据库中一条记录
  • field:document中一个字段,类似于mysql数据库表中一个字段

note:本文分析的lucene版本为5.1.0

倒排索引模型

Lucene打分公式的推导

左边一列是按照一定顺序排列的经过分词处理后的Term,称为字典;每个词都指向的包含该词的文档组成链表称为倒排表。

lucene处理流程

Lucene打分公式的推导

创建索引的过程:

  • 准备待索引的原文档,数据来源可能是文件、数据库或网络
  • 对文档的内容进行分词组件处理,形成一系列的Term
  • 索引组件对文档和Term处理,形成字典和倒排表

搜索索引的过程:

  • 对查询语句进行分词处理,形成一系列Term
  • 根据倒排索引表查找出包含Term的文档,并进行合并形成符合结果的文档集
  • 比对查询语句与各个文档相关性得分,并按照得分高低返回

评分公式推导

空间向量模型

Lucene打分公式的推导

lucene的评分计算模型是基于VSM,即空间向量模型,但实现上稍有不同。

空间向量模型的逻辑就是将每个文档看做是由N个Term组成的向量,文档间相关性就是两个向量的在N维空间内的夹角大小,由于两个向量的之间的夹角越小,相关性就越大,所以就可以将夹角的余弦值作为相关性的得分,夹角越小,余弦值越大,相关性越大。

VSM(空间向量模型) 计算公式:

Lucene打分公式的推导

比如索引中的文档

Document Vector = {Weight1, Weight2, ..., Weight N},查询语句也可以看做是一个文档,查询文档:Query Vector = {Weight1, Weight2, ..., Weight N},Weight是某个Term的权重,N是所有文档包括查询文档在内的所有Term总数,如果文档不包含某个Term,则文档向量中Term的Weight为0。

Term的权重计算

影响一个Term在文档中权重大小的因素主要有两个:

  • Term Frequency(tf):即该Term在该文档中出现的次数,tf越大说明越重要;
  • Document Frequency(df):即有多少个文档包含了该Term,df越小说明越重要;

计算公式:

Lucene打分公式的推导

以上是Term weight计算的典型实现,Lucene实现于此稍有不同,使用的是tf(t ind ) * idf(t)。

lucene公式推导

Lucene打分公式的推导

我们首先计算余弦公式的分子部分,也即两个向量的点积:

Lucene打分公式的推导
Lucene打分公式的推导

在这里有三点需要指出:

  • 由于是点积,则此处的 t1, t2, ..., tn 只有查询语句和文档的并集有非零值,只在查询语句出现的或只在文档中出现的 Term 的项的值为零。
  • 在查询的时候,很少有人会在查询语句中输入同样的词,因而可以假设 tf(t, q)都=1
  • idf 是指 Term 在多少篇文档中出现过,其中也包括查询语句这篇小文档,因而 idf(t, q)和 idf(t, d)其实是一样的,是索引中的文档总数加一,当索引中的文档总数足够大的时候,查询语句这篇小文档可以忽略,因而可以假设 idf(t, q) = idf(t, d) = idf(t)
Lucene打分公式的推导

下面推导查询语句的长度

由上面的讨论,查询语句中 tf 都为 1,idf 都忽略查询语句这篇小文档,得到如下公式:

Lucene打分公式的推导

接下来推导文档的长度

为什么在打分过程中,需要除以文档的长度呢? 因为在索引中,不同的文档长度不一样,很显然,对于任意一个 term,在长的文档中的 tf 要大的多,因而分数也越高,这样对小的文档不公平,举一个极端的例子,在一篇 1000 万 个词的鸿篇巨著中,“lucene” 这个词出现了 11 次,而在一篇 12 个词的短小文档中,“lucene” 这个词出现了 10 次,如果不考虑长度在内,当然鸿篇巨著应该分数更高,然而显然这篇小文档才是真正关注“lucene” 的。然而如果按照标准的余弦计算公式,完全消除文档长度的影响,则又对长文档不公平(毕竟它是包含更多的信息),偏向于首先返回短小的文档的,这样在实际应用中使得搜索结果 很难看。

在默认状况下,Lucene 采用 DefaultSimilarity,认为在计算文档的向量长度的时候,每个 Term 的权重就不再考虑在内了,而是全部为一。

Lucene打分公式的推导

再加上各种 boost 和 coord,则可得出 Lucene 的计算公式

lucene计算公式

Lucene打分公式的推导

coord(q,d):得分因子,score factor,一个文档中包含越多的查询Term词,则该文档的得分越高,对应lucene类 TFIDFSimilarity.coord(int overlap, int maxOverlap)

Lucene打分公式的推导

queryNorm(q):归一化因子,normalizing factor,使得不同查询间的得分具有可比性,但并不会影响文档的排序,对应lucene类 TFIDFSimilarity.queryNorm(float sumOfSquaredWeights)

Lucene打分公式的推导

tf(t in d):Term在文档d中出现的次数,对应lucene类 TFIDFSimilarity.tf(float freq)

Lucene打分公式的推导

idf(t):Term的逆文档频率,即一个Term在所有文档中出现的次数越多,重要性越小,对应lucene类 TFIDFSimilarity.idf(long docFreq, long numDocs)

Lucene打分公式的推导

norm(t,d):封装了文档字段field的权重和field内容长度因子,在index时计算,对应lucene类 TFIDFSimilarity.computeNorm(FieldInvertState state)

Lucene打分公式的推导

lengthNorm:field内容长度因子,field字段内容长度越短,则值越大,对应lucene类TFIDFSimilarity.lengthNorm(FieldInvertState state);

Lucene打分公式的推导

q.getBoost():查询的权重(默认值为1.0)

t.getBoost():子查询的权重(默认值为1.0)

f.getBoost():filed字段的权重(认值为1.0)

设置Query权重

BooleanQuery parentQuery=new BooleanQuery();
parentQuery.setBoost(1.0f);

TermQuery termQuery=new TermQuery(new Term("search"));
termQuery.setBoost(2.0f);
parentQuery.add(termQuery,BooleanClause.Occur.SHOULD);

termQuery=new TermQuery(new Term("掘金"));
termQuery.setBoost(2.0f);
parentQuery.add(termQuery,BooleanClause.Occur.SHOULD);

reader=DirectoryReader.open(index_directory);
IndexSearcher searcher=new IndexSearcher(reader);

TopScoreDocCollector collector=TopScoreDocCollector.create(5);
searcher.search(parentQuery,collector);
ScoreDoc[]hits=collector.topDocs().scoreDocs;

设置Field权重

Document document = new Document();
TextField questionField = new TextField(FieldConstants.QUESTION, question, Field.Store.YES);
questionField.setBoost(2.0f);
TextField answerField = new TextField(FieldConstants.ANSWER, question, Field.Store.YES);
answerField.setBoost(2.0f);

document.add(questionField);
document.add(answerField);
documents.add(document);

note:从lucene4.0之后就不在支持设置document的boost,应该使用filed


以上所述就是小编给大家介绍的《Lucene打分公式的推导》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

设计原本

设计原本

Frederick P. Brooks, Jr. / InfoQ中文站、王海鹏、高博 / 机械工业出版社 / 2011-1-1 / 55.00元

无论是软件开发、工程还是建筑,有效的设计都是工作的核心。《设计原本:计算机科学巨匠Frederick P. Brooks的思考》将对设计过程进行深入分析,揭示进行有效和优雅设计的方法。 本书包含了多个行业设计者的特别领悟。Frederick P. Brooks, Jr.精确发现了所有设计项目中内在的不变因素,揭示 了进行优秀设计的过程和模式。通过与几十位优秀设计者的对话,以及他自己在几个设计......一起来看看 《设计原本》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具