spaCy:自定义属性不匹配?



我在最近改进的匹配器(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)]

换句话说,规则在跨度"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)]

第一条规则的作用如上所述。然后触发第二个规则,以及回调函数(打印消息(。新模式还有一个额外的正确匹配项,以及第一个规则中的正确匹配项和错误匹配项。

所以,我有几个问题:

  1. 为什么pattern1匹配不正确?(即为什么_自定义属性约束不适用?
  2. 为什么回调函数在第一次调用时不起作用?
  3. 为什么它在添加新规则后有效?

在我自己的代码中,当使用自定义属性作为后续模式中的约束时,这些模式在所有令牌上匹配。我认为这与上述代码所表现出的行为有关。

抱歉,如果这令人困惑 - 但您所指的GitHub线程仍然只是规范和建议,即计划的实现。这些更改有望随spaCy v2.1.0一起提供(因为对Matcher内部结构的一些更改并不完全向后兼容(。

虽然尚未实现自定义属性匹配,但Matcher引擎的基本改进已经在develop分支和 alpha 版本中通过spacy-nightly(pip install spacy-nightly提供。这些更新还可能解决您在回调函数中观察到的不一致行为。

最新更新