WordNetLemmatizer не возвращает правильную лемму, если POS не является явным - Python NLTK

Я лемматизирую стенограмму набора данных Теда. Я заметил кое-что странное: не все слова лемматизируются. Сказать,

selected -> select

Какой правильный.

Однако involved !-> involve и horsing !-> horse, если я явно не ввел атрибут 'v' (глагол).

На терминале Python я получаю правильный вывод, но не в моем коде:

>>> from nltk.stem import WordNetLemmatizer
>>> from nltk.corpus import wordnet
>>> lem = WordNetLemmatizer()
>>> lem.lemmatize('involved','v')
u'involve'
>>> lem.lemmatize('horsing','v')
u'horse'

Соответствующий раздел кода таков:

for l in LDA_Row[0].split('+'):
    w=str(l.split('*')[1])
    word=lmtzr.lemmatize(w)
    wordv=lmtzr.lemmatize(w,'v')
    print wordv, word
    # if word is not wordv:
    #   print word, wordv

Весь код находится здесь.

В чем проблема?


person FlyingAura    schedule 05.10.2015    source источник
comment
Код не работает без установки ... можете ли вы извлечь ввод, например. как выглядит LDA_Row?   -  person rebeling    schedule 06.10.2015
comment
Это потому, что ваши POS-теги неверны. P/S: В следующий раз, пожалуйста, постарайтесь не публиковать полный код, а иметь в виду фрагменты в вашем коде, которые объясняют проблему, иначе пользователи Stackoverflow могут просто попытаться закрыть вопрос, говоря, что вопрос неясен или это мой код. рабочий вопрос =)   -  person alvas    schedule 06.10.2015


Ответы (1)


Лемматизатор требует, чтобы правильный тег POS был точным, если вы используете настройки по умолчанию WordNetLemmatizer.lemmatize(), тег по умолчанию — существительное, см. https://github.com/nltk/nltk/blob/develop/nltk/stem/wordnet.py#L39

Чтобы решить эту проблему, всегда добавляйте POS-теги к своим данным перед лемматизацией, например.

>>> from nltk.stem import WordNetLemmatizer
>>> from nltk import pos_tag, word_tokenize
>>> wnl = WordNetLemmatizer()
>>> sent = 'This is a foo bar sentence'
>>> pos_tag(word_tokenize(sent))
[('This', 'DT'), ('is', 'VBZ'), ('a', 'DT'), ('foo', 'NN'), ('bar', 'NN'), ('sentence', 'NN')]
>>> for word, tag in pos_tag(word_tokenize(sent)):
...     wntag = tag[0].lower()
...     wntag = wntag if wntag in ['a', 'r', 'n', 'v'] else None
...     if not wntag:
...             lemma = word
...     else:
...             lemma = wnl.lemmatize(word, wntag)
...     print lemma
... 
This
be
a
foo
bar
sentence

Обратите внимание, что «есть -> быть», т.е.

>>> wnl.lemmatize('is')
'is'
>>> wnl.lemmatize('is', 'v')
u'be'

Чтобы ответить на вопрос словами из ваших примеров:

>>> sent = 'These sentences involves some horsing around'
>>> for word, tag in pos_tag(word_tokenize(sent)):
...     wntag = tag[0].lower()
...     wntag = wntag if wntag in ['a', 'r', 'n', 'v'] else None
...     lemma = wnl.lemmatize(word, wntag) if wntag else word
...     print lemma
... 
These
sentence
involve
some
horse
around

Обратите внимание, что с WordNetLemmatizer есть некоторые особенности:

Кроме того, POS-тегер NLTK по умолчанию претерпевает серьезные изменения для повышения точности:

Готовое решение для лемматизатора можно найти на https://github.com/alvations/pywsd и то, как я сделал несколько try-exceptions для перехвата слов, которых нет в WordNet, см. https://github.com/alvations/pywsd/blob/master/pywsd/utils.py#L66

person alvas    schedule 06.10.2015
comment
Было здорово помочь, Спасибо! - person FlyingAura; 07.10.2015