#python-3.x #spacy
#python-3.x #spacy
Вопрос:
Я маркирую десятки тысяч документов с помощью SpaCy. В среднем на каждый документ уходит около 5 секунд. Есть предложения по ускорению токенизатора?
Некоторая дополнительная информация:
- Входные файлы представляют собой текстовые файлы с символами новой строки
- Средний размер файла составляет около 400 КБ
- Токены каждого входного файла записываются в новую строку выходного файла (хотя я могу изменить это, если это поможет увеличить скорость)
- Существует 1655 стоп-слов
- Выходной файл является подачей в fasttext
Ниже приведен мой код:
from pathlib import Path, PurePath
from time import time
st = time()
nlp = en_core_web_sm.load(disable = ['ner', 'tagger', 'parser', 'textcat'])
p = Path('input_text/').glob('*.txt')
files = ['input_text/' x.name for x in p if x.is_file()]
#nlp = spacy.load('en-core-web-sm')
stopwords_file = 'stopwords.txt'
def getStopWords():
f = open(stopwords_file, 'r')
stopWordsSet = f.read()
return stopWordsSet
stopWordsSet = getStopWords()
out_file = 'token_results.txt'
for file in files:
#print (out_file)
with open(file, encoding="utf8") as f:
st_doc = time()
for line in f:
doc = nlp(line)
for token in doc:
if (not token.text.lower() in stopWordsSet
and not token.is_punct and not token.is_space and not token.like_num
and len(token.shape_)>1):
tup = (token.text, '|', token.lemma_)
appendFile = open(out_file, 'a', encoding="utf-8")
appendFile.write(" " tup[0])
print((time() -st_doc), 'seconds elasped for', file)
appendFile.write('n')
appendFile.close()
print((time()-st)/60, 'minutes elasped')
Ответ №1:
-
Основная проблема: откройте выходной файл один раз и оставьте его открытым до конца вашего скрипта. Многократное закрытие и повторное открытие и поиск до конца все большего текстового файла будет происходить чрезвычайно медленно.
-
Преобразуйте стоп-слова в фактическое
set()
. В противном случае вы будете искать каждый токен в длинной строке, содержащей весь файл, что случайно соответствует частичным словам и намного, намного медленнее, чем проверка принадлежности к set. -
Используйте nlp.pipe () или для токенизации просто nlp.tokenizer.pipe(), чтобы немного ускорить объемную часть. С кучей коротких документов в одно предложение это, кажется, не имеет большого значения. Гораздо быстрее маркировать один большой документ, чем обрабатывать каждую строку как отдельный документ, но хотите ли вы это сделать, зависит от того, как структурированы ваши данные. Если вы просто создаете токены, вы можете увеличить максимальный размер документа (
nlp.max_length
), если вам нужно.
texts = f.readlines()
docs = nlp.tokenizer.pipe(texts)
for doc in docs:
for token in doc:
...