2012-02-08 16 views
16

He indexado un conjunto de documentos con lucene. También he almacenado DocumentTermVector para cada contenido del documento. Escribí un programa y obtuve el término vector de frecuencia para cada documento, pero ¿cómo puedo obtener el vector tf-idf de cada documento?Extraer vectores tf-idf con lucene

Aquí está mi código que da salida a las frecuencias de términos en cada documento:

Directory dir = FSDirectory.open(new File(indexDir)); 
    IndexReader ir = IndexReader.open(dir); 
    for (int docNum=0; docNum<ir.numDocs(); docNum++) { 
     System.out.println(ir.document(docNum).getField("filename").stringValue()); 
     TermFreqVector tfv = ir.getTermFreqVector(docNum, "contents"); 
     if (tfv == null) { 
     // ignore empty fields 
     continue; 
     } 
     String terms[] = tfv.getTerms(); 
     int termCount = terms.length; 
     int freqs[] = tfv.getTermFrequencies(); 

     for (int t=0; t < termCount; t++) { 
     System.out.println(terms[t] + " " + freqs[t]); 
     } 
    } 

¿Hay alguna función buit-in en Lucene para que haga eso?


Nadie ha ayudado, y lo hice por mí mismo:

Directory dir = FSDirectory.open(new File(indexDir)); 
    IndexReader ir = IndexReader.open(dir); 

    int docNum; 
    for (docNum = 0; docNum<ir.numDocs(); docNum++) { 
     TermFreqVector tfv = ir.getTermFreqVector(docNum, "title"); 
     if (tfv == null) { 
       // ignore empty fields 
       continue; 
     } 
     String tterms[] = tfv.getTerms(); 
     int termCount = tterms.length; 
     int freqs[] = tfv.getTermFrequencies(); 

     for (int t=0; t < termCount; t++) { 
      double idf = ir.numDocs()/ir.docFreq(new Term("title", tterms[t])); 
      System.out.println(tterms[t] + " " + freqs[t]*Math.log(idf)); 
     } 
    } 

¿hay alguna manera de encontrar el número de identificación de cada término?


Nadie ha ayudado, y lo hice por mí mismo otra vez:

List list = new LinkedList(); 
    terms = null; 
    try 
    { 
     terms = ir.terms(new Term("title", "")); 
     while ("title".equals(terms.term().field())) 
     { 
     list.add(terms.term().text()); 
     if (!terms.next()) 
      break; 
     } 
    } 
    finally 
    { 
     terms.close(); 
    } 
    int docNum; 
    for (docNum = 0; docNum<ir.numDocs(); docNum++) { 
     TermFreqVector tfv = ir.getTermFreqVector(docNum, "title"); 
     if (tfv == null) { 
       // ignore empty fields 
       continue; 
     } 
     String tterms[] = tfv.getTerms(); 
     int termCount = tterms.length; 
     int freqs[] = tfv.getTermFrequencies(); 

     for (int t=0; t < termCount; t++) { 
      double idf = ir.numDocs()/ir.docFreq(new Term("title", tterms[t])); 
      System.out.println(Collections.binarySearch(list, tterms[t]) + " " + tterms[t] + " " + freqs[t]*Math.log(idf)); 
     } 
    } 

Respuesta

2

Es probable que no va a encontrado un vector TF-IDF. Pero como ya lo ha hecho, puede calcular IDF a mano. Probablemente sea mejor usar el DefaultSimilarity (o cualquier implementación de similitud que esté usando) para calcularlo por usted.

En cuanto a la ID de término, creo que actualmente no se puede. At least not until Lucene 4.0, vea this.

+0

¡Pero todos los términos están ordenados y tienen un número único en un índice (su orden)! ¿Cómo puedo acceder a ese número para cada término? – orezvani

+0

¡Resolví esta parte! – orezvani

+0

Si su índice es estático (no agrega más documentos después del índice de lote inicial) puede usar este orden como ID de término. Primer término, ID: 0, segundo término, ID: 1, etc. ... Si la necesidad de los ID de términos es externa a lucene, también podría crear estos ID fuera de este. Iterar los Términos y almacenarlos por separado de Lucene con su correspondiente identificación asignada (por usted). –