spaCy:匹配器结束令牌偏移量不是我所期望的

时间:2018-06-28 16:29:05

标签: python nlp matcher spacy

对于spaCy(根据2.0.11,依据spacy.info(),我正在尝试使用Matcher识别令牌模式,但未获得预期的结果。匹配对象中的标记偏移量与应该在文本中匹配的标记的偏移量不对应。

这是一个简化的代码段,用于显示我在做什么:

import spacy
from spacy.matcher import Matcher

nlp = spacy.load('en')

text = "This has not gone far. The end."
doc = nlp(text)

pattern1 = [{'POS': 'VERB'}, {'LEMMA': 'not'}, {'POS': 'VERB'}] # match has not gone
pattern2 = [{'POS': 'DET'}, {'POS': 'NOUN'}] # match The end

matcher = Matcher(nlp.vocab)

matcher.add('rule1', None, pattern1)
matcher.add('rule2', None, pattern2)

matches = matcher(doc)

for match in matches:
    print(doc[match[1]], doc[match[2]], match)

我得到的输出是:

has far (15137773209560627690, 1, 4)
The . (16952143625379849586, 6, 8)

我期望的输出是:

has gone (15137773209560627690, 1, 3)
The end (16952143625379849586, 6, 7)

因此,匹配的结束标记偏移量是模式匹配的最后一个标记之后的标记 之后的标记。这是预期的行为吗?

更笼统地说,我正在尝试产生TokensRegex样式的行为,即能够在给定的匹配项中向各个标记添加自定义注释(例如,向“ has”和“ gone”添加一个negated = TRUE注释和一个否定词) = TRUE表示副词“ not”在同一匹配项中)。可以使用回调函数将单个注释添加到匹配项中,但这并不是我想要的。 (可能)吗?

1 个答案:

答案 0 :(得分:1)

我认为问题在于您只查看开始和结束令牌,而不是匹配的跨度。跨度的end索引始终是排他的,因此doc[2:4]将是令牌2 直到令牌4。我只是尝试了您的示例并打印了每个匹配的跨度文本,我看到以下输出:

for match_id, start, end in matches:
    span = doc[start:end]
    print(span.text)

# has not gone
# The end

回答第二个问题:您可以使用token._.negatedtoken._.negation之类的custom extension attributes来达到非常相似的目的。如果您的否定规则匹配,则可以为匹配创建Span,遍历标记并设置相应的属性。为了使它更加美观,您还可以将该逻辑包装在pipeline component中,这样当您在文本上调用nlp时它将自动运行。