【问题标题】:Lucene 4.4. How to get term frequency over all index?Lucene 4.4。如何获得所有索引的词频?
【发布时间】:2014-01-01 17:43:23
【问题描述】:

我正在尝试计算文档中每个术语的 tf-idf 值。因此,我遍历文档中的术语,并希望找到该术语在整个语料库中出现的频率以及该术语出现的文档数量。以下是我的代码:

//@param index path to index directory
//@param docNbr the document number in the index
public void readingIndex(String index, int docNbr) {
    IndexReader reader = DirectoryReader.open(FSDirectory.open(new File(index)));

    Document doc = reader.document(docNbr);         
    System.out.println("Processing file: "+doc.get("id"));

    Terms termVector = reader.getTermVector(docNbr, "contents");
    TermsEnum itr = termVector.iterator(null);
    BytesRef term = null;

    while ((term = itr.next()) != null) {               
        String termText = term.utf8ToString();                              
        long termFreq = itr.totalTermFreq();   //FIXME: this only return frequency in this doc
        long docCount = itr.docFreq();   //FIXME: docCount = 1 in all cases 

        System.out.println("term: "+termText+", termFreq = "+termFreq+", docCount = "+docCount);   
    }            

    reader.close();     
}

虽然文档说 totalTermFreq() 返回该术语在所有文档中出现的总数,但在测试时我发现它只返回 docNbr 给出的文档中该术语的频率。并且 docFreq() 总是返回 1。

如何获得一个词在整个索引中的频率?

更新 当然,我可以创建一个映射来将一个术语映射到它的频率。然后遍历每个文档以计算一个术语出现的总次数。但是,我认为 Lucene 应该为此目的提供一个内置方法。 谢谢你,

【问题讨论】:

    标签: lucene indexing tf-idf frequency-analysis


    【解决方案1】:

    IndexReader.TotalTermFreq(Term) 将为您提供。您对TermsEnum 上的类似方法的调用确实在枚举中提供了所有文档的统计信息。使用阅读器应该可以让您获得索引本身中所有文档的统计信息。比如:

    String termText = term.utf8ToString();
    Term termInstance = new Term("contents", term);                              
    long termFreq = reader.totalTermFreq(termInstance);
    long docCount = reader.docFreq(termInstance);
    
    System.out.println("term: "+termText+", termFreq = "+termFreq+", docCount = "+docCount);
    

    【讨论】:

    • 太棒了!有用。我之前看到过这种方法,但不确定如何将 BytesRef 转换回 Term。顺便说一句,你有什么见解为什么 Lucene 有 itr.next() 返回 BytesRef 而不是 Term?如果 docFreq() 只返回 1,为什么在 TermsEnum 上有 docFreq()?谢谢。
    • 是的,您可以使用 TermsEnum 迭代多个文档或整个索引上的术语,在这种情况下,它会是一个更有用的统计数据。至于为什么它会传回 BytesRef,我自己也想知道。在 3.X 中,它从 term() 传回了 Term,但在 4.0 中更改为传回 BytesRef。可能是它被重新设计了,TermEnum` 本身并没有真正存储找到该术语的字段。不过只是猜测,不太确定。
    • 是的。很好的答案
    猜你喜欢
    • 2013-10-10
    • 1970-01-01
    • 2011-11-04
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多