首页 > 解决方案 > 加速 Spacy 处理

问题描述

我想使用 spacy (或其他东西)预处理文本数据。我下面的代码有效,但速度很慢。我只有一个 20 MB 的压缩文本文件作为演示,处理我的代码需要 10 多分钟。问题是:我需要处理大约 20 GB 压缩文本文件的文本文件,并且之前想加快我的算法。

另外,我将如何处理 20 GB 的压缩文本文件?如果我运行下面的代码,它会破坏我 16GB 的主内存。我可以逐行阅读并仍然获得良好的速度吗?

任何帮助,将不胜感激。

import zipfile
nlp = spacy.load("en_core_web_sm" , n_process=4)

with zipfile.ZipFile(filename, 'r') as thezip:
  text=thezip.open(thezip.filelist[0],mode='r').read()

text=text.decode('utf-8').splitlines()


for doc in nlp.pipe(text, disable=["tok2vec", "parser",  "attribute_ruler"], batch_size=2000):
    # Do something with the doc here
    # First remove punctuation
    tokens=[t for t in doc if t.text not in string.punctuation]
    # then remove stop words, weird unicode characters, words with digits in them
    # and empty characters. 
    tokens = [ t for t in tokens if not t.is_stop and t.is_ascii and not t.is_digit and len(t) > 1 and not any(char.isdigit() for char in t.text)]
    # remove empty lines, make it lower case and put them in sentence form
    if len(tokens):
      sentence= " ".join(token.text.lower() for token in tokens)
      # do something useful with sentence here

标签: pythonnlpspacy

解决方案


看起来您只想使用 spaCy 标记器?在这种情况下,使用nlp = spacy.blank("en")代替spacy.load,然后您可以省略 中的disable部分nlp.pipe

另外要明确的是,您使用的是 spaCy v2?

这是一个使您的代码更快、更清晰的函数:

def is_ok(tok):
    # this is much faster than `not in string.punctuation`
    if tok.is_punct: return False
    if tok.is_stop: return False
    if not tok.is_ascii: return False
    if tok.is_digit: return False
    if len(tok.text) < 2: return False
    # this gets rid of anything with a number in it
    if 'd' in tok.shape_: return False
    return True

# replace your stuff with this:
toks = [tok for tok in doc if is_ok(tok)]

一次读取一行 zip 文件应该完全没问题,因为您只是在使用标记器。


推荐阅读