Вот как выглядят зависимости этого предложения:
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp(u"This is some sentence that spacy will not appreciate")
for token in doc:
print(token.text, token.dep_, token.head.text, token.head.pos_,
[child for child in token.children])
This nsubj is VERB []
is ROOT is VERB [This, sentence]
some det sentence NOUN []
sentence attr is VERB [some, appreciate]
that mark appreciate VERB []
spacy nsubj appreciate VERB []
will aux appreciate VERB []
not neg appreciate VERB []
appreciate relcl sentence NOUN [that, spacy, will, not]
Итак, мы видим, что doc[2]
("some") имеет пустой дочерний вектор.Однако «есть» (doc[1]
) нет.Если вместо этого мы запустим ...
print([token.text for token in doc[1].lefts])
print([token.text for token in doc[1].rights])
, то получим ...
['This']
['sentence']
Используемые вами функции перемещаются по дереву зависимостей, а не по документу, поэтому вы и получаете пустоерезультаты для некоторых слов.
Если вам нужны только предыдущие и последующие токены, вы можете просто сделать что-то вроде ...
for ix, token in enumerate(doc):
if ix == 0:
print('Previous: %s, Current: %s, Next: %s' % ('', doc[ix], doc[ix + 1]))
elif ix == (len(doc) - 1):
print('Previous: %s, Current: %s, Next: %s' % (doc[ix - 1], doc[ix], ''))
else:
print('Previous: %s, Current: %s, Next: %s' % (doc[ix - 1], doc[ix], doc[ix + 1]))
или ...
for ix, token in enumerate(doc):
print('Previous: %s' % doc[:ix])
print('Current: %s' % doc[ix])
print('Following: %s' % doc[ix:])