Глубокое копирование объекта PhraseMatcher в spacy не работает - PullRequest
0 голосов
/ 21 сентября 2018

Я хочу запустить какой-нибудь многопроцессорный модуль для параллельного выполнения некоторых совпадений фраз в документах.Для этого я подумал о создании объекта сопоставления фраз в одном процессе, а затем обмениваться ими между несколькими процессами, создавая копию объекта 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

Я застрял в этом на пару дней.Буду признателен за любую помощь.

Спасибо.

1 Ответ

0 голосов
/ 29 сентября 2018

Корень вашей проблемы в том, что PhraseMatcher - это класс Cython, определенный и реализованный в файле matcher.pyx, и Cython не работает должным образом с глубокой копией.

Ссылка на принятый ответ this StackOverflow вопрос:

Cython не любит глубокую копирование в классах, которые имеют переменные, ссылающиеся на функцию / метод.Эти переменные копии потерпят неудачу.

Однако есть альтернативы этому.Если вы хотите запустить 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)

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...