如何加速spaCy的词形还原?

12

我在NLP流程的第一步中使用spaCy(版本2.0.11)进行词形还原,但不幸的是它需要非常长的时间。 明显地,这是我的处理流程中最慢的部分,我想知道是否有改进的方法。 我正在使用以下管道:

nlp.pipe(docs_generator, batch_size=200, n_threads=6, disable=['ner'])

在一台8核的机器上,我已经验证这台机器正在使用所有的内核。

对于大约3百万个短文本、总计近2GB的语料库进行词形还原和写入磁盘需要接近24小时。这合理吗?

我尝试禁用了处理管道的几个部分,并发现这破坏了词形还原(解析器、标注器)。

除命名实体识别之外,默认处理管道中是否有其他不需要词形还原的部分?

还有其他加速spaCy词形还原过程的方法吗?

附言:

似乎文档没有列出解析管道中的所有操作。在spacy Language类的顶部,我们有:

factories = {
    'tokenizer': lambda nlp: nlp.Defaults.create_tokenizer(nlp),
    'tensorizer': lambda nlp, **cfg: Tensorizer(nlp.vocab, **cfg),
    'tagger': lambda nlp, **cfg: Tagger(nlp.vocab, **cfg),
    'parser': lambda nlp, **cfg: DependencyParser(nlp.vocab, **cfg),
    'ner': lambda nlp, **cfg: EntityRecognizer(nlp.vocab, **cfg),
    'similarity': lambda nlp, **cfg: SimilarityHook(nlp.vocab, **cfg),
    'textcat': lambda nlp, **cfg: TextCategorizer(nlp.vocab, **cfg),
    'sbd': lambda nlp, **cfg: SentenceSegmenter(nlp.vocab, **cfg),
    'sentencizer': lambda nlp, **cfg: SentenceSegmenter(nlp.vocab, **cfg),
    'merge_noun_chunks': lambda nlp, **cfg: merge_noun_chunks,
    'merge_entities': lambda nlp, **cfg: merge_entities
}

这包括一些文档中未涵盖的内容:https://spacy.io/usage/processing-pipelines

由于它们未被涵盖,我不确定哪些可能已禁用,也不知道它们的依赖关系。

2个回答

10

我发现你也可以禁用spacy管道中的解析器部分,只要添加句子分割器。虽然速度并不是特别快,但确实有所改善——在测试中,时间看起来大约是之前的1/3(当我只禁用'ner'时)。这是我现在拥有的:

nlp = spacy.load('en', disable=['ner', 'parser'])
nlp.add_pipe(nlp.create_pipe('sentencizer'))

嗨,我使用了150万语料库遇到了相同的问题。我已禁用标记器、解析器和命名实体识别器,但仍然运行了8小时。你有尝试其他方法吗? - Jorge A. Salazar

0
  • 一个快速而有影响力的优化方法是使用适当的内存结构或内存数据库进行记忆化(如Python字典或Redis/Memcache)。
  • 单词的词形还有它们的上下文,如词性,都是不变的,因此没有必要一遍又一遍地在它们上面花费计算能力。

  • 在您的300万个文本语料库中会有大量重复,记忆化将大大缩短时间。

例子:

>>> import spacy
>>> nlp = spacy.load('en')
>>> txt1 = u"he saw the dragon, he saw the forest, and used a saw to cut the tree, and then threw the saw in the river." 
>>> [(x.text,x.pos_,x.lemma_) for x in nlp(txt1)]
[(u'he', u'PRON', u'-PRON-'), (u'saw', u'VERB', u'see'), (u'the', u'DET', u'the'), (u'dragon', u'NOUN', u'dragon'), (u',', u'PUNCT', u','), (u'he', u'PRON', u'-PRON-'), (u'saw', u'VERB', u'see'), (u'the', u'DET', u'the'), (u'forest', u'NOUN', u'forest'), (u',', u'PUNCT', u','), (u'and', u'CCONJ', u'and'), (u'used', u'VERB', u'use'), (u'a', u'DET', u'a'), (u'saw', u'NOUN', u'saw'), (u'to', u'PART', u'to'), (u'cut', u'VERB', u'cut'), (u'the', u'DET', u'the'), (u'tree', u'NOUN', u'tree'), (u',', u'PUNCT', u','), (u'and', u'CCONJ', u'and'), (u'then', u'ADV', u'then'), (u'threw', u'VERB', u'throw'), (u'the', u'DET', u'the'), (u'saw', u'NOUN', u'saw'), (u'in', u'ADP', u'in'), (u'the', u'DET', u'the'), (u'river', u'NOUN', u'river'), (u'.', u'PUNCT', u'.')]

正如您所看到的,词性标注+词形还原是不变的。


1
你确定可以将它们视为常量吗?如果是这样,为什么会需要词性标注器?以下是维基百科关于词形还原的解释:“与词干提取不同,词形还原依赖于在句子中正确地识别单词的意思和词性,以及在句子周围更大的上下文中的含义…” - TR517
我已经修改了这些例子,它将取决于单词的用法,是作为动词还是名词等。 - DhruvPathak
请在您的文本语料库上尝试此测试:https://gist.github.com/dhruvpathak/a7b96f469fd404a2351de69a5ff41144 - DhruvPathak
有趣。我下周会试一试。我唯一的担心是内存,但我有很多。 - TR517
你还可以使用外部缓存或快速数据库,例如Redis、Aerospike或MongoDB来进行记忆化。 - DhruvPathak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接