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
)。
WordNet lemmatizer doesはPOSタグを考慮に入れますが、魔法のように決定しません:
>>> nltk.stem.WordNetLemmatizer().lemmatize('loving')
'loving'
>>> nltk.stem.WordNetLemmatizer().lemmatize('loving', 'v')
u'love'
POSタグがない場合、フィードするものはすべて名詞と見なされます。したがって、ここでは、「愛する」という名詞(「甘い愛する」など)を渡すと考えています。
これをトラブルシューティングする最良の方法は、実際に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
お役に立てれば。
列挙よりも明確で効果的です:
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)
上記の@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))
同様の@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,
}