web-dev-qa-db-fra.com

NLTK WordNet Lemmatizer: Ne devrait-il pas lemmatiser toutes les inflexions d'un mot?

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

26
sanjeev mk

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").

54
Fred Foo

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.

27
bogs

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,

}
0
tim

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)
0
Joe Zhow