Lucene 4.4. Как узнать частоту обращения по всему индексу?

Я пытаюсь вычислить значение 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 должен быть встроенный метод для этой цели. Спасибо,


person chepukha    schedule 13.12.2013    source источник


Ответы (1)


IndexReader.TotalTermFreq(Term) < / a> предоставит вам это. Ваши вызовы аналогичных методов в 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);
person femtoRgon    schedule 13.12.2013
comment
Здорово! Оно работает. Я видел этот метод раньше, но не знал, как преобразовать BytesRef обратно в Term. Кстати, знаете ли вы, почему в Lucene itr.next () return BytesRef, а не Term? и зачем использовать docFreq () для TermsEnum, если он возвращает только 1? Спасибо. - person chepukha; 14.12.2013
comment
Да, вы можете использовать TermsEnum итерацию терминов в нескольких документах или весь индекс, и в этом случае это будет более полезная статистика. Что касается того, почему он возвращает BytesRef, мне самому это было интересно. В 3.X он передал Term обратно от term(), но в 4.0 он изменился, чтобы вместо этого вернуть BytesRef. Может быть, он был переработан таким образом, что сам термин «TermsEnum` на самом деле не хранит, в каком поле был найден термин. Просто предположение, но не совсем уверен. - person femtoRgon; 14.12.2013
comment
да. Отличный ответ - person Gaurav Koradiya; 09.05.2020