2015-10-05 7 views
1

Я лектифицирую Ted Dataset Transcript. Там что-то странное замечаю: Не все слова лемматизируются. Сказать,WordNetLemmatizer не возвращает правильную лемму, если POS не является явной - Python NLTK

selected -> select 

Что является правильным.

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

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

>>> 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 

Весь код here.

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

+0

Код не работает без установки ... можете ли вы извлечь ввод, например как выглядит LDA_Row? – rebeling

+0

Это потому, что ваши теги POS ошибочны. P/S: В следующий раз, пожалуйста, постарайтесь не публиковать полный код, а означать фрагменты кода, который объясняет проблему, в противном случае пользователи Stackoverflow могут просто попытаться закрыть вопрос о том, что «вопрос неясен», или это «мой код не работает "question =) – alvas

ответ

2

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

Чтобы решить эту проблему, всегда POS пометки данных перед lemmatizing , например

>>> 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:

Также NLTK по POS умолчанию Таггер под текущие крупные изменения для повышения точности:

Ииз готового к выпуску решения для lemmatizer, вы можете взглянуть на https://github.com/alvations/pywsd и как я сделал некоторые попытки исключить, чтобы поймать слова, которые не находятся в WordNet, см. https://github.com/alvations/pywsd/blob/master/pywsd/utils.py#L66

+0

Была отличная помощь, спасибо! – FlyingAura