我在使用自定义扩展属性和最近改进的Matcher(spaCy 2.012)时遇到了问题。即使是一个简单的示例(大多是从here复制的)也无法按我预期的那样工作:
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)]
换句话说,规则在跨度'have'(1,2)上正确匹配,但是在'have'(5,6)和'had'(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
的匹配不正确? (即,为什么_
自定义属性约束不适用?)在我自己的代码中,当使用自定义属性作为后续模式中的约束时,这些模式在所有令牌上都匹配。我认为这与上面代码显示的行为有关。
答案 0 :(得分:1)
很抱歉,如果这样做令人困惑,但是您指的GitHub thread仍然只是规范和提案,即计划中的实施方案。希望这些更改将随spaCy v2.1.0一起提供(因为对Matcher
内部的某些更改不完全向后兼容)。
虽然尚未实现自定义属性匹配,但是Matcher
引擎的基本改进已在develop
分支和通过spacy-nightly
的alpha版本中提供({{ 1}})。这些更新还可能解决您在回调函数中观察到的不一致行为。