web-dev-qa-db-ja.com

NLTK WordNet Lemmatizer:単語のすべての語尾変化をレマタイズするべきではありませんか?

NLTK WordNet Lemmatizerを品詞タグ付けプロジェクトに使用します。最初にトレーニングコーパスの各Wordをそのステムに変更し(インプレース変更)、次に新しいコーパスでのみトレーニングします。しかし、レンマタイザーが期待どおりに機能していないことがわかりました。

たとえば、単語lovesは正しいloveにレンマ化されますが、単語lovingはレンマ化後もlovingのままです。ここでlovingは「私はそれを愛している」という文のようです。

loveは、語尾変化した語の幹lovingではありませんか?同様に、他の多くの「ing」形式は、見出し語化後もそのまま残ります。これは正しい動作ですか?

正確な他のレンマタイザーとは何ですか? (NLTKに存在する必要はありません)Wordの語幹を決定する際に、Wordの品詞タグも考慮に入れる形態分析装置またはレンマタイザーはありますか?たとえば、単語killingは、killが動詞として使用される場合、語幹としてkillingを持つ必要がありますが、語幹としてkillingを持つ必要があります名詞として使用されます(the killing was done by xyz)。

31
sanjeev mk

WordNet lemmatizer doesはPOSタグを考慮に入れますが、魔法のように決定しません:

>>> nltk.stem.WordNetLemmatizer().lemmatize('loving')
'loving'
>>> nltk.stem.WordNetLemmatizer().lemmatize('loving', 'v')
u'love'

POSタグがない場合、フィードするものはすべて名詞と見なされます。したがって、ここでは、「愛する」という名詞(「甘い愛する」など)を渡すと考えています。

60
Fred Foo

これをトラブルシューティングする最良の方法は、実際にWordnetを調べることです。こちらをご覧ください: ワードネットで愛する 。ご覧のとおり、実際にはWordnetには形容詞「愛」が存在します。実際のところ、「愛情を込めて」という副詞もあります。 Wordnetでは愛情を込めて 。ワードネットは実際にどのスピーチの部分が実際に欲しいかを知らないので、デフォルトでは名詞(Wordnetでは 'n')になります。 Penn Treebankタグセットを使用している場合、PennをWNタグに変換するための便利な関数を次に示します。

from nltk.corpus import wordnet as wn

def is_noun(tag):
    return tag in ['NN', 'NNS', 'NNP', 'NNPS']


def is_verb(tag):
    return tag in ['VB', 'VBD', 'VBG', 'VBN', 'VBP', 'VBZ']


def is_adverb(tag):
    return tag in ['RB', 'RBR', 'RBS']


def is_adjective(tag):
    return tag in ['JJ', 'JJR', 'JJS']


def penn_to_wn(tag):
    if is_adjective(tag):
        return wn.ADJ
    Elif is_noun(tag):
        return wn.NOUN
    Elif is_adverb(tag):
        return wn.ADV
    Elif is_verb(tag):
        return wn.VERB
    return None

お役に立てれば。

27
bogs

列挙よりも明確で効果的です:

from nltk.corpus import wordnet

def get_wordnet_pos(self, treebank_tag):
    if treebank_tag.startswith('J'):
        return wordnet.ADJ
    Elif treebank_tag.startswith('V'):
        return wordnet.VERB
    Elif treebank_tag.startswith('N'):
        return wordnet.NOUN
    Elif treebank_tag.startswith('R'):
        return wordnet.ADV
    else:
        return ''

def penn_to_wn(tag):
    return get_wordnet_pos(tag)
2
Joe Zhow

上記の@Fred Fooから受け入れられた回答の拡張として。

from nltk import WordNetLemmatizer, pos_tag, Word_tokenize

lem = WordNetLemmatizer()
Word = input("Enter Word:\t")

# Get the single character pos constant from pos_tag like this:
pos_label = (pos_tag(Word_tokenize(Word))[0][1][0]).lower()

# pos_refs = {'n': ['NN', 'NNS', 'NNP', 'NNPS'],
#            'v': ['VB', 'VBD', 'VBG', 'VBN', 'VBP', 'VBZ'],
#            'r': ['RB', 'RBR', 'RBS'],
#            'a': ['JJ', 'JJR', 'JJS']}

if pos_label == 'j': pos_label = 'a'    # 'j' <--> 'a' reassignment

if pos_label in ['r']:  # For adverbs it's a bit different
    print(wordnet.synset(Word+'.r.1').lemmas()[0].pertainyms()[0].name())
Elif pos_label in ['a', 's', 'v']: # For adjectives and verbs
    print(lem.lemmatize(Word, pos=pos_label))
else:   # For nouns and everything else as it is the default kwarg
    print(lem.lemmatize(Word))
0
Kiran Racherla

同様の@bogs

私は辞書を使用します:

from textblob.wordnet import NOUN, VERB, ADJ, ADV

pos_to_wornet_dict = {

    'JJ': ADJ,
    'JJR': ADJ,
    'JJS': ADJ,
    'RB': ADV,
    'RBR': ADV,
    'RBS': ADV,
    'NN': NOUN,
    'NNP': NOUN,
    'NNS': NOUN,
    'NNPS': NOUN,
    'VB': VERB,
    'VBG': VERB,
    'VBD': VERB,
    'VBN': VERB,
    'VBP': VERB,
    'VBZ': VERB,

}
0
tim