Sulla base di varie risposte su Stack Overflow e sui blog che ho incontrato, questo è il metodo che sto usando e sembra restituire parole reali abbastanza bene. L'idea è di dividere il testo in arrivo in una matrice di parole (usa il metodo che desideri), quindi trova le parti del discorso (POS) per quelle parole e usale per aiutare a arginare e lemmatizzare le parole.
Il tuo esempio sopra non funziona troppo bene, perché il POS non può essere determinato. Tuttavia, se usiamo una frase vera, le cose funzionano molto meglio.
import nltk
from nltk.corpus import wordnet
lmtzr = nltk.WordNetLemmatizer().lemmatize
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 wordnet.NOUN
def normalize_text(text):
word_pos = nltk.pos_tag(nltk.word_tokenize(text))
lemm_words = [lmtzr(sw[0], get_wordnet_pos(sw[1])) for sw in word_pos]
return [x.lower() for x in lemm_words]
print(normalize_text('cats running ran cactus cactuses cacti community communities'))
# ['cat', 'run', 'ran', 'cactus', 'cactuses', 'cacti', 'community', 'community']
print(normalize_text('The cactus ran to the community to see the cats running around cacti between communities.'))
# ['the', 'cactus', 'run', 'to', 'the', 'community', 'to', 'see', 'the', 'cat', 'run', 'around', 'cactus', 'between', 'community', '.']