Я хочу запустить несколько многопроцессорных модулей для параллельного параллельного сопоставления фразу. Для этого я подумал о создании объекта сопоставления фразы в одном процессе, а затем обмениваться между несколькими процессами, создав копию объекта 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.
Ссылка на принятый ответ на этот вопрос StackOverflow:
Cython не любит deepcopy в классах, у которых есть переменные функции/метода. Эти переменные копии не удастся.
Однако есть альтернативы этому. Если вы хотите запустить PhraseMatcher для нескольких документов параллельно, вы можете использовать многопоточность с методом pipe для 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)
Надеюсь, поможет!