python - 在 spacy 中深度复制 PhraseMatcher 对象不起作用

标签 python python-3.x nltk spacy

我想运行一些多处理模块来并行地对文档运行一些短语匹配。为此,我考虑在一个进程中创建短语匹配对象,然后通过创建 PhraseMatcher 对象的副本在多个进程之间共享。该代码似乎失败了,但没有给出任何类型的错误。为了让事情变得更容易,我尝试这样做来展示我想要实现的目标

import copy
import spacy
from spacy.matcher import PhraseMatcher


nlp = spacy.load('en')
color_patterns = [nlp(text) for text in ('red', 'green', 'yellow')]
product_patterns = [nlp(text) for text in ('boots', 'coats', 'bag')]
material_patterns = [nlp(text) for text in ('silk', 'yellow fabric')]

matcher = PhraseMatcher(nlp.vocab)
matcher.add('COLOR', None, *color_patterns)
matcher.add('PRODUCT', None, *product_patterns)
matcher.add('MATERIAL', None, *material_patterns)


matcher2 = copy.deepcopy(matcher)

doc = nlp("yellow fabric")
matches = matcher2(doc)
for match_id, start, end in matches:
    rule_id = nlp.vocab.strings[match_id]  # get the unicode ID, i.e. 'COLOR'
    span = doc[start : end]  # get the matched slice of the doc
    print(rule_id, span.text)

使用 matcher2 对象,它不会给出任何输出,但使用 matcher 对象,我可以获得结果。

COLOR yellow
MATERIAL yellow fabric

我已经被这个问题困扰了好几天了。任何帮助将不胜感激。

谢谢。

最佳答案

问题的根源在于 PhraseMatcher 是一个 Cython 类,在文件 matcher.pyx 中定义和实现,而 Cython 无法与 DeepCopy 一起正常工作。

引用自已接受的答案 this StackOverflow 问题:

Cython doesn't like deepcopy on Classes which have function/method referenced variables. Those variable copies will fail.

但是,还有其他选择。如果您想并行运行 PhraseMatcher 到多个文档,您可以通过 PhraseMatcher 的管道方法使用多线程。

解决您的问题的可能方法:

import copy
import spacy
from spacy.matcher import PhraseMatcher


nlp = spacy.load('en_core_web_sm')
color_patterns = [nlp(text) for text in ('red', 'green', 'yellow')]
product_patterns = [nlp(text) for text in ('boots', 'coats', 'bag')]
material_patterns = [nlp(text) for text in ('silk', 'yellow fabric')]

matcher = PhraseMatcher(nlp.vocab)
matcher.add('COLOR', None, *color_patterns)
matcher.add('PRODUCT', None, *product_patterns)
matcher.add('MATERIAL', None, *material_patterns)

doc1 = nlp('yellow fabric')
doc2 = nlp('red lipstick and big black boots')

for doc in matcher.pipe([doc1, doc2], n_threads=4):
    matches = matcher(doc)
    for match_id, start, end in matches:
        rule_id = nlp.vocab.strings[match_id]
        span = doc[start : end]
        print(rule_id, span.text)

希望对你有帮助!

关于python - 在 spacy 中深度复制 PhraseMatcher 对象不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52436726/

相关文章:

python - 如何根据距已知引用轨迹的距离过滤位置数据?

python - 如何创建一个只接受位置参数而不接受关键字参数的python函数?

python:如何在 scikit 学习分类器 (SVM) 等中使用 POS(词性)特征

python-2.7 - 从 Python NLTK 或其他模块中的任何单词中获取音素?

python - 优化 NLTK 代码以根据文本进行预测

python - 重采样时间序列的中心日期时间

python - 需要 pandas 行操作的帮助

python - tf.gradients 和 tf.train.RMSPropOptimizer(lr_rate).compute_gradients 有什么区别?

python-3.x - 何时使用 ast.literal_eval

python - 有条件地填充 pandas 数据框会导致空数据框