У меня были проблемы с использованием пользовательских атрибутов расширения с недавно улучшенным Matcher (spaCy 2.012).Даже простой пример (в основном скопированный с здесь ) не работает, как я ожидал:
import spacy
from spacy.tokens import Token
from spacy.matcher import Matcher
nlp = spacy.load('en')
text = 'I have apple. I have had nothing.'
doc = nlp(text)
def on_match(matcher, doc, id, matches):
print('Matched!', matches)
Token.set_extension('is_fruit', getter=lambda token: token.text in ('apple', 'banana'))
pattern1 = [{'LEMMA': 'have'}, {'_': {'is_fruit': True}}]
matcher = Matcher(nlp.vocab)
matcher.add('HAVING_FRUIT', on_match, pattern1)
matches = matcher(doc)
print(matches)
Это дает следующий вывод:
[(13835066833201802823, 1, 2), (13835066833201802823, 5, 6), (13835066833201802823, 6, 7)]
Другими словамиправило правильно соответствует диапазону «иметь» (1, 2), но неправильно соответствует «иметь» (5, 6) и «имел» (6, 7).Кроме того, функция обратного вызова не вызывается.Пользовательский атрибут, кажется, игнорируется.
Когда я добавляю новый шаблон, как показано ниже:
Token.set_extension('nope', default=False)
pattern2 = [{'LEMMA': 'nothing'}]
matcher.add('NADA', on_match, pattern2)
matches = matcher(doc)
print(matches)
Я получаю следующий вывод:
[(12682145344353966206, 1, 2), (12682145344353966206, 5, 6), (12682145344353966206, 6, 7)]
Matched! [(12682145344353966206, 1, 2), (12682145344353966206, 5, 6), (12682145344353966206, 6, 7), (5033951595686580046, 7, 8)]
[(12682145344353966206, 1, 2), (12682145344353966206, 5, 6), (12682145344353966206, 6, 7), (5033951595686580046, 7, 8)]
ПервыйПравило функционирует, как указано выше.Затем срабатывает второе правило вместе с функцией обратного вызова (которая печатает сообщение).Существует дополнительное правильное совпадение для нового шаблона, а также правильные и ошибочные совпадения из первого правила.
Итак, у меня есть несколько вопросов:
- почему
pattern1
совпадать неправильно?(т.е. почему ограничение _
настраиваемого атрибута не применяется?) - , почему функция обратного вызова не работает при первом вызове?
- , почему она работает при добавлении нового правила?
В моем собственном коде при использовании пользовательских атрибутов в качестве ограничений в последующих шаблонах эти шаблоны совпадают на ВСЕХ токенах.Я предполагаю, что это связано с поведением, показанным кодом выше.