J'utilise le Lemmatizer NLTK WordNet pour un projet de marquage Part-of-Speech en modifiant d'abord chaque mot du corpus d'apprentissage en son tronc (modification en place), puis en m'entraînant uniquement sur le nouveau corpus. Cependant, j'ai constaté que le lemmatiseur ne fonctionnait pas comme prévu.
Par exemple, le mot loves
est lemmatisé à love
, ce qui est correct, mais le mot loving
reste loving
même après la lemmatisation. Ici, loving
est comme dans la phrase "je l’aime".
love
n'est-il pas la racine du mot infléchi loving
? De même, de nombreuses autres formes de "ing" restent en l'état après la lemmatisation. Est-ce le comportement correct?
Quels sont les autres lemmatiseurs qui sont précis? (ne doit pas nécessairement être en NLTK) Existe-t-il des analyseurs de morphologie ou des lemmatiseurs qui prennent également en compte une balise Part of Speech de Word lors de la détermination du radical Word? Par exemple, le mot killing
devrait avoir kill
comme racine si killing
est utilisé comme verbe, mais il devrait avoir killing
comme tige si elle est utilisée comme nom (comme dans the killing was done by xyz
).
Le lemmatiseur WordNet ne / prend en compte le tag POS, mais ne le détermine pas par magie:
>>> nltk.stem.WordNetLemmatizer().lemmatize('loving')
'loving'
>>> nltk.stem.WordNetLemmatizer().lemmatize('loving', 'v')
u'love'
Sans étiquette de point de vente, il suppose que tout ce que vous alimentez est un nom. Donc ici, il pense que vous passez le nom "aimer" (comme dans "doux aimer").
Le meilleur moyen de résoudre ce problème consiste à consulter Wordnet. Jetez un oeil ici: Loving in wordnet . Comme vous pouvez le constater, Wordnet contient en réalité un adjectif "aimant". En fait, il y a même l'adverbe "amoureusement": amoureusement dans Wordnet . Parce que wordnet ne sait pas réellement quelle partie du discours vous voulez réellement, il utilise par défaut le nom ('n' dans Wordnet). Si vous utilisez le jeu de balises Penn Treebank, voici une fonction pratique pour transformer Penn en balises 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
J'espère que cela t'aides.
Similaire @bogs
J'utilise un dict:
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,
}
c'est plus clair et plus efficace qu'une énumération:
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)