我希望计算目录中所有文件(最多15,000个文件)的前500个字(按出现的顺序)。我正在对包含1000个文件的小型目录进行相同的实验。对于这1000个文件,我得到了结果,但是没有保留时间效率。处理时间太长。
首先,我将所有文件合并为一个文件,即combined.txt
,这是输入文件(使用TXTcollector)。然后,我对其进行了预处理(停用词,小写字母,引理和pos标记),并借助nltk
FreqDist()
计算了前500个单词。
Combined.txt是输入文件,它包含多个用====(定界符)分隔的文本文件中的数据。
目前,我的代码在性能方面非常慢。这是因为对于一个36 Kb的文件(合并一个目录的所有文件):下面提到的代码需要4.6秒,而对于8888 MB的文件(合并一个目录的所有文件)则需要672秒的处理时间。而且,当目录大小增加时,如果时间变长,代码将变得效率低下。
注意:我正在使用Windows 10(64位),Python 3.7,我的编辑器是Sublime-text。我已经从编辑器本身计算了经过的时间。
代码如下:
import nltk
from nltk.stem.wordnet import WordNetLemmatizer
from nltk.tokenize.regexp import wordpunct_tokenize
from nltk.corpus import stopwords
from nltk.data import load
from nltk.tokenize import word_tokenize, RegexpTokenizer
_POS_TAGGER = 'taggers/maxent_treebank_pos_tagger/english.pickle'
tagger = load(_POS_TAGGER)
regexp_tagger = nltk.tag.RegexpTagger([(r'\(|\)', '--')], backoff = tagger)
def read_data():
with open("path", 'r', encoding='utf-8', errors = 'replace') as f:
raw_data = f.read()
global text
text = '\n'.join(nltk.line_tokenize(raw_data.lower()))
read_data()
def preprocess():
stop_words = set(stopwords.words("english"))
tokens = nltk.word_tokenize(text)
pos_text = regexp_tagger.tag(tokens)
names = [n.encode('utf-8') for n,pos in pos_text if (pos == 'NN' or pos == 'NNP' or pos == 'NNS' or pos == 'NNPS')]
names_text = (' '.join(map(bytes.decode, names))).strip()
tokens = [t for t in wordpunct_tokenize(names_text)]
tokens = filter(lambda x: x not in stop_words, tokens)
tokens = filter(lambda x: x.isalpha(), tokens)
tokens = filter(lambda x: len(x) > 1, tokens)
wordnet_lemmatizer = WordNetLemmatizer()
global lemmatized_tokens
lemmatized_tokens = [wordnet_lemmatizer.lemmatize(t) for t in tokens]
preprocess()
def freq_count():
fd = nltk.FreqDist(lemmatized_tokens)
print(fd.most_common(500))
freq_count()
如何在时间上获得有效的结果?