python nltk wordnet lemmatization

Lematización de wordnet y etiquetado pos en python



nltk lemmatization (6)

Pasos para convertir: Documento-> Oraciones-> Fichas-> POS-> Lemmas

import nltk from nltk.stem import WordNetLemmatizer from nltk.corpus import wordnet #example text text = ''What can I say about this place. The staff of these restaurants is nice and the eggplant is not bad'' class Splitter(object): """ split the document into sentences and tokenize each sentence """ def __init__(self): self.splitter = nltk.data.load(''tokenizers/punkt/english.pickle'') self.tokenizer = nltk.tokenize.TreebankWordTokenizer() def split(self,text): """ out : [''What'', ''can'', ''I'', ''say'', ''about'', ''this'', ''place'', ''.''] """ # split into single sentence sentences = self.splitter.tokenize(text) # tokenization in each sentences tokens = [self.tokenizer.tokenize(sent) for sent in sentences] return tokens class LemmatizationWithPOSTagger(object): def __init__(self): pass def get_wordnet_pos(self,treebank_tag): """ return WORDNET POS compliance to WORDENT lemmatization (a,n,r,v) """ 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: # As default pos in lemmatization is Noun return wordnet.NOUN def pos_tag(self,tokens): # find the pos tagginf for each tokens [(''What'', ''WP''), (''can'', ''MD''), (''I'', ''PRP'') .... pos_tokens = [nltk.pos_tag(token) for token in tokens] # lemmatization using pos tagg # convert into feature set of [(''What'', ''What'', [''WP'']), (''can'', ''can'', [''MD'']), ... ie [original WORD, Lemmatized word, POS tag] pos_tokens = [ [(word, lemmatizer.lemmatize(word,self.get_wordnet_pos(pos_tag)), [pos_tag]) for (word,pos_tag) in pos] for pos in pos_tokens] return pos_tokens lemmatizer = WordNetLemmatizer() splitter = Splitter() lemmatization_using_pos_tagger = LemmatizationWithPOSTagger() #step 1 split document into sentence followed by tokenization tokens = splitter.split(text) #step 2 lemmatization using pos tagger lemma_pos_token = lemmatization_using_pos_tagger.pos_tag(tokens) print(lemma_pos_token)

Quería usar wordnet lemmatizer en python y he aprendido que la etiqueta pos predeterminada es NOUN y que no genera el lema correcto para un verbo, a menos que la etiqueta pos se especifique explícitamente como VERB.

Mi pregunta es ¿cuál es la mejor toma para realizar la lematización anterior con precisión?

Hice el etiquetado pos utilizando nltk.pos_tag y estoy perdido en la integración de las etiquetas pos del banco de árboles a las etiquetas pos compatibles con wordnet. Por favor ayuda

from nltk.stem.wordnet import WordNetLemmatizer lmtzr = WordNetLemmatizer() tagged = nltk.pos_tag(tokens)

Obtengo las etiquetas de salida en NN, JJ, VB, RB. ¿Cómo puedo cambiar estas etiquetas compatibles con wordnet?

¿También tengo que entrenar nltk.pos_tag() con un corpus etiquetado o puedo usarlo directamente en mis datos para evaluar?


@Suzana_K estaba trabajando. Pero hay algunos resultados de casos en KeyError como @ Reloj esclavo mención.

Convertir etiquetas treebank a Wordnet etiqueta

from nltk.corpus import wordnet def get_wordnet_pos(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 None # for easy if-statement

Ahora, solo ingresamos pos en la función lematizar solo si tenemos la etiqueta wordnet

from nltk.stem.wordnet import WordNetLemmatizer lemmatizer = WordNetLemmatizer() tagged = nltk.pos_tag(tokens) for word, tag in tagged: wntag = get_wordnet_pos(tag) if wntag is None:# not supply tag in case of None lemma = lemmatizer.lemmatize(word) else: lemma = lemmatizer.lemmatize(word, pos=wntag)



En primer lugar, puedes usar nltk.pos_tag() directamente sin entrenarlo. La función cargará un etiquetador pre-entrenado desde un archivo. Puede ver el nombre del archivo con nltk.tag._POS_TAGGER :

nltk.tag._POS_TAGGER >>> ''taggers/maxent_treebank_pos_tagger/english.pickle''

Como se entrenó con el corpus de Treebank, también usa el conjunto de etiquetas Treebank .

La siguiente función asignaría las etiquetas treebank a la parte de WordNet de los nombres de voz:

from nltk.corpus import wordnet def get_wordnet_pos(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 ''''

Luego puede usar el valor de retorno con el lematizante:

from nltk.stem.wordnet import WordNetLemmatizer lemmatizer = WordNetLemmatizer() lemmatizer.lemmatize(''going'', wordnet.VERB) >>> ''go''

Verifique el valor de retorno antes de pasarlo al Lemmatizer porque una cadena vacía daría un KeyError .


Puede crear un mapa utilizando el dict predeterminado de Python y aprovechar el hecho de que para el lematizador la etiqueta predeterminada es Noun.

from nltk.corpus import wordnet as wn from nltk.stem.wordnet import WordNetLemmatizer from nltk import word_tokenize, pos_tag from collections import defaultdict tag_map = defaultdict(lambda : wn.NOUN) tag_map[''J''] = wn.ADJ tag_map[''V''] = wn.VERB tag_map[''R''] = wn.ADV text = "Another way of achieving this task" tokens = word_tokenize(text) lmtzr = WordNetLemmatizer() for token, tag in pos_tag(tokens): lemma = lmtzr.lemmatize(token, tag_map[tag[0]]) print(token, "=>", lemma)


Puedes hacer esto en una línea:

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

Luego use wnpos(nltk_pos) para obtener el POS para dar a .lemmatize (). En su caso, lmtzr.lemmatize(word=tagged[0][0], pos=wnpos(tagged[0][1])) .