В настоящее время я пытаюсь рассчитать матрицу tf-idf для терминов в индексе lucene. Я пытаюсь сделать это с помощью следующей функции:
public Table<Integer, BytesRef, Double> tfidf(String field) throws IOException, ParseException{
//variables in complete context
int totalNoOfDocs = reader.numDocs(); //total no of docs
HashBasedTable<Integer, BytesRef, Double> tfidfPerDocAndTerm = HashBasedTable.create(); //tfidf value for each document(integer) and term(Byteref) pair.
//variables in loop context
BytesRef term; //term as BytesRef
int noOfDocs; //number of documents (a term occours in)
int tf; //term frequency (of a term in a doc)
double idf; //inverse document frequency (of a term in a doc)
double tfidf; //term frequency - inverse document frequency value (of a term in a doc)
Terms termVector; //all terms of current doc in current field
TermsEnum termsEnum; //iterator for terms
DocsEnum docsEnum; //iterator for documents (of current term)
List<Integer> docIds = getDocIds(totalNoOfDocs); //get internal documentIds of documents
try {
for(int doc : docIds){
termVector = reader.getTermVector(doc, field); //get termvector for document
termsEnum = termVector.iterator(null); //get iterator of termvector to iterate over terms
while((term = termsEnum.next()) != null){ //iterate of terms
noOfDocs = termsEnum.docFreq(); //add no of docs the term occurs in to list
docsEnum = termsEnum.docs(null, null); //get document iterator for this term (all documents the term occours in)
while((doc = docsEnum.nextDoc()) != DocIdSetIterator.NO_MORE_DOCS){ //iterate over documents - computation of all tf-idf values for this term
tf = docsEnum.freq(); //get termfrequency of current term in current doc
idf = Math.log((double)totalNoOfDocs / (double)noOfDocs); //calculate idf
tfidf = (double) tf * idf; //caculate tfidf
tfidfPerDocAndTerm.put(doc, term, tfidf); //add tf-idf value to matrix
}
}
}
} catch (IOException ex) {
Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
}
return tfidfPerDocAndTerm;
}
Проблема в следующем: noOfDocs = termsEnum.docFreq(); всегда возвращает 1. Даже если есть очевидные термины, которые встречаются более чем в одном документе (проверено вручную, напечатав «термин»).
Я также узнал, что docsEnum я получаю с помощью: docsEnum = termsEnum.docs(null, null); всегда содержит только 1 документ (doc 0).
При создании индекса я использовал стандартный анализатор со списком стоп-слов, поэтому все термины в нижнем регистре.
Так в чем моя проблема? :/
Спасибо за вашу помощь!