2017-07-30 8 views
3

Je voudrais lemmater du texte italien afin d'effectuer un comptage fréquentiel de mots et d'autres recherches sur la sortie de ce contenu lemmatisé. Je préfère la lemmatisation plutôt que le stemming parce que je pourrais extraire le mot sens du contexte dans la phrase (par exemple, distinguer un verbe et un nom) et obtenir des mots qui existent dans la langue, plutôt que des racines de ces mots qui n'ont généralement pas de sens.Lemmatisation des phrases italiennes pour le comptage de fréquence

Je trouve cette bibliothèque appelée pattern (pip2 install pattern) qui devrait compléter nltk afin d'effectuer lemmatisation du langue italienne, mais je ne suis pas sûr de l'approche ci-dessous est correcte, car chaque mot est lemmatisée par lui-même, pas le contexte d'une phrase. Probablement je devrais donner pattern la responsabilité de marquer une phrase (ainsi annoter chaque mot avec les métadonnées concernant les verbes/noms/adjectifs etc), puis récupérer le mot lemmatisé, mais je ne suis pas capable de le faire et je suis pas même sûr que c'est possible en ce moment?

Aussi: en italien certains articles sont rendus avec une apostrophe donc par exemple "l'appartamento" (en anglais "l'appartement") est en fait 2 mots: "lo" et "appartamento". En ce moment je ne suis pas en mesure de trouver un moyen de diviser ces 2 mots avec une combinaison de nltk et pattern alors je ne suis pas capable de compter la fréquence des mots de la bonne façon.

import nltk 
import string 
import pattern 

# dictionary of Italian stop-words 
it_stop_words = nltk.corpus.stopwords.words('italian') 
# Snowball stemmer with rules for the Italian language 
ita_stemmer = nltk.stem.snowball.ItalianStemmer() 

# the following function is just to get the lemma 
# out of the original input word (but right now 
# it may be loosing the context about the sentence 
# from where the word is coming from i.e. 
# the same word could either be a noun/verb/adjective 
# according to the context) 
def lemmatize_word(input_word): 
    in_word = input_word#.decode('utf-8') 
    # print('Something: {}'.format(in_word)) 
    word_it = pattern.it.parse(
     in_word, 
     tokenize=False, 
     tag=False, 
     chunk=False, 
     lemmata=True 
    ) 
    # print("Input: {} Output: {}".format(in_word, word_it)) 
    the_lemmatized_word = word_it.split()[0][0][4] 
    # print("Returning: {}".format(the_lemmatized_word)) 
    return the_lemmatized_word 

it_string = "Ieri sono andato in due supermercati. Oggi volevo andare all'ippodromo. Stasera mangio la pizza con le verdure." 

# 1st tokenize the sentence(s) 
word_tokenized_list = nltk.tokenize.word_tokenize(it_string) 
print("1) NLTK tokenizer, num words: {} for list: {}".format(len(word_tokenized_list), word_tokenized_list)) 

# 2nd remove punctuation and everything lower case 
word_tokenized_no_punct = [string.lower(x) for x in word_tokenized_list if x not in string.punctuation] 
print("2) Clean punctuation, num words: {} for list: {}".format(len(word_tokenized_no_punct), word_tokenized_no_punct)) 

# 3rd remove stop words (for the Italian language) 
word_tokenized_no_punct_no_sw = [x for x in word_tokenized_no_punct if x not in it_stop_words] 
print("3) Clean stop-words, num words: {} for list: {}".format(len(word_tokenized_no_punct_no_sw), word_tokenized_no_punct_no_sw)) 

# 4.1 lemmatize the words 
word_tokenize_list_no_punct_lc_no_stowords_lemmatized = [lemmatize_word(x) for x in word_tokenized_no_punct_no_sw] 
print("4.1) lemmatizer, num words: {} for list: {}".format(len(word_tokenize_list_no_punct_lc_no_stowords_lemmatized), word_tokenize_list_no_punct_lc_no_stowords_lemmatized)) 

# 4.2 snowball stemmer for Italian 
word_tokenize_list_no_punct_lc_no_stowords_stem = [ita_stemmer.stem(i) for i in word_tokenized_no_punct_no_sw] 
print("4.2) stemmer, num words: {} for list: {}".format(len(word_tokenize_list_no_punct_lc_no_stowords_stem), word_tokenize_list_no_punct_lc_no_stowords_stem)) 

# difference between stemmer and lemmatizer 
print(
    "For original word(s) '{}' and '{}' the stemmer: '{}' '{}' (count 1 each), the lemmatizer: '{}' '{}' (count 2)" 
    .format(
     word_tokenized_no_punct_no_sw[1], 
     word_tokenized_no_punct_no_sw[6], 
     word_tokenize_list_no_punct_lc_no_stowords_stem[1], 
     word_tokenize_list_no_punct_lc_no_stowords_stem[6], 
     word_tokenize_list_no_punct_lc_no_stowords_lemmatized[1], 
     word_tokenize_list_no_punct_lc_no_stowords_lemmatized[1] 
    ) 
) 

donne cette sortie:

1) NLTK tokenizer, num words: 20 for list: ['Ieri', 'sono', 'andato', 'in', 'due', 'supermercati', '.', 'Oggi', 'volevo', 'andare', "all'ippodromo", '.', 'Stasera', 'mangio', 'la', 'pizza', 'con', 'le', 'verdure', '.'] 
2) Clean punctuation, num words: 17 for list: ['ieri', 'sono', 'andato', 'in', 'due', 'supermercati', 'oggi', 'volevo', 'andare', "all'ippodromo", 'stasera', 'mangio', 'la', 'pizza', 'con', 'le', 'verdure'] 
3) Clean stop-words, num words: 12 for list: ['ieri', 'andato', 'due', 'supermercati', 'oggi', 'volevo', 'andare', "all'ippodromo", 'stasera', 'mangio', 'pizza', 'verdure'] 
4.1) lemmatizer, num words: 12 for list: [u'ieri', u'andarsene', u'due', u'supermercato', u'oggi', u'volere', u'andare', u"all'ippodromo", u'stasera', u'mangiare', u'pizza', u'verdura'] 
4.2) stemmer, num words: 12 for list: [u'ier', u'andat', u'due', u'supermerc', u'oggi', u'vol', u'andar', u"all'ippodrom", u'staser', u'mang', u'pizz', u'verdur'] 
For original word(s) 'andato' and 'andare' the stemmer: 'andat' 'andar' (count 1 each), the lemmatizer: 'andarsene' 'andarsene' (count 2) 
  • Comment lemmatiser efficacement quelques phrases avec pattern en utilisant leur tokenizer? (en supposant que les lemmes sont reconnus comme des noms/verbes/adjectifs, etc.)
  • Existe-t-il une alternative python à pattern à utiliser pour la lemmatisation italienne avec nltk?
  • Comment diviser des articles liés au mot suivant en utilisant des apostrophes?

Répondre

1

Je vais essayer de répondre à votre question, sachant que je ne connais pas beaucoup l'italien!

1) Pour autant que je sache, la principale responsabilité pour enlever l'apostrophe est le tokenizer, et en tant que tel le tokenizer italien nltk semble avoir échoué.

3) Une chose simple que vous pouvez faire à ce sujet est d'appeler la méthode replace (bien que vous devrez probablement utiliser le package re pour modèle plus complexe), un exemple:

word_tokenized_no_punct_no_sw_no_apostrophe = [x.split("'") for x in word_tokenized_no_punct_no_sw] 
word_tokenized_no_punct_no_sw_no_apostrophe = [y for x in word_tokenized_no_punct_no_sw_no_apostrophe for y in x] 

Il donne:

['ieri', 'andato', 'due', 'supermercati', 'oggi', 'volevo', 'andare', 'all', 'ippodromo', 'stasera', 'mangio', 'pizza', 'verdure'] 

2) Une alternative à motif serait treetagger, accordé ce n'est pas le plus facile d'installer de tous (vous avez besoin du python package et le tool itself, mais après cette partie, il fonctionne sur Windows et Linux).

Un exemple simple avec votre exemple ci-dessus:

import treetaggerwrapper 
from pprint import pprint 

it_string = "Ieri sono andato in due supermercati. Oggi volevo andare all'ippodromo. Stasera mangio la pizza con le verdure." 
tagger = treetaggerwrapper.TreeTagger(TAGLANG="it") 
tags = tagger.tag_text(it_string) 
pprint(treetaggerwrapper.make_tags(tags)) 

Les pprint rendements:

[Tag(word=u'Ieri', pos=u'ADV', lemma=u'ieri'), 
Tag(word=u'sono', pos=u'VER:pres', lemma=u'essere'), 
Tag(word=u'andato', pos=u'VER:pper', lemma=u'andare'), 
Tag(word=u'in', pos=u'PRE', lemma=u'in'), 
Tag(word=u'due', pos=u'ADJ', lemma=u'due'), 
Tag(word=u'supermercati', pos=u'NOM', lemma=u'supermercato'), 
Tag(word=u'.', pos=u'SENT', lemma=u'.'), 
Tag(word=u'Oggi', pos=u'ADV', lemma=u'oggi'), 
Tag(word=u'volevo', pos=u'VER:impf', lemma=u'volere'), 
Tag(word=u'andare', pos=u'VER:infi', lemma=u'andare'), 
Tag(word=u"all'", pos=u'PRE:det', lemma=u'al'), 
Tag(word=u'ippodromo', pos=u'NOM', lemma=u'ippodromo'), 
Tag(word=u'.', pos=u'SENT', lemma=u'.'), 
Tag(word=u'Stasera', pos=u'ADV', lemma=u'stasera'), 
Tag(word=u'mangio', pos=u'VER:pres', lemma=u'mangiare'), 
Tag(word=u'la', pos=u'DET:def', lemma=u'il'), 
Tag(word=u'pizza', pos=u'NOM', lemma=u'pizza'), 
Tag(word=u'con', pos=u'PRE', lemma=u'con'), 
Tag(word=u'le', pos=u'DET:def', lemma=u'il'), 
Tag(word=u'verdure', pos=u'NOM', lemma=u'verdura'), 
Tag(word=u'.', pos=u'SENT', lemma=u'.')] 

Il a également tokenisé assez bien la all'ippodromo-al et ippodromo (qui est, espérons-correct) sous le capot avant de lemmatiser. Maintenant, nous avons juste besoin d'appliquer la suppression des mots d'arrêt et de la ponctuation et ce sera bien.

bibliothèque The doc for installing the TreeTaggerWrapper pour python

+1

Merci, cela a fonctionné. Sur linux, le chemin où les scripts sont installés pourrait être spécifié directement dans le code python, par ex. 'treetaggerwrapper.TreeTagger (TAGLANG =" il ", TAGDIR = '/ abs-chemin/vers/arborescence-tag-linux-3.2.1 /')', ou comme une variable d'environnement comme expliqué ici http: //treetaggerwrapper.readthedocs .io/fr/latest/# configuration Aussi pour obtenir juste les lemmes des tuples nommés 'Tag':' tags_str = tagger.tag_text (it_string) 'alors' tags = treetaggerwrapper.make_tags (tags_str) 'alors' lemmas = map ((lambda x: x.lemma), balises) ' – TPPZ