Выделение некоторых форм множественного числа с помощью лемматизатора wordnet не работает

Привет, у меня проблема с nltk (2.0.4): я пытаюсь определить слова «мужчины» или «зубы», но, похоже, это не работает. Вот мой код:

############################################################################
import nltk
from nltk.corpus import wordnet as wn
from nltk.stem.wordnet import WordNetLemmatizer

lmtzr=WordNetLemmatizer()
words_raw = "men teeth"
words = nltk.word_tokenize(words_raw)
for word in words:
        print 'WordNet Lemmatizer NOUN: ' + lmtzr.lemmatize(word, wn.NOUN)
#############################################################################

Это должно печатать «человек» и «зуб», но вместо этого печатает «мужчины» и «зубы».

любые решения?


person BlackOwl    schedule 11.03.2014    source источник
comment
Привет! добро пожаловать в переполнение стека! ознакомьтесь со статьей о лемматизации в Википедии, чтобы получить разъяснения. вы пытаетесь найти единственное число для этих слов или вы пытаетесь найти одно слово / лемму для набора слов, таких как индустриализация, отрасли (что должно дать промышленность)?   -  person arturomp    schedule 11.03.2014
comment
Да, я пытаюсь найти единственное число для этих слов; для других слов, таких как «женщины» или «ноги», это работает отлично.   -  person BlackOwl    schedule 12.03.2014


Ответы (2)


Я нашел решение! Я проверил файлы в wordnet.py в папке /usr/local/lib/python2.6/dist-packages/nltk/corpus/reader и заметил, что функция _morphy(self,form,pos) возвращает список, содержащий слова в основе . Итак, я попытался протестировать _morphy :

import nltk
from nltk.corpus import wordnet as wn
from nltk.stem.wordnet import WordNetLemmatizer

words_raw = "men teeth books"
words = nltk.word_tokenize(words_raw)
for word in words:
        print wn._morphy(word, wn.NOUN)

Эта программа печатает [люди,человек], [зубы,зуб] и [книгу]!

объяснение почему lmtzr.lemmatize() печатает только первый элемент списка, возможно его можно найти в функции lemmatize, содержащейся в файле 'wordnet.py' который находится в папке /usr/local/lib/python2 .6/dist-packages/nltk/стел.

def lemmatize(self, word, pos=NOUN):
    lemmas = wordnet._morphy(word, pos)
    return min(lemmas, key=len) if lemmas else word

Я предполагаю, что он возвращает только более короткое слово, содержащееся в списке слов, и если два слова имеют одинаковую длину, он возвращает первое; например, «мужчины» или «зубы», а не «человек» и «зуб»

person BlackOwl    schedule 12.03.2014

Нет ничего плохого в wordnetlemmatizer как таковом, но он просто не может достаточно хорошо обрабатывать неправильные слова. Вы можете попробовать этот «хак» и попытаться найти ближайший lemma_names для синсета:

>>> from nltk.stem import WordNetLemmatizer
>>> wnl = WordNetLemmatizer()
>>> word = "teeth"
>>> wnl.lemmatize(word)
'teeth'
>>> wnlemmas = list(set(list(chain(*[i.lemma_names() for i in wordnet.synsets('teeth')]))))
>>> from difflib import get_close_matches as gcm
>>> [i for i in gcm(word,wnlemmas) if i != word]
[u'tooth']

>>> word = 'men'
>>> wnlemmas = list(set(list(chain(*[i.lemma_names() for i in wordnet.synsets(word)]))))
>>> gcm(word,wnlemmas)
[u'men', u'man']
>>> [i for i in gcm(word,wnlemmas) if i != word]
[u'man']

Однако тот факт, что wordnet.synsets('men') может получить правильный синсет, а WordNetLemmatizer().lemmatize('men') не может свидетельствовать о том, что в коде WordNetLemmatizer чего-то не хватает.


Чтобы расширить список исключений, см. также: Python NLTK Лемматизация слово «далее» с wordnet

person alvas    schedule 12.03.2014
comment
Спасибо, мужик! но я пытаюсь понять, почему лемматизатор wordnet ведет себя таким образом без какого-либо взлома. Я попытался посмотреть на код, и кажется, что ничего не пропало... я проверил папку /home/mydir/nltk_data/corpora/wordnet и нашел там файл с именем noun.exec, который содержит исключение "men man" .... также я проверил папку /usr/local/lib/python2.6/dist-packages/nltk/corpus/reader, и там есть файл с именем 'wordnet.py', который в порядке - person BlackOwl; 12.03.2014