spaCy:自定义属性不正确匹配?

spaCy: custom attributes not matching correctly?

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

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

所以,我有几个问题:

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

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

抱歉,如果这让您感到困惑 – 但您所指的 GitHub thread 仍然只是 规范和提案 ,即计划实施。这些更改有望与 spaCy v2.1.0 一起发布(因为 Matcher 内部的一些更改不完全向后兼容)。

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