2016-08-16 8 views
1

В настоящее время я использую PyLucene, но поскольку для этого нет документации, я думаю, что решение в Java для Lucene также будет (но если у кого-то есть один Python было бы еще лучше).Получите N терминов с верхними оценками TFIDF для каждого документа в Lucene (PyLucene)

Я работаю с научными публикациями, и на данный момент я извлекаю ключевые слова из них. Однако для некоторых документов просто нет ключевых слов. Альтернативой этому было бы получить N слов (5-8) с самыми высокими баллами TFIDF.

Я не знаю, как это сделать, а также , когда. К тому времени, когда я имею в виду: я должен сказать Lucene на этапе индексирования для вычисления этих значений, это можно сделать при поиске индекса.

То, что я хотел бы иметь для каждого запроса будет что-то вроде этого:

Query Ranking 

Document1, top 5 TFIDF terms, Lucene score (default TFIDF) 
Document2,  "  " , "   " 
... 

Что бы также возможно является первым получить ранжирование для запроса, а затем вычислить верхние 5 TFIDF условия для каждый из этих документов.

Есть ли у кого-нибудь идеи, как мне это сделать?

ответ

1

Порывшись немного в списке рассылки, я закончил тем, что то, что я искал.

Вот метод, который я придумал:

def getTopTFIDFTerms(docID, reader): 
    termVector = reader.getTermVector(docID, "contents"); 
    termsEnumvar = termVector.iterator(None) 
    termsref = BytesRefIterator.cast_(termsEnumvar) 
    tc_dict = {}      # Counts of each term 
    dc_dict = {}      # Number of docs associated with each term 
    tfidf_dict = {}     # TF-IDF values of each term in the doc 
    N_terms = 0 
    try: 
     while (termsref.next()): 
      termval = TermsEnum.cast_(termsref) 
      fg = termval.term().utf8ToString()  # Term in unicode 
      tc = termval.totalTermFreq()    # Term count in the doc 

      # Number of docs having this term in the index 
      dc = reader.docFreq(Term("contents", termval.term())) 
      N_terms = N_terms + 1 
      tc_dict[fg]=tc 
      dc_dict[fg]=dc 
    except: 
     print 'error in term_dict' 

    # Compute TF-IDF for each term 
    for term in tc_dict: 
     tf = tc_dict[term]/N_terms 
     idf = 1 + math.log(N_DOCS_INDEX/(dc_dict[term]+1)) 
     tfidf_dict[term] = tf*idf 

    # Here I get a representation of the sorted dictionary 
    sorted_x = sorted(tfidf_dict.items(), key=operator.itemgetter(1), reverse=True) 

    # Get the top 5 
    top5 = [i[0] for i in sorted_x[:5]] # replace 5 by TOP N 

Я не знаю, почему я должен бросить termsEnum как BytesRefIterator, я получил от этого нить в списке рассылки, которые можно найти here

Надеюсь, это поможет :)

1

Если поле indexed, могут быть получены частоты документа с getTerms. Если поле имеет stored term vectors, то можно получить временные частоты с помощью getTermVector.

Я также предлагаю посмотреть на MoreLikeThis, который использует tf * idf для создания запроса, подобного документу, из которого вы можете извлечь термины.

И если вы хотите более вещий интерфейс, это была моя мотивация для lupyne:

from lupyne import engine 
searcher = engine.IndexSearcher(<filepath>) 
df = dict(searcher.terms(<field>, counts=True)) 
tf = dict(searcher.termvector(<docnum>, <field>, counts=True)) 
query = searcher.morelikethis(<docnum>, <field>) 
+0

Спасибо за ваш ответ :) В итоге я получил то, что хотел на Python. Я отправлю свой ответ, чтобы другие люди, борющиеся с PyLucene, могли это увидеть! –