просторная агрессивная лемматизация и удаление неожиданных слов

Я пытаюсь очистить некоторые текстовые данные. Сначала я удалил стоп-слова, затем я попытался лемматизировать текст. Но слова, такие как существительные, удаляются

Образцы данных

https://drive.google.com/file/d/1p9SKWLSVYeNScOCU_pEu7A08jbP-50oZ/view?usp=sharing обновленный код

# Libraries  
import spacy
import pandas as pd
import gensim
from gensim.utils import simple_preprocess
import nltk; nltk.download('stopwords')
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['covid', 'COVID-19', 'coronavirus'])

article= pd.read_csv("testdata.csv")
data = article.title.values.tolist()
nlp = spacy.load('en_core_web_sm')

def sent_to_words(sentences):
    for sentence in sentences:
      yield(gensim.utils.simple_preprocess(str(sentence), deacc=True))  # deacc=True removes punctuations

data_words = list(sent_to_words(data))

def remove_stopwords(texts):
    return [[word for word in simple_preprocess(str(doc)) if word not in stop_words] for doc in texts]
data_words_nostops = remove_stopwords(data_words)
print ("*** Text  After removing Stop words:   ")
print(data_words_nostops)
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV','PRON']):
    """https://spacy.io/api/annotation"""
    texts_out = []
    for sent in texts:
        doc = nlp(" ".join(sent)) 
        texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
    return texts_out
data_lemmatized = lemmatization(data_words_nostops, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV','PRON'])
print ("*** Text  After Lemmatization:   ")

print(data_lemmatized)

Результат после удаления стоп-слов:

[['qaia', 'флаги', 'амман', 'мельбурн', 'jetstar', 'рейсы', 'восстановление', 'план'],
['западный', 'амман', 'пригород ',' новый ',' nsw ',' ground ',' zero ', children],
[' flight ',' return ',' amman ',' qaia ',' staff ',' contract ', 'вождение'],]]

Выход после лематизации:

[["полет", "восстановление", "план"]

['пригород', 'земля']

["возврат", "контракт", "вождение"]

по каждому реакорду я не понимаю следующего:

-1-я запись: почему удалены эти слова: "qaia", "flags", "amman", "melbourne", "jetstar"

-2ed recored: основные слова reomved так же, как и первое reord. Кроме того, я ожидал, что дети обратятся в child

-3ed, движение не преобразуется в движение

Я ожидал, что такие слова, как Амман, не будут удалены. Также я ожидаю, что слова будут преобразованы из множественного числа в единственное. И глаголы будут преобразованы в инфинитив ...

Что мне здесь не хватает ??? Заранее спасибо


person almegdadi    schedule 27.11.2020    source источник
comment
Удаленные слова выглядят как существительные собственные. Попробуйте добавить PROPN в свой allowed_postags. Ваши ожидания относительно лемматизации верны, однако лемматизатор Spacy не очень хорош. Если вам нужна более высокая производительность, вы можете попробовать lemminflect.   -  person bivouac0    schedule 28.11.2020
comment
Кстати ... Я заметил, что вы используете версию предложения со стоп-словами, удаленными через nlp Спейси. Это может привести к сбоям в назначении тегов pos, что будет мешать лемматизации и т. Д. Проверьте теги, которые Spacy назначает вашим тестовым предложениям, чтобы убедиться, что они верны, и подумайте о том, чтобы обработать ваше полное предложение через nlp.   -  person bivouac0    schedule 28.11.2020
comment
@ bivouac0 Спасибо за ваш комментарий. Что касается стоп-слова, я расширил список слов englihsh, как этот stop_words = stopwords.words('english'); stop_words.extend(['covid', 'COVID-19', 'coronavirus']), но я отключил его, потому что я хотел проверить поведение лемматизатора   -  person almegdadi    schedule 28.11.2020
comment
@ bivouac0 Я добавил PROPN в allowed_postags .. Это отлично подходит для таких слов, как Амман, полеты ** ... НО, такие слова, как ** дети не преобразовались в ребенок   -  person almegdadi    schedule 28.11.2020


Ответы (1)


Я предполагаю, что большинство ваших проблем связано с тем, что вы не кормите spaCy полными предложениями и не назначаете правильные теги части речи вашим словам. Это может привести к тому, что лемматизатор вернет неверные результаты. Однако, поскольку вы предоставили только фрагменты кода, а не исходный текст, ответить на этот вопрос сложно. В следующий раз подумайте о том, чтобы свести ваш вопрос к нескольким строкам кода, который кто-то другой может запустить на своей машине ТОЧНО НАПИСАННЫМ, и предоставив образец ввода, который не работает. См. минимальный воспроизводимый пример

Вот пример, который работает и близок к тому, что вы делаете.

import spacy
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
allow_postags = set(['NOUN', 'VERB', 'ADJ', 'ADV', 'PROPN'])
nlp = spacy.load('en')
text = 'The children in Amman and Melbourne are too young to be driving.'
words = []
for token in nlp(text):
    if token.text not in stop_words and token.pos_ in allow_postags:
        words.append(token.lemma_)
print(' '.join(words))

Это возвращает child Amman Melbourne young drive

person bivouac0    schedule 28.11.2020
comment
не могли бы вы проверить мой обновленный код @ bivouac0 - person almegdadi; 28.11.2020
comment
У вас все еще та же проблема, лемматизатор spaCy не работает правильно после запуска через gensim, потому что вы удаляете стоп-слова, знаки препинания и конвертируете все в нижний регистр. Вам нужно увеличить объем исходного предложения, а затем извлечь слова, которые вы хотите сохранить. Вам вообще не нужны gensim (или pandas). Кстати .. Я думаю, вы тоже хотите PROPN, а не PRON в своем alllowed_postags. - person bivouac0; 28.11.2020