2013-12-13 18 views
6

Ich versuche, Tf-IDF-Wert jedes Begriffs in einem Dokument zu berechnen. Ich durchlaufe also die Begriffe in einem Dokument und möchte die Häufigkeit des Begriffs im gesamten Korpus und die Anzahl der Dokumente finden, in denen der Begriff erscheint. Im Anschluss ist mein Code:Lucene 4.4. Wie erhält man die Termhäufigkeit über den gesamten Index?

//@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();  
} 

Obwohl die Dokumentation sagt totalTermFreq() über alle Dokumente, die die Gesamtzahl der Vorkommen dieser Begriff zurückgibt, wenn bei der Prüfung ich es nur gefunden in dem Dokument von docNbr gegeben, um die Frequenz des Begriffs zurück . und docFreq() geben immer 1 zurück.

Wie kann ich die Häufigkeit eines Begriffs über den gesamten Index erhalten?

Aktualisieren Natürlich kann ich eine Karte erstellen, um einen Ausdruck zu seiner Häufigkeit zuzuordnen. Dann durchlaufen Sie jedes Dokument, um die Gesamtzahl der Zeit zu zählen, die ein Begriff auftritt. Ich dachte jedoch, dass Lucene eine eingebaute Methode für diesen Zweck haben sollte. Vielen Dank,

Antwort

12

IndexReader.TotalTermFreq(Term) wird dies für Sie bereitstellen. Ihre Aufrufe der ähnlichen Methoden auf der TermsEnum liefern tatsächlich die Statistiken für alle Dokumente in der Aufzählung. Mit dem Reader sollten Sie die Statistiken für alle Dokumente im Index selbst erhalten. Etwas wie:

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

Großartig! Es klappt. Ich habe diese Methode schon einmal gesehen, war mir aber nicht sicher, wie ich BytesRef wieder in Term umwandeln konnte. Übrigens, hast du einen Einblick, warum Lucene itr.next() ByteRef zurückgibt und nicht Term? und warum docFreq() auf TermsEnum, wenn es nur 1 zurückgibt? Vielen Dank. – chepukha

+0

Ja, Sie könnten ein 'TermsEnum' haben, das über Terme für mehrere Dokumente oder einen ganzen Index iteriert, in diesem Fall wäre es eine nützlichere Statistik. Soweit es den BytesRef zurückgibt, habe ich mich selbst gefragt. In 3.X gab es einen 'Term' zurück von' term() ', aber er änderte sich in 4.0, um stattdessen' BytesRef' zurück zu geben. Könnte sein, dass es so neu gestaltet wurde, dass das TermsEnum selbst nicht wirklich speichert, in welchem ​​Feld der Begriff gefunden wurde. Nur eine Vermutung, aber nicht wirklich sicher. – femtoRgon