还没读TFIDFSimilarity的代码,读了一下lucene的文档,没有特复杂,感觉还是非常严谨的。
对于查询q和文档d,如果查询为纯token查询,套用向量空间模型(VSM),相似度度量使用余弦,另外再加一个coord(q,d)即d中满足q中must和should查询条件个数的度量(预计通常是m / n了)。cos直接用向量点积除以两个向量的模(euclidean norm)。
cos = v(q) * v(d) / (|v(q)| * |v(d)|)
sim = coord(q,d) * cos
当中:
v(q) = (idf(t),...)
v(d) = (tf,...)
当中tf并不是简单的term freq,而是其平方根,这非常可能是为了让其模刚好是doclen。
idf = 1 + log(numDocs / (1 + docFreq),因此这个公式里面,tf的数值被弱化了。
在文档的lucene practical scoring formula,当中对于|v(q)|的计算被归到queryNorm上(queryNorm = 1 / |v(q)|) ,对于|v(d)|的计算被归到norm(t, d)中(norm(t,d) = 1 / |v(d)|)。
queryNorm中有个query bootst值,偶认为对于纯tf idf计算(无论query多长总是能够展开成一级)没什么意义,并且对最后总分没影响,仅仅是能够对不同query的结果进行比較。
queryNorm中另一个t.getBoost(),这个事实上非常重要,能够是一个主要调參的地方,由于term boost能够包括field boost的信息,所以能够在search时进行设置,有了term boost,v(q)变为:
v(q) = (idf(t) * t.getBoost(),...)
|v(d)|的计算归结到norm(t,d)中,当中引入field.getBoost另整个公式不严谨,由于点积中没有乘以这个数字,模也不是正常计算的了,再加上t.getBoost()就能够包括field boost信息,还有每一个field保存的norm值仅仅用一个字节表示,精度非常差,我认为这个norm值不有用,倒不如直接用lengthNorm(我倒是非常好奇没有norm值,lucene怎么处理的)。
參考文献:
http://lucene.apache.org/core/4_0_0/core/org/apache/lucene/search/similarities/TFIDFSimilarity.html
Lucene TFIDF打分公式,布布扣,bubuko.com
原文地址:http://www.cnblogs.com/blfshiye/p/3761311.html