为 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 中找到=]
希望这会有所帮助:)
我目前正在使用 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 中找到=]
希望这会有所帮助:)