【问题标题】:Stemming some plurals with wordnet lemmatizer doesn't work用 wordnet lemmatizer 提取一些复数词不起作用
【发布时间】:2014-04-15 12:25:07
【问题描述】:

您好,我对 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)
#############################################################################

这应该打印 'man' 和 'tooth' 但它会打印 'men' 和 'teeth'。

有什么解决办法吗?

【问题讨论】:

  • 嗨!欢迎堆栈溢出!查看维基百科上的lemmatization 文章以获得澄清。您是想为这些词找到单数,还是想为“工业化”、“工业”(应该产生“工业”)等一组词找到一个词/引理?
  • 是的,我正在尝试为这些词找到单数;对于像“女人”或“脚”这样的其他词,它非常有效。

标签: nltk python-2.6 wordnet stemming lemmatization


【解决方案1】:

wordnetlemmatizer 本身没有问题,但它不能很好地处理不规则的单词。您可以尝试这个“hack”并尝试为同义词集找到最接近的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 Lemmatization of the word 'further' with wordnet

【讨论】:

  • 谢谢你!但我试图弄清楚为什么 wordnet lemmatizer 以这种方式表现而没有任何黑客攻击。我试图查看代码,似乎没有任何遗漏......我检查了文件夹/home/mydir/nltk_data/corpora/wordnet,有一个名为'noun.exec'的文件,其中包含异常'men man' .... 我还检查了文件夹 /usr/local/lib/python2.6/dist-packages/nltk/corpus/reader 并且有一个名为 'wordnet.py' 的文件,可以
【解决方案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)

这个程序打印 [men,man]、[teeth,tooth] 和 [book]!

为什么 lmtzr.lemmatize () 只打印列表的第一个元素的解释,也许它可以在函数 lemmatize 中找到,包含在文件夹 /usr/local/ 中的文件 'wordnet.py' 中lib/python2.6/dist-packages/nltk/stem.

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

我假设它只返回单词列表中较短的单词,如果两个单词长度相等,则返回第一个单词;例如 'men' 或 'teeth' 而不是 'man' 和 'tooth'

【讨论】:

    猜你喜欢
    • 2017-01-11
    • 1970-01-01
    • 2016-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    相关资源
    最近更新 更多