我正在研究文本分类问题,我尝试了WordNetLemmmatizer,然后是TF-IDF,CountVectorizer。现在,我正在尝试在馈送到 TF-IDF 之前使用 Spacy 清理文本。输入文件有大约 20,000 条记录,每条记录只有很少的句子。文件的总大小为 45MB。
使用WordNet进行词形还原只需要几秒钟。但是下面的代码使用Spacy花费的时间太长了。20分钟后,我的笔记本电脑被挂起来了。请告知如何优化空间以进行文本预处理和词形还原。
我正在使用Spacy 2.0.12。
import spacy
nlp = spacy.load('en', disable=['parser', 'tagger', 'ner'])
def spacy_lemma_text(text):
doc = nlp(text)
tokens = [tok.lemma_.lower().strip() for tok in doc if tok.lemma_ != '-PRON-']
tokens = [tok for tok in tokens if tok not in nltk_stopwords and tok not in punctuations]
tokens = ' '.join(tokens)
return tokens
df['spacy_lemma_text'] = df['text'].apply(spacy_lemma_text)
我想到了几种可能的解释:
-
nltk_stopwords
是一个列表,而不是一个集合,所以像tok not in nltk_stopwords
这样的检查需要线性时间而不是常量。尝试在函数定义之前添加nltk_stopwords = set(nltk_stopwords)
-
您可能正在运行其他 Spacy 模型,而不仅仅是 lemmatiser 和 tokeniser。最好明确一点(https://spacy.io/api/tokenizer 的例子(:
从 spacy.lang.en 导入英语 分词器 = 英语((。Defaults.create_tokenizer(NLP( 标记 = 分词器(u'这是一个句子'( 断言 len(令牌( == 4
- 您是否多次加载空间模型?
- 尽管这不太可能,但您可能内存不足。分页到磁盘会大大减慢您的速度。签入系统监视器/任务管理器
如果你要遍历多个文档,你应该使用spacy的nlp.pipe函数。这将允许您合并批量大小以及多线程。空间未设置为按照您建议的方式工作。
此外,我认为使用 nltk 的停用词将是一个瓶颈。如果您使用的是 spacy,请继续使用 spacy 的停用词。它们应该针对空间使用进行优化,而不是 nltk。
import spacy
from spacy.attrs import *
import numpy as np
nlp = spacy.load('en_core_web_lg')
texts = ["this is some sentence","This is the last sentence"]
max_length =10
data = np.zeros((len(texts), max_length), dtype=np.uint64)
for row, doc in enumerate(nlp.pipe(texts, n_threads=8, batch_size=10000)):
dat = doc.to_array([LEMMA, IS_STOP])
# Check to see if text length is not 0
if len(dat) > 0:
delete = np.where(dat[:, 1] == 1)
dat = np.delete(dat, delete, 0)
length = min(len(dat), max_length)
data[row, :length] = dat[:length, 0].ravel()
这将使您将空间哈希数据存储在 numpy 数组中。然后可以通过访问 spacy 的词汇表来转换此哈希数据。我现在没有时间测试这个,但我的猜测是它会快得多。希望这有帮助。