Удаление существительных, содержащих стоп-слова, с помощью spaCy

Я использовал spaCy для поиска наиболее употребляемых существительных и noun_phrases.

Я могу успешно избавиться от знаков препинания и стоп-слов при поиске отдельных существительных

docx = nlp('The bird is flying high in the sky blue of color')

# Just looking at nouns
nouns = []
for token in docx:
    if token.is_stop != True and token.is_punct != True and token.pos_ == 'NOUN':
        nouns.append(token)

# Count and look at the most frequent nouns #
word_freq = Counter(nouns)
common_nouns = word_freq.most_common(10)

Однако использование noun_chunks для определения фраз приводит к ошибке атрибута

noun_phrases = []
for noun in docx.noun_chunks: 
    if len(noun) > 1 and '-PRON-' not in noun.lemma_ and noun.is_stop:
        noun_phrases.append(noun)

AttributeError: объект spacy.tokens.span.Span не имеет атрибута> is_stop

Я понимаю природу сообщения, но я не могу, хоть убей, правильно понять синтаксис, при котором присутствие стоп-слова в лемматизированной строке было бы исключено из добавления в список noun_phrases

Вывод без удаления игнорируемых слов

[{'word': 'птица', 'lemma': 'птица', 'len': 2}, {'word': 'небесно-голубой', 'lemma': 'небесно-голубой', 'len ': 3}]

Предполагаемый результат (удаление леммы, содержащей запрещающие слова, которые включают "the"

[{}]


person Gabriel Varela    schedule 14.09.2018    source источник


Ответы (2)


Какую версию spacy и python вы используете?

Я использую Python 3.6.5 и spacy 2.0.12 на Mac High Sierra. Кажется, ваш код отображает предполагаемый результат.

import spacy
from collections import Counter

nlp = spacy.load('en_core_web_sm')

docx = nlp('The bird is flying high in the sky blue of color')

# Just looking at nouns
nouns = []
for token in docx:
    if token.is_stop != True and token.is_punct != True and token.pos_ == 'NOUN':
        nouns.append(token)

# Count and look at the most frequent nouns #
word_freq = Counter(nouns)
common_nouns = word_freq.most_common(10)

print( word_freq)
print(common_nouns)


$python3  /tmp/nlp.py
Counter({bird: 1, sky: 1, blue: 1, color: 1})
[(bird, 1), (sky, 1), (blue, 1), (color, 1)]

Также 'is_stop' является атрибутом docx. Вы можете проверить через

>>> dir(docx)

Вы можете обновить spacy и его зависимости и посмотреть, поможет ли это.

Кроме того, flying - это ГЛАГОЛ, поэтому даже после лемметизации он не будет добавлен в соответствии с вашим условием.

token.text, token.lemma_, token.pos_, token.tag_, token.dep_,
          token.shape_, token.is_alpha, token.is_stop
flying fly VERB VBG ROOT xxxx True False

РЕДАКТИРОВАТЬ-1

Вы можете попробовать что-то подобное. Поскольку мы не можем использовать is_stop непосредственно для фрагментов слов, мы можем перебирать каждый фрагмент за словом и проверять условие в соответствии с вашими требованиями. (например, не имеет стоп-слова и имеет длину> 1 и т. д.). Если вас устраивает, мы добавляем в список.

noun_phrases = []
for chunk in docx.noun_chunks:
    print(chunk)
    if all(token.is_stop != True and token.is_punct != True and '-PRON-' not in token.lemma_ for token in chunk) == True:
        if len(chunk) > 1:
            noun_phrases.append(chunk)
print(noun_phrases)

Результат:

python3 /tmp/so.py
Counter({bird: 1, sky: 1, blue: 1, color: 1})
[(bird, 1), (sky, 1), (blue, 1), (color, 1)]
The bird
the sky blue
color
[]   # contents of noun_phrases is empty here.

Надеюсь это поможет. Вы можете настроить условия в if all в соответствии со своими требованиями.

person Anil_M    schedule 18.09.2018
comment
Привет, Анил, спасибо за помощь; Я могу нормально запустить этот фрагмент кода и сам, как я отмечал в сообщении, это вторая часть кода (например, с использованием фрагментов существительных), которая не работает! Я опубликовал только первую часть, чтобы показать, каков был мой предполагаемый результат, только с существительными фразами вместо существительных. Я также обновлю свой пост предполагаемым результатом. - person Gabriel Varela; 19.09.2018
comment
Спасибо за обновление, отлично работает! Я установлю все в .lower () в цикле, чтобы избежать обнаружения. - person Gabriel Varela; 19.09.2018

Вы также можете попробовать парсер Berkeley Natural. https://spacy.io/universe/project/self-attentive-parser Мне сказали, это дает вам дерево синтаксического анализа Penn Treebank. Еще мне сказали, что он медленный :-(

Также, если я не ошибаюсь, кусок существительного состоит из токенов, а токены идут с is_stop_, pos_ и tag_; то есть вы можете фильтровать соответственно.

С кусками существительных я обнаружил две неприятные проблемы: они идут после N + Ps на правой границе с прерывистым "и" между двумя кусками существительного! Что касается первого вопроса, то он не будет воспринимать «Калифорнийский университет» как фрагмент, а скорее «Университет» и «Калифорнию» как два отдельных фрагмента существительного.
Кроме того, он не согласован, что меня убивает . Джим Смит и Джейн Джонс могут выглядеть как «Джим Смит» плюс «Джейн Джонс» как два куска существительного; что и есть правильный ответ. Или "Джим Смит и Джейн Джонс" как одно существительное!?!

person user96265    schedule 12.12.2019