Lucene:评分机制

使用 Hits 对象可以得到某个文档的得分。本文将对评分和 Lucene 的评分机制进行介绍。

理解评分的概念

评分其实是搜索引擎中很重要的一个概念。通常情况下,当用户输入一个关键字,搜索引擎接收到信息后即可开始进行检索。对于检索到的结果,需要按一定的顺序返回给用户。因此,需要引入一种机制来对检索结果进行排序,以便更加合理地将结果返回给用户。

评分机制就是对检索结果按某种标准进行评估,然后按分值的高低来对结果进行排序。同时,对于一个商用的搜索引擎来说,评分机制是其收入来源的重要部分。例如某公司向搜索引擎缴纳一定数量的费用,则该搜索引擎就将其搜索结果中关于该公司的部分公值加大,以便能在检索结果返回给用户时让该公司获得更加靠前的位置。这种做法增加了用户浏览该公司网页和产品的机会,无形之中也给该公司带来了更大的社会影响和潜在商机。因此,评分机制从各方面来说都是相当重要的。

2  Lucene评分算法

那么,Lucene中是如何确定各个Document评分的呢?下面将详细介绍该功能的基本原理。

文档的得分是在用户进行检索时实时计算出来的。如果在建立索引时就已经将每个文档的得分计算好,那么当用户输入任何关键字时,得分最高的文档都会被排在返回结果的最前面,这显然是不合理的。

因此,所有文档的得分应当都与用户输入的关键字有关系,而且是实时运算的结果。其实,所谓得分,可以简单理解成是某个关键字在某文档中出现的频率。

11-6所示的公式就是Lucene用于计算某个关键字在对应于某文档的得分。

11-6  Lucene的得分公式

Lucene得分公式中,已经包含了影响文档评分的各种因素。在表11.1中详细介绍了每一种因素对搜索结果评分的影响作用。

11-1                                                 Lucene得分公式的解释

   

在公式中的作用描述

tf(t in d)

词条t在文档d中出现的词频

idf( t )

词条t在文档中的倒排词频

boost(t.field in d)

在索引过程中设置的字段参数

lengthNorm(t.field in d)

字段的标准化值,表明在字段中存储了多少词条,这个数值是在索引过程中计算出来的,并且也存储在索引中

coord(q, d)

协调因子,它的计算是基于文档d中所包含的所有可供查询的词条数

queryNorm(q)

在给出每个查询条目的方差和后,计算某查询的标准化值

 

改变文档的得分

除了内置的得分算法外,Lucene还提供了一种方法来改变每个文档的得分。

在代码11.3中,初始化Document后,使用了DocumentsetBoost方法来改变一下文档的boost因子。这种做法的实际目的是将文档的得分乘以这个因子,以这个新的数作为文档的得分。

代码11.3  使用Boost的例子

public static void buildIndex() throws Exception {

     //生成新的Document对象,下同

    Document doc1 = new Document();

    doc1.add(Field.Text("contents", "word1 word"));

    doc1.add(Field.Keyword("path", "path//document1.txt"));

     //改变文档的boost因子,下同

    doc1.setBoost(1.0f);

   

    Document doc2 = new Document();

    doc2.add(Field.Text("contents", "word2 word"));

    doc2.add(Field.Keyword("path", "path//document2.txt"));

    doc2.setBoost(0.1f);

   

    Document doc3 = new Document();

    doc3.add(Field.Text("contents", "word3 word"));

    doc3.add(Field.Keyword("path", "path//document3.txt"));

    doc3.setBoost(0.5f);

   

    Document doc4 = new Document();

    doc4.add(Field.Text("contents", "word4 word"));

    doc4.add(Field.Keyword("path", "path//document4.txt"));

    doc4.setBoost(0.2f);

   

    Document doc5 = new Document();

    doc5.add(Field.Text("contents", "word5 word"));

    doc5.add(Field.Keyword("path", "path//document5.txt"));

    doc5.setBoost(0.8f);

   

    Document doc6 = new Document();

    doc6.add(Field.Text("contents", "word6 word"));

    doc6.add(Field.Keyword("path", "path//document6.txt"));

    doc6.setBoost(0.1f);

   

    Document doc7 = new Document();

    doc7.add(Field.Text("contents", "word7 word"));

    doc7.add(Field.Keyword("path", "path//document7.txt"));

    doc7.setBoost(0.5f);

   

    Document doc8 = new Document();

    doc8.add(Field.Text("contents", "word8 word"));

    doc8.add(Field.Keyword("path", "path//document8.txt"));

    doc8.setBoost(0.7f);

   

    Document doc9 = new Document();

    doc9.add(Field.Text("contents", "word9 word"));

    doc9.add(Field.Keyword("path", "path//document9.txt"));

    doc9.setBoost(0.2f);

   

    Document doc10 = new Document();

    doc10.add(Field.Text("contents", "word10 word"));

    doc10.add(Field.Keyword("path", "path//document10.txt"));

    doc10.setBoost(0.4f);

   

    Document doc11 = new Document();

    doc11.add(Field.Text("contents", "word11 word"));

    doc11.add(Field.Keyword("path", "path//document11.txt"));

   

    Document doc12 = new Document();

    doc12.add(Field.Text("contents", "word12 word"));

    doc12.add(Field.Keyword("path", "path//document12.txt"));

   

    IndexWriter writer = new IndexWriter("c://index", new StandardAnalyzer(), true);

    //添加到索引中,下同

    writer.addDocument(doc1);

    writer.addDocument(doc2);

    writer.addDocument(doc3);

    writer.addDocument(doc4);

    writer.addDocument(doc5);

    writer.addDocument(doc6);

    writer.addDocument(doc7);

    writer.addDocument(doc8);

    writer.addDocument(doc9);

    writer.addDocument(doc10);

    writer.addDocument(doc11);

    writer.addDocument(doc12);

   

    writer.close();

  }

代码11.3的运行效果,如图11-7所示。

11-7  改变Boost后的运行效果

从图11-7可以看出,每个文档的分值已经发生了变化,其中,由于文档11112boost值和原来一样,因此分值排在最前面,显示的顺序也到了最前面。而其他的文档则已经因为boost值发生了改变,显示的顺序也发生了变化。可以看到,排在最后一个位置的文档是文档6,它的boost值为0.1,所以分值也成了原来的十分之一

像代码11.3中这样通过Boost值来改变分值的方式相当灵活,可以很有效的达到对文档顺序进行控制的目的。不过,这仍然不是一种理想的方式,因为在建立索引时还需要人为地指定每个文档的boost值。有关排序的更高级话题,将在后面的章节来说明。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值