加速 SpaCy 分词器

Bri*_*itt 3 python-3.x spacy

我正在使用 SpaCy 对数万个文档进行标记。平均每个文档大约需要 5 秒。关于如何加速标记器有什么建议吗?

一些附加信息:

  • 输入文件是带有换行符的文本文件
  • 文件平均大小约为400KB
  • 每个输入文件的标记都会写入输出文件中的新行(尽管如果有助于提高速度,我可以更改它)
  • 有 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')
Run Code Online (Sandbox Code Playgroud)

aab*_*aab 5

  1. 主要问题:打开输出文件一次并保持打开状态直到脚本结束。反复关闭并重新打开并查找更大的文本文件的末尾将会非常慢。

  2. 将停用词读入实际的set(). 否则,您将在包含整个文件的长字符串中搜索每个标记,这会意外匹配部分单词,并且比检查集合成员资格慢得多。

  3. 使用 nlp.pipe() 或仅使用 nlp.tokenizer.pipe() 进行标记化,以稍微加快spacy部分的速度。对于一堆简短的一句话文档来说,这似乎并没有产生很大的区别。标记一个大型文档比将每一行视为一个单独的文档要快得多,但您是否要这样做取决于数据的结构方式。如果您只是进行标记化,则可以nlp.max_length根据需要增加最大文档大小 ( )。

texts = f.readlines()
docs = nlp.tokenizer.pipe(texts)

for doc in docs:
    for token in doc:
        ...
Run Code Online (Sandbox Code Playgroud)