了解Apache Lucene的评分算法

时间:2015-06-17 07:39:58

标签: search solr lucene full-text-search hibernate-search

我现在正在使用Hibernate Search几个月,但我仍然无法消化它带来的相关性。我对它返回的结果总体感到满意,但即使是最简单的测试也不能满足我的期望。

首次测试使用术语频率(tf)。 数据:

  • 字词
  • 单词单词
  • 单词单词word
  • 单词单词单词
  • 单词单词word word word

我得到的结果:

  1. 单词单词word
  2. 单词单词单词
  3. 单词单词word word word
  4. 字词
  5. 单词单词
  6. 我真的对这种得分效果感到困惑。我的查询非常复杂,但由于此测试没有涉及任何其他字段,因此可以简化如下: booleanjunction.should(phraseQuery)。应该(keywordQuery)。应该(fuzzyQuery)

    我的分析仪如下:

     StandardFilterFactory
     LowerCaseFilterFactory
     StopFilterFactory
     SnowballPorterFilterFactory for english
    

    我的解释对象 https://jsfiddle.net/o51kh3og/

1 个答案:

答案 0 :(得分:4)

评分计算非常复杂。在这里,您必须从the primal equation开始:

  

得分(q,d)=坐标(q,d)·queryNorm(q)·Σ(tf(t in d)·   idf(t)2·t.getBoost()·norm(t,d))

正如你所说,你有tf这意味着术语频率及其值是术语频率的平方根。

但是在这里,正如您在your explanation中看到的那样,您还有norm(又名fieldNorm),用于fieldWeight计算。我们举个例子:

  

eklavya eklavya eklavya eklavya eklavya

4.296241 = fieldWeight in 177, product of:
  2.236068 = tf(freq=5.0), with freq of:
    5.0 = termFreq=5.0
  4.391628 = idf(docFreq=6, maxDocs=208)
  0.4375 = fieldNorm(doc=177)
  

eklavya

4.391628 = fieldWeight in 170, product of:
  1.0 = tf(freq=1.0), with freq of:
    1.0 = termFreq=1.0
  4.391628 = idf(docFreq=6, maxDocs=208)
  1.0 = fieldNorm(doc=170)

此处,eklavya的分数高于另一个,因为fieldWeighttfidffieldNorm的乘积。对于eklavya文档,最后一个更高,因为他只包含一个术语。

如上文所述:

  

lengthNorm - 将文档添加到索引中时计算出来的   根据文档中此字段的标记数,所以   较短的字段对分数的贡献更大。

字段中的字词越多,fieldNorm就越低。 请注意value of this field

因此,总而言之,在这里你有一个完美的组合,可以理解分数不仅仅根据频率计算,还可以计算你所在领域的术语数。