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

时间:2018-10-01 20:56:40

标签: python nlp spacy matcher

我在使用自定义扩展属性和最近改进的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. 为什么添加新规则后它会起作用?

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

1 个答案:

答案 0 :(得分:1)

很抱歉,如果这样做令人困惑,但是您指的GitHub thread仍然只是规范和提案,即计划中的实施方案。希望这些更改将随spaCy v2.1.0一起提供(因为对Matcher内部的某些更改不完全向后兼容)。

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