2014-08-27 5 views
17

Sto usando il Lemmatizer di WordNet NLTK per un progetto di tagging di parte del discorso, modificando prima ogni parola nel corpus di addestramento sul suo gambo (modifica sul posto) e quindi l'allenamento solo sul nuovo corpus. Tuttavia, ho trovato che il lemmatizer non funziona come mi aspettavo.NLTK Lemmatizzatore WordNet: non dovrebbe lemmatizzare tutte le inflessioni di una parola?

Ad esempio, la parola loves è lemmatizzato a love che è corretto, ma la parola loving rimane anche dopo loving lemmatizzazione. Qui loving è come nella frase "Lo sto amando".

Non è love lo stelo della parola flessa loving? Allo stesso modo, molte altre forme di "ing" rimangono come sono dopo la lemmatizzazione. È questo il comportamento corretto?

Quali sono alcuni altri lemmatizzatori che sono precisi? (Non è necessario essere in NLTK) Ci sono analizzatori morfologici o lemmatizzatori che tengono conto anche del tag Part of Speech di una parola, nel decidere la parola stem? Ad esempio, la parola killing dovrebbe avere kill come la radice se killing viene utilizzato come un verbo, ma dovrebbe avere killing come la radice se viene utilizzato come un nome (come in the killing was done by xyz).

risposta

40

Il WordNet lemmatizer fa prendere il tag POS in considerazione, ma non è così magicamente determinarlo:

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

Senza un tag POS, assume tutto ciò che lo alimentano è un sostantivo. Quindi qui pensa di passargli il nome "amorevole" (come in "dolce amore").

+4

Grazie per la risposta! Puoi anche dire, quali sono tutti i tag che prende? n-sostantivi, v = verbi ...? –

24

Il modo migliore per risolvere questo problema è in realtà cercare in Wordnet. Dai un'occhiata qui: Loving in wordnet. Come puoi vedere, c'è in realtà un aggettivo "amorevole" presente in Wordnet. In realtà, c'è anche l'avverbio "amorevolmente": lovingly in Wordnet. Poiché wordnet non sa in realtà quale parte del discorso vuoi effettivamente, per impostazione predefinita è noun ('n' in Wordnet). Se si utilizza Penn Treebank tag insieme, ecco qualche funzione utile per trasformare Penn a tag 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 

Spero che questo aiuti.

+3

wnpos = lambda e: ('a' if e [0] .lower() == 'j' else e [0] .lower()) if e [0] .lower() in ['n', ' r ',' v '] else' x ' –

+0

1 riga è leggermente migliore di 28;) – wordsforthewise

+0

Tuttavia, dovrebbe essere 'wnpos = lambda e: (' a 'if e [0] .lower() ==' j 'else e [0] .lower()) if e [0] .lower() in [' n ',' r ',' v '] else' n'' perché il valore predefinito per la funzione è NOUN, non 'x' o 'Nessuno'. – wordsforthewise

0

simili @bogs woth

Io uso 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, 

} 
1

è più chiara e più efficace di enumerazione:

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)