我在我的文档语料库中使用来自here的TF-IDF代码,这是3份PDF文档,每篇文档大约270页。
# Calculating the Term Frequency, Inverse Document Frequency score
import os
import math
from textblob import TextBlob as tb
def tf(word, blob):
return tb(blob).words.count(word) / len(tb(blob).words)
def n_containing(word, bloblist):
return sum(1 for blob in bloblist if word in tb(blob).words)
def idf(word, bloblist):
return math.log(len(bloblist) / (1 + n_containing(word, bloblist)))
def tfidf(word, blob, bloblist):
return tf(word, blob) * idf(word, bloblist)
# Stemming the articles
from nltk.stem import PorterStemmer
port = PorterStemmer()
bloblist = []
doclist = [pdf1, pdf2, pdf3] # Defined earlier, not showing here as it is not relevant to the question
for doc in doclist:
bloblist.append(port.stem(str(doc)))
# TF-IDF calculation on the stemmed articles
for index, blob in enumerate(bloblist):
print("Top words in document {}".format(index + 1))
scores = {word: tfidf(word, blob, bloblist) for word in tb(blob).words}
sorted_words = sorted(scores.items(), key=lambda x: x[1], reverse=True)
i=1
for word, score in sorted_words[:5]:
print("\tWord "+str(i)+": {}, TF-IDF: {}".format(word, round(score, 5)))
i+=1
问题是,它只是继续运行,没有显示Top words in document 1
以外的任何内容。为什么计算scores
需要这么长时间?我现在已经运行了一个小时,代码也没有终止。之前我尝试了50个奇数txt文件的代码,这些文件的长度要短得多(比如平均2-3段),并且能够立即显示TF-IDF分数。 3个270页的文档有什么问题?
答案 0 :(得分:1)
从粗略的一瞥中突然出现一些东西,
1)在没有看到方法tb如何实现的情况下,您似乎正在为每个单词调用tb(blob)
。也许从tb(blob)
为每个单词返回一次对象来制作一个对象会加快速度。
2)nltk
有自己的tfidf
实现,它将更加优化,可以加快速度。
3)你可以使用numpy
而不是vanilla python进行实现,这肯定会加快速度。但即使这样,最好还是缓存结果并使用它们而不是调用可能很重的函数多次。
答案 1 :(得分:1)
正如另一个回答提到的那样,你过多地呼叫tb(blob)
;它看起来像一个N字的文件你称之为N ^ 2次。这总是很慢。你需要做这样的改变:
for index, blob in enumerate(bloblist):
print("Top words in document {}".format(index + 1))
# XXX use textblob here just once
tblob = tb(blob)
scores = {word: tfidf(word, tblob, bloblist) for word in tblob.words}
sorted_words = sorted(scores.items(), key=lambda x: x[1], reverse=True)
i=1
for word, score in sorted_words[:5]:
print("\tWord "+str(i)+": {}, TF-IDF: {}".format(word, round(score, 5)))
i+=1
您还需要更改tfidf功能,以便他们每次都使用tblob
而不是调用tb(blob)
。