2013-12-13 36 views
6

我正試圖計算文檔中每個術語的tf-idf值。因此,我遍歷文檔中的術語,並希望查找整個語料庫中該術語的頻率以及術語出現的文檔數量。以下是我的代碼:Lucene 4.4。如何獲得所有指數的術語頻率?

//@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應該有一個內置的方法來達到這個目的。 謝謝,

回答

12

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); 
+0

太棒了!有用。我之前看到過這種方法,但不知道如何將BytesRef轉換回Term。順便說一句,你有任何洞察,爲什麼Lucene有itr.next()返回BytesRef而不是Term?爲什麼在TermsEnum上只有docFreq()返回1?謝謝。 – chepukha

+0

是的,你可以有一個'TermsEnum'迭代多個文檔或整個索引的條款,在這種情況下,這將是一個更有用的統計。至於爲什麼它傳回BytesRef,我在想我自己。在3.X中,它從'term()'傳遞了一個'Term',但它在4.0中改變以代之以傳回'BytesRef'。可能是因爲它被重新設計的方式使得TermsEnum本身並不真正存儲該術語被發現的字段。只是猜測,儘管並不確定。 – femtoRgon

相關問題