Токенизация со Spacy - как получить левый и правый токены - PullRequest
0 голосов
/ 23 мая 2019

Я использую Spacy для текстового токенизации и застреваю с ним:

import spacy
nlp = spacy.load("en_core_web_sm")
mytext = "This is some sentence that spacy will not appreciate"
doc = nlp(mytext)

for token in doc:
    print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_, token.shape_, token.is_alpha, token.is_stop)

возвращает то, что, как мне кажется, говорит о том, что токенизация прошла успешно:

This this DET DT nsubj Xxxx True False 
is be VERB VBZ ROOT xx True True 
some some DET DT det xxxx True True 
sentence sentence NOUN NN attr xxxx True False 
that that ADP IN mark xxxx True True 
spacy spacy NOUN NN nsubj xxxx True False 
will will VERB MD aux xxxx True True 
not not ADV RB neg xxx True True 
appreciate appreciate VERB VB ccomp xxxx True False

но с другой стороны

[token.text for token in doc[2].lefts]

возвращает пустой список. Есть ли ошибка в lefts/rights?

Новичок в обработке естественного языка, надеюсь, я не попаду в концептуальную ловушку. Использование Spacy v'2.0.4 '.

1 Ответ

1 голос
/ 24 мая 2019

Вот как выглядят зависимости этого предложения:

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:])
...