Lucene.Net笔记--逆向文档频率(IDF)

本博文通过分析Lucene代码,阐述了其计算逆向文档频率的完整过程。

先上 评分公式 如下:

Σt int q(tf(t in d) × idf(t)2 × boost(t.field in d) × lengthNorm(t.field in d)) × coord(q, d) × queryNorm(q)

逆向文档频率(IDF)

定义:逆向文件频率,指定的项(Term)在整个倒排索引中出现的频率。

Lucene.Net.Search名称空间下的Weight.GetSumOfSquaredWeights()方法用来计算逆向文件频率。对于最简单的搜索(TermQuery),它在Lucene.Net.Search.TermQuery.TermWeight类中实现:

public override float GetSumOfSquaredWeights()
{
    var idf = this.TermQuery
        .GetSimilarity(this.Searcher)
        .IdfExplain(this.TermQuery.Term, this.Searcher)
        .Idf; 
    var queryWeight = idf*this.TermQuery.Boost;    // Boost是在创建TermQuery时,由客户程序(如用户)传入的。
    return queryWeight*queryWeight;    // square it 
} 

Lucene.Net.Search.Weight类是Lucene.Net.SearchQuery类的包装类,其派生类的构造函数一般为

public DerivedWeight(DerivedQuery enclosingInstance, Searcher searcher) 
{
}

Weight类型总是包含对应的QuerySearcher的相关引用。

TermQuery.GetSimilarity(this.Searcher)返回一个“相似度模型”,如果该方法的参数为一个Lucene.Net.Searcher.IndexSearcher,而非Lucene.Net.Searcher.MultiSearcher(多索引搜索),则返回的Similarity其实是一个默认实现:Lucene.Net.Search.DefaultSimilaritySimilarity及其派生类是评分公式和核心实现类。

考虑一般情况,上述代码中的Similarity.IdfExplain(Term, Searcher).Idf实际上是用默认的评分公式(DefaultSimilarity实现)来计算某次搜索中的某个项的逆向文档频率。IdfExplain方法返回一个Lucene.Net.Search.Explanation.IDFExplanation抽象类,该抽象类主要用于生成评分注释,对于Idf值本身来说,该类仅起了一个Idf参数传递作用。该抽象类没有任何成员上的实现,

using system;

namespace Lucene.Net.Search;

public class Explanation
{
    public abstract class IDFExplanation
    {
        public abstract float Idf{get;}
        public abstract string Explan();
    }
}

在Lucene.net中的仅有的两个实现是Lucene.Net.Search.Similarity.AnonymousClassIDFExplanation1Lucene.Net.Search.Similarity.AnonymousClassIDFExplanation3,分别用于“TermQuery”和“PhraseQuery”。下面来看一下Similarity.IdfExplain(Term, Searcher)的具体实现

public virtual IDFExplanation IdfExplain(Term term, Searcher searcher) 
{
    int df = searcher.DocFreq(term); //计算有多少文档包含了参数中的Term
    int max = searcher.MaxDoc; //整个索引中文档的总数
    float idf = (float) (System.Math.Log(max / (double) (df + 1)) + 1.0); 
    return new AnonymousClassIDFExplanation1(df, max, idf2, this); 
} 

以上就是逆向文档频率的完整计算过程。将计算过程写入一个函数,如下所示:

using system;
using Lucene.Net.Search;

public override float GetSumOfSquaredWeights()
{
    int df = this.Searcher.DocFreq(this.TermQuery.Term);//计算有多少文档包含了当前的Term
    int totalDocNum = this.Searcher.maxDoc;//整个索引中文档的总数。
    float idf = (float) (Math.Log(totalDocNum / (double) (df + 1)) + 1.0); 
    var queryWeight = idf*this.TermQuery.Boost;    //Boost是在创建TermQuery时,由客户程序(如用户)传入的。
    return queryWeight*queryWeight;
} 
原文地址:https://www.cnblogs.com/crayfish/p/6000039.html