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
Весь код здесь.
В чем проблема?
1 ответ
Лемматизатор требует правильной метки POS, чтобы быть точным, если вы используете настройки по умолчанию WordNetLemmatizer.lemmatize()
тег по умолчанию является существительным, см. https://github.com/nltk/nltk/blob/develop/nltk/stem/wordnet.py
Чтобы решить проблему, всегда используйте 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 происходят некоторые серьезные изменения для повышения точности:
- Python NLTK pos_tag не возвращает правильный тег части речи
- https://github.com/nltk/nltk/issues/1110
- https://github.com/nltk/nltk/pull/1143
А для готового / готового решения для лемматизатора вы можете взглянуть на https://github.com/alvations/pywsd и узнать, как я сделал несколько исключений-попыток, чтобы поймать слова которые не находятся в WordNet, см. https://github.com/alvations/pywsd/blob/master/pywsd/utils.py