nltk: заменить токены другими словами в зависимости от POS - PullRequest
0 голосов
/ 12 июня 2018

Я работаю над обработкой естественного языка и мне нужно предварительно обработать некоторые данные.Мои данные находятся в текстовом файле, и я должен прочитать данные и изменить все имена на Мужские или Женские.

После прочтения данных и их токенизации я применяю pos-теги и проверяю файл, имеющий список имени измените имя на «Мужской» или «Женский»

Например:

['Jack', 'and', 'Jill', 'Went', 'up', 'the', 'hill']

следует изменить на

['Male', 'and', 'Female', 'Went', 'up',' the ',' hill ']

на основе следующего POS

[(' Jack ',' NNP '), (' and ','CC '), (' Jill ',' NNP '), (' Went ',' NNP '), (' up ',' IN '), (' the ',' DT '), (' hill ','NN ')]

Мой код выглядит следующим образом:

import nltk

text = open('collegegirl.txt').read()

with open('male_names.txt') as f1:
    male = nltk.word_tokenize(f1.read())

with open('female_names.txt') as f2:
    female = nltk.word_tokenize(f2.read())  

data = nltk.pos_tag(nltk.word_tokenize(text))
for word, pos in data:
    if(pos == 'NNP'):
        if word in male:
            word = 'Male'
        if word in female:
            word = 'Female'

Приведенный выше код просто проверяет слова и ничего не пишет.Как мне отредактировать имена в данных.Я новичок в Python.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 20 июня 2018

По моему личному мнению, лучше использовать Spacy для POS-тегов, которые бывают быстрее и точнее.Кроме того, вы можете использовать его именованное распознавание сущности, чтобы проверить, является ли слово ЧЕЛОВЕКОМ.Установите spacy и скачайте модель en_core_web_lg отсюда https://spacy.io/usage/

Ваши проблемы могут быть решены как:

import spacy
from functools import reduce

nlp_spacy = spacy.load('en_core_web_lg')

NAMELIST = {'Christiano Ronaldo':'Male', 'Neymar':'Male', 'Messi':'Male', "Sandra":'Female'}

with open("input.txt") as f:
    text = f.read()

doc = nlp_spacy(text)

names_in_text = [(entity.text, NAMELIST[entity.text])  for entity in doc.ents if entity.label_ in ['PERSON'] and entity.text in NAMELIST]
print(names_in_text)       #------- prints [('Christiano Ronaldo', 'Male'), ('Messi', 'Male')]

replaced_text = reduce(lambda x, kv: x.replace(*kv), names_in_text, text)
print(replaced_text)       #------- prints Male scored three. Male scored one. Female is an athlete. I am from US.
0 голосов
/ 12 июня 2018

Разделите текст и сделайте в вашем цикле for:

for i, (word, pos) in enumerate(data):
    if(pos == 'NNP'):
        if word in male:
            data[i] = ('Male', pos)
        if word in female:
            data[i] = ('Female', pos)
array = [text for (text, pos) in data]

Более питонский способ сделать это:

array = [x if (not pos == "NNP" and not x in male and not x in female) else ("Female" if (x in female) else ( "Male" if (x in male) else x)) for (x, pos) in data]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...