访问spaCy doc中超出范围的单词:为什么起作用?

问题描述

我正在学习spaCy,并且正在玩Matchers

我有

  • 一个非常基本的句子(“白色牧羊犬”)
  • 匹配对象,正在搜索模式(“白色牧羊犬”)
  • 显示匹配项的印刷品,以及匹配项之前的字词和POS

我只是想检查一下如何处理超出预期范围的索引,因为匹配之前没有任何内容。我没想到它会起作用,但是它确实起作用了,并且正在返回“ dog”,这是比赛后的结果……现在我很困惑。

spaCy似乎使用了一个循环列表(或我认为是双端队列)?

这需要一种语言模型才能运行,如果您想复制它,则可以使用以下命令行安装它:

python -m spacy download en_core_web_md

这是代码

import spacy
from spacy.matcher import Matcher 

# Loading language model
nlp = spacy.load("en_core_web_md")

# Initialising with shared vocab
matcher = Matcher(nlp.vocab)

# Adding statistical predictions
matcher.add("DOG",None,[{"LOWER": "white"},{"LOWER": "shepherd"}])  # searching for white shepherd
doc = nlp("white shepherd dog")

for match_id,start,end in matcher(doc):
    span = doc[start:end]  
    print("Matched span: ",span.text)   
    # Get prevIoUs token and its POS
    print("PrevIoUs token: ",doc[start - 1].text,doc[start - 1].pos_) # I would expect the error here

我得到以下信息:

>>> Matched span:  white shepherd
>>> PrevIoUs token:  dog PROPN

有人可以解释发生了什么吗?

谢谢!

解决方法

您正在寻找索引为0-1的令牌,该令牌的值为-1,这是最后一个令牌。

我建议使用Token.nbor方法在跨度之前查找第一个标记,如果没有先前的标记,请将其设置为None或一个空字符串。

import spacy
from spacy.matcher import Matcher 

# Loading language model
nlp = spacy.load("en_core_web_md")

# Initialising with shared vocab
matcher = Matcher(nlp.vocab)

# Adding statistical predictions
matcher.add("DOG",None,[{"LOWER": "white"},{"LOWER": "shepherd"}])  # searching for white shepherd
doc = nlp("white shepherd dog")

for match_id,start,end in matcher(doc):
    span = doc[start:end]
    print("Matched span: ",span.text)
    try:
        nbor_tok = span[0].nbor(-1)
        print("Previous token:",nbor_tok,nbor_tok.pos_)
    except IndexError:
        nbor_tok = ''
        print("Previous token: None None")