【问题标题】:Spacy - preprocessing & lemmatization taking long timeSpacy - 预处理和词形还原需要很长时间
【发布时间】:2018-09-19 02:22:16
【问题描述】:

我正在研究文本分类问题,我尝试过 WordNetLemmmatizer,然后是 TF-IDF、CountVectorizer。现在,我正在尝试在输入 TF-IDF 之前使用 Spacy 清理文本。输入文件有大约 20,000 条记录,每条记录只有几个句子。文件的总大小为 45MB。

使用 WordNet 进行词形还原只需几秒钟。但是下面使用 Spacy 的代码花费了太长时间。 20 分钟后,我的笔记本电脑挂了。请建议如何优化 Spacy 以进行文本预处理和词形还原。

我正在使用 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)

【问题讨论】:

    标签: nlp text-processing spacy lemmatization


    【解决方案1】:

    我想到了几种可能的解释:

    • nltk_stopwords 是一个列表,而不是一个集合,所以像 tok not in nltk_stopwords 这样的检查需要线性时间而不是常数。尝试在函数定义之前添加nltk_stopwords = set(nltk_stopwords)

    • 您可能正在运行其他 spacy 模型,而不仅仅是 lemmatiser 和 tokeniser。最好是明确的(来自https://spacy.io/api/tokenizer 的示例):

    从 spacy.lang.en 导入英语 tokenizer = English().Defaults.create_tokenizer(nlp) tokens = tokenizer(u'这是一个句子') 断言 len(tokens) == 4
    • 您是否多次加载 spacy 模型?
    • 虽然不太可能,但您可能内存不足。分页到磁盘会大大减慢您的速度。检查您的系统监视器/任务管理器

    【讨论】:

    • 正如我所建议的,我已经尝试使用nltk_stopwords = set(nltk_stopwords),但仍然需要很长时间并且没有得到结果。作为预处理的一部分,我试图对单词进行词形还原并加入它们并添加到新的 pandas 数据框列。而且我只在代码中加载一次 spacy 模型。
    【解决方案2】:

    如果您要遍历多个文档,则应该使用 spacy 的 nlp.pipe 函数。这将允许您合并批量大小以及多线程。 Spacy 没有按照您建议的方式工作。

    此外,我认为使用 nltk 的停用词将成为瓶颈。如果您使用 spacy,请继续使用 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 的词汇表来转换此哈希数据。我现在没有时间测试这个,但我猜它会快得多。希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多