为 Lucene (PyLucene) 中的每个文档获取 TFIDF 得分最高的 N 个术语

Get N terms with top TFIDF scores for each documents in Lucene (PyLucene)

我目前正在使用 PyLucene,但由于没有它的文档,我想 Java 中的 Lucene 解决方案也可以(但如果有人在 Python 中有一个解决方案,它甚至更好)。

我正在与科学出版物打交道,目前,我正在检索这些出版物的关键字。但是,对于某些文档,根本没有关键字。另一种方法是获取 TFIDF 分数最高的 N 个单词 (5-8)。

我不确定该怎么做,也何时。什么时候,我的意思是:我是否必须在索引阶段告诉 Lucene 来计算这些值,在搜索索引时是否可以这样做。

我希望每个查询的内容如下所示:

Query Ranking

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

也可以先检索查询的排名,然后计算每个文档的前 5 个 TFIDF 术语。

有人知道我该怎么做吗?

如果一个字段是indexed, document frequencies can be retrieved with getTerms. If a field has stored term vectors, term frequencies can be retrieved with getTermVector.

我还建议查看 MoreLikeThis,它使用 tf*idf 创建类似于文档的查询,您可以从中提取术语。

如果您想要更像 Python 的界面,那是我 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>)

在邮件列表中进行了一番挖掘后,我终于找到了我要找的东西。

这是我想出的方法:

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[=14 中找到=]

希望这会有所帮助:)