python - tagger - pos tag nltk español
NLTK WordNet Lemmatizer: ¿No debería minimizar todas las inflexiones de una palabra? (4)
El lematizante de WordNet toma en cuenta la etiqueta POS, pero no la determina mágicamente:
>>> nltk.stem.WordNetLemmatizer().lemmatize(''loving'')
''loving''
>>> nltk.stem.WordNetLemmatizer().lemmatize(''loving'', ''v'')
u''love''
Sin una etiqueta POS, asume que todo lo que le das es un sustantivo. Así que aquí cree que le está pasando el sustantivo "amoroso" (como en "amoroso dulce").
Estoy utilizando el Lemmatizer de WordNet de NLTK para un proyecto de etiquetado de partes del habla, modificando primero cada palabra en el corpus de entrenamiento a su raíz (modificación in situ), y luego entrenando solo en el nuevo corpus. Sin embargo, encontré que el lematizante no está funcionando como esperaba.
Por ejemplo, la palabra loves
está lemmatizada al love
cual es correcto, pero la palabra loving
sigue siendo loving
incluso después de la lematización. Aquí loving
es como en la frase "lo estoy amando".
¿Acaso el love
no es la raíz de la palabra inflexionada? De manera similar, muchas otras formas ''ing'' permanecen como están después de la lematización. ¿Es este el comportamiento correcto?
¿Cuáles son algunos otros lematizadores que son precisos? (no es necesario que esté en NLTK) ¿Existen analizadores de morfología o lemmatizadores que también tienen en cuenta la etiqueta Part Of Speech de una palabra al decidir la raíz de la palabra? Por ejemplo, killing
la palabra debería tener kill
como la raíz si la killing
se usa como un verbo, pero debería tener la killing
como la raíz si se usa como un sustantivo (como en the killing was done by xyz
).
La mejor manera de solucionar este problema es buscar en Wordnet. Echa un vistazo aquí: Amar en wordnet . Como puede ver, en realidad hay un adjetivo "amante" presente en Wordnet. De hecho, incluso existe el adverbio "amorosamente": amorosamente en Wordnet . Debido a que wordnet no sabe realmente qué parte del discurso realmente desea, por defecto es sustantivo (''n'' en Wordnet). Si está usando el conjunto de etiquetas Penn Treebank, aquí tiene algunas funciones prácticas para transformar las etiquetas Penn en 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
Espero que esto ayude.
Similar woth @bogs
Yo 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,
}
es más claro y más efectivo que la enumeración:
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)