lucene评分

来源:互联网 发布:提示windows找不到aero 编辑:程序博客网 时间:2024/06/06 06:39

lucene文档:http://lucene.apache.org/core/7_1_0/

经典评分算法:Lucene的经典的向量空间模型实现

翻译:http://lucene.apache.org/core/7_1_0/core/org/apache/lucene/search/similarities/TFIDFSimilarity.html

这里写图片描述

Similarity的一个实现,用向量空间模型。

Expert: Scoring API.

TFIDFSimilarity 定义了lucene评分的各个部分。改变这些评分部分,就能很方便的改变Lucene评分。

建议阅读:Introduction To Information Retrieval, Chapter 6.

下面描述了Lucene是如何评分的,通过从下面的信息检索模型到(高效的)实现。我们首先简单的了解下VSM Score,然后是由它演变的Lucene’s Conceptual Scoring Formula,最后形成了Lucene’s Practical Scoring Function(这个直接跟Lucene的类和方法相联系的)。

Lucene组合了Boolean model (BM) of Information Retrieval 和Vector Space Model (VSM) of Information Retrieval - documents

在VSM(向量空间模型)中,文档和查询词被表示为多维空间中有权重的向量,其中,每个索引词是一个维度,这个维度的大小事TF-idf值。

VSM不需要向量的值用Tf-idf值表示,但是用Tf-idf值会使搜索结果更准确,所以Lucene使用Tf-idfTfIdf下面会详细介绍,但是现在,我们可以先这样简单理解,给一个查询词t和一篇文档xTf(t,x)根据词t在文档x中出现的次数变化(正比),idf(t)跟包含词t的文档数成反比。

查询词q和文档d的VSM评分公式是向量V(q)V(d)的余弦相似度:
这里写图片描述

其中V(q)V(d)是向量的点集,|V(q)||V(d)|是它们的欧几里得模。

注意:如果是单位向量,那么上面的公式就是它们的点集了。

Lucene完善了VSM Score的准确性和易用性:

  • 将向量V(d)归一化为单位向量,它去掉了文档长度信息。对一些文档来说去掉这个信息没有问题,例如一篇文档是有一段重复10次组成的,特别是当那个段落有不同词组成。但是如果一篇文档没有重复的段落,这可能就不好了。为了避免这个问题,采用了一个不同的文档长度正则化因子,它将一个向量正则化为单位向量,或比单位向量大:doc-len-norm(d)
  • 建立索引时,用户可以指定某些文档比其他的重要,通过设置一个参数。通过这个参数,每篇文档的得分乘以一个值doc-boost(d)
  • Lucene是基于字段的,所以每一个查询词都会应用于每个字段,文档长度正则化是根据每个字段的长度计算,除了文档权重参数,还有字段权重。
  • 在建立索引时,一个字段可以被添加好多次,所以那个字段的权重是几个部分的乘积。
  • 查询时,用户可以指定每个查询词、子查询词的权重,所以每个查询词对一篇文档贡献的得分要乘以那个查询词的权重query-boost(q)
  • 一篇文档可能包含多个查询词,但不包含全部(这是可以的)。

下面假设索引中只有一个字段,我们得到了Lucene的得分公式:
这里写图片描述

这个概念上的公式对下面两个方面进行了简化:1、查询词和文档都是有字段的;2、权重是对每个query term而不是每个query。

现在我们描述Lucene是如何实现这个概念得分公式的,从而推导出Lucene实际的得分公式。

为了高效计算得分,一些得分部分提前计算:

  1. 查询词(实际是每个分词)的权重Query-boost,当查询开始时,是已经知道的。
  2. 查询词的欧几里得模|V(q)|,在查询开始时计算,并且它是跟文档没有关系的。从查询优化角度看,为什么要归一化查询词呢?这个问题是有意义的,因为所有的得分的文档都会乘以相同的|V(q)|,所以这个归一化不会影响排名。有很好的理由保留这个归一化:

    余弦相似度可以用于九三两篇文档的相似度。可以将Lucene用于,比如:聚类,将一篇文档作为一个查询词计算和其他文档的相似度。在这种情况下,文档d3和查询词d1的得分,还有文档d3和查询词d2的得分,要有可比较性。也就是说,同一篇文档对不同查询词的得分要有可比较性。还有其他的情况可能会需要这种可比较性。这就是查询向量V(q)正则化提供的:多次查询可比较。

  3. 文档长度模doc-len-norm(d)和文档权重doc-boost(d)在建索引的时候就知道了。提前计算它们,它们的乘积也保存在索引中:norm(d)。(在下面的等式中,norm(t in d)意思是norm(field(t) in doc d)),其中field(t)是一个字段。

    Lucene的实际的得分公式是从上面推导来的。彩色公式演示了和概念公式的关系:
    这里写图片描述
    其中:
    1、tf(t in d) 是分词的词频,定义为分词t在文档d中的出现次数。对一个给定的分词,文档中出现这个词次数越多得分越高。注意:tf(t in q)=1,所以他没有出现在公式中。然而,如果查询词包含两次相同的分词,那么对一个term就会有两次term-queries,所以计算仍然是正确的(虽然不太高效)。tf(t in d)的默认计算方法在ClassicSimilarity:

    tf(t in d)=frequency(1/2)

    2、idf(t)代表反文档词频。这个值和docFreq(the term t 在多少文档中出现)成反比。这意味着越不常见的词会贡献越高的得分。idf(t)在查询词和文档中都出现了,所以公式中时平方。默认idf(t)的计算在ClassicSimilarity中是:
    idf(t)=1+log(docCount+1docFreq+1)

    3、t.getBoost()是一个查询时查询词q的分词t的权重(参考query syntax),或者通过BoostQuery设置。
    4、norm(t,d)时一个索引时权重参数,他只跟文档的一个字段中tokens数有关,短的字段贡献更高的得分。

0.079056755 = (MATCH) product of:  0.31622702 = (MATCH) sum of:    0.0070335586 = (MATCH) product of:      0.014067117 = (MATCH) sum of:        0.014067117 = (MATCH) product of:          0.028134234 = (MATCH) sum of:            0.028134234 = (MATCH) weight(tags:小说 in 13741) [DefaultSimilarity], result of:              0.028134234 = score(doc=13741,freq=1.0 = termFreq=1.0), product of:                0.0071443617 = queryWeight, product of:                  3.9379632 = idf(docFreq=1801, maxDocs=34017)                  0.0018142277 = queryNorm                3.9379632 = fieldWeight in 13741, product of:                  1.0 = tf(freq=1.0), with freq of:                    1.0 = termFreq=1.0                  3.9379632 = idf(docFreq=1801, maxDocs=34017)                  1.0 = fieldNorm(doc=13741)          0.5 = coord(1/2)      0.5 = coord(1/2)    0.30919346 = (MATCH) product of:      0.6183869 = (MATCH) sum of:        0.6183869 = (MATCH) product of:          1.2367738 = (MATCH) sum of:            1.2367738 = (MATCH) weight(itemName:小说 in 13741) [DefaultSimilarity], result of:              1.2367738 = score(doc=13741,freq=1.0 = termFreq=1.0), product of:                0.14979284 = queryWeight, product of:                  8.256562 = idf(docFreq=23, maxDocs=34017)                  0.018142277 = queryNorm                8.256562 = fieldWeight in 13741, product of:                  1.0 = tf(freq=1.0), with freq of:                    1.0 = termFreq=1.0                  8.256562 = idf(docFreq=23, maxDocs=34017)                  1.0 = fieldNorm(doc=13741)          0.5 = coord(1/2)      0.5 = coord(1/2)  0.25 = coord(2/8)0.032049756 = (MATCH) product of:  0.12819903 = (MATCH) sum of:    0.008821609 = (MATCH) product of:      0.017643219 = (MATCH) sum of:        0.017643219 = (MATCH) sum of:          0.007813523 = (MATCH) weight(tags:有声 in 21325) [DefaultSimilarity], result of:            0.007813523 = score(doc=21325,freq=4.0 = termFreq=4.0), product of:              0.006735104 = queryWeight, product of:                3.712381 = idf(docFreq=2257, maxDocs=34017)                0.0018142277 = queryNorm              1.160119 = fieldWeight in 21325, product of:                2.0 = tf(freq=4.0), with freq of:                  4.0 = termFreq=4.0                3.712381 = idf(docFreq=2257, maxDocs=34017)                0.15625 = fieldNorm(doc=21325)          0.009829696 = (MATCH) weight(tags:小说 in 21325) [DefaultSimilarity], result of:            0.009829696 = score(doc=21325,freq=5.0 = termFreq=5.0), product of:              0.0071443617 = queryWeight, product of:                3.9379632 = idf(docFreq=1801, maxDocs=34017)                0.0018142277 = queryNorm              1.3758677 = fieldWeight in 21325, product of:                2.236068 = tf(freq=5.0), with freq of:                  5.0 = termFreq=5.0                3.9379632 = idf(docFreq=1801, maxDocs=34017)                0.15625 = fieldNorm(doc=21325)      0.5 = coord(1/2)    0.11937742 = (MATCH) product of:      0.23875484 = (MATCH) sum of:g        0.23875484 = (MATCH) sum of:          0.11861164 = (MATCH) weight(productName:有声 in 21325) [DefaultSimilarity], result of:            0.11861164 = score(doc=21325,freq=1.0 = termFreq=1.0), product of:              0.092776835 = queryWeight, product of:                5.1138473 = idf(docFreq=555, maxDocs=34017)                0.018142277 = queryNorm              1.2784618 = fieldWeight in 21325, product of:                1.0 = tf(freq=1.0), with freq of:                  1.0 = termFreq=1.0                5.1138473 = idf(docFreq=555, maxDocs=34017)                0.25 = fieldNorm(doc=21325)          0.12014319 = (MATCH) weight(productName:小说 in 21325) [DefaultSimilarity], result of:            0.12014319 = score(doc=21325,freq=1.0 = termFreq=1.0), product of:              0.093373895 = queryWeight, product of:                5.146757 = idf(docFreq=537, maxDocs=34017)                0.018142277 = queryNorm              1.2866893 = fieldWeight in 21325, product of:                1.0 = tf(freq=1.0), with freq of:                  1.0 = termFreq=1.0                5.146757 = idf(docFreq=537, maxDocs=34017)                0.25 = fieldNorm(doc=21325)      0.5 = coord(1/2)  0.25 = coord(2/8)
原创粉丝点击