Эффективный ли счетчик времени (500 лучших слов) большого каталога в Python? - PullRequest
0 голосов
/ 26 ноября 2018

Я хочу вычислить первые 500 слов (с точки зрения вхождения) для всех файлов (максимум 15 000 файлов) каталога.Я экспериментирую с маленькими каталогами, содержащими 1000 файлов.Для этих 1000 файлов я получаю результаты, но эффективность времени не сохраняется.Обработка занимает слишком много времени.

Во-первых, я объединил все файлы в один файл, а именно combined.txt, который является входным файлом (используя TXTcollector ).Затем я предварительно обработал его (стоп-слова, строчные буквы, леммы и теги pos) и вычислил 500 лучших слов с помощью nltk FreqDist().

Combined.txt является входным файлом и содержит данные из нескольких текстовых файлов, разделенных ==== (разделителем).

В настоящее время мой код очень медленный с точки зрения производительности.Это связано с тем, что для файла размером 36 КБ (объединяющего все файлы каталога): приведенный ниже код занимает 4,6 с, а для файла 8888 МБ (объединяющего все файлы каталога) для обработки требуется 672 с.И, кроме того, когда размер будет увеличен, код будет неэффективным с точки зрения времени, то же самое происходит, если размер файла в каталоге увеличивается.

Примечание. Я использую Windows10, 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()

Как добиться эффективных результатов с точки зрения времени?

...