lucene修改相似度实现:去掉文本长度和重复词的影响 - sling2007的日志 - 网易博客

文档的分值代表了该文档在特定查询词下对应的相关性高低,他关联着信息检索向量空间模型中的向量夹角的接近度。一个文档越与查询词相关,得分越高。分值计算公式如下:

score(q,d)   =   coord(q,d) · queryNorm(q) ·   ∑ ( tf(t in d) · idf(t)2 · t.getBoost() · norm(t,d) ) 
                                                                      t in q  

其中

tf(t in d)

这个值衡量着Term在文档中出现的频率,也就是词频。关键词在文档中出现的次数越多,得分越高,这个值在DefaultSimilarity的计算公式如下(词频的平方根):

tf(t in d)   =    frequency½

idf(t)

代表着该词的逆词频,这个值衡量了该词在整个文档库中出现的频度。这意味着,一个词出现的越少,根据香农的信息公示,他越珍稀。同时将贡献更多的分值给总 分值。默认的计算公式如下(其中numDocs代表整个文档的数量,docFreq代表了含有Term t的文档数量):

                                   numDocs 
idf(t) =    1 + log    ( –––––––––   )  
                                  docFreq+1 

coord(q,d)

一次查询可能查询好多条件,产生多个子查询。文档命中的子查询数越多,说明越符合查询,得分应该越高。

比如title:中国 || keyword:中国 || author:作者,这个查询有三个子查询,命中一个条件即为0.333,两个就是0.6667,都命中则为1

coord(q,d) = overlap / maxOverlap

queryNorm(q)

这个标准化因子用于在多个查询器中进行比较。它并不影响文档的排名。它的主要作用在于多个查询器返回的结果进行比较,甚至是结果来自多个索引时。这是搜索时的权重因子,当给查询器设置权重时就是通过这个因子进行影响的。默认的实现公式如下:

                                                                                                           1 
queryNorm(q)   =   queryNorm(sumOfSquaredWeights)   =   –––––––––––––– 
                                                                                         sumOfSquaredWeights½

其中的sumOfSquaredWeights的计算公式如下:(可以清晰的看到获取query的boost,当没给查询器设置值时,默认为1,不起作用)

sumOfSquaredWeights   =   q.getBoost() 2 ·   ∑ ( idf(t) · t.getBoost() ) 2  
                                                                      t in q

t.getBoost()

该值是一个搜索时权重因子,可以在查询时给不同的Term设置不同的权重,可以通过lucene语法(具体参见我翻译的另外一篇文章:hi.baidu.com/expertsearch/blog/item/8d4f7d355a2e413c5ab5f547.html),也可以通过setBost()函数,注意,在多Term查询器中,是没有获取单一Term权重的函数的,所以如果需要获取,只能调用相应的子查询器函数的getBoost()函数。

norm(t,d)

封装了一些索引时因子以及长度因子。
Document boost - 在索引时,添加到Index前可以通过doc.setBoost()设置,衡量了Document的重要程度。. 
Field boost - 在将字段加入到文档前可以通过调用field.setBoost()来设置字段的权重。
lengthNorm(field) - 该值在将文档添加到索引时,根据所有文档中特定字段的Term数来计算。所以默认更短的字段将贡献更多的分值。

                                                   1 
lengthNorm(field) =   –––––––––––––– 
                                           numTerms½

当文档加入索引时,以上因子将相乘,如果一个文档中有多个同名的字段,那么将多个多同的权重也相乘。

norm(t,d)   =   doc.getBoost() · lengthNorm(field) ·   ∏ f.getBoost() 
                                                                       field f in d named as t

可 是还有件值得注意的事情,这个值在索引时计算完毕后将编码为一个Byte存储起来,在搜索时,再从文件中读取出该值并解码成float。在这个过程中,可 能会造成精度的缺失,并不能保证decode(encode(x)) = x,比如,有可能decode(encode(0.89)) = 0.75,同样值得注意的是,在搜索时改变此值已经太晚了。例如,用一个不同于DefaultSimilarity的实现。

阅读全文……

你可能感兴趣的:(Lucene)