Niveau
Débutant
Env.
Local (Windows), Local (Linux)
Code
Python
Libs
nltk
Sources

Du NLP avec Python NLTK

Dans un précédent article nous avons vu comment la librairie SpaCy pouvait nous aider à analyser et surtout exploiter des données textuelles. Nous allons voir dans cet article comment utiliser l’autre librairie (quelque peu concurrente, mais pas tant que ça finalement) NLTK de Python.

Installation de NLTK

Pour commencer nous devons installer la librairie. Pour celà vous devez bien sur déjà disposer de Python sur votre machine et ensuite utiliser PIP (package installer for Python) pour installer la librairie nltk :

ShellSession
pip install nltk

Ce n’est pas vraiment fini, car une fois la librairie installée, il faut maintenant télécharger tout le corpus NLTK afin de pouvoir utiliser ses fonctionnalités correctement.

Un corpus est un ensemble de documents, artistiques ou non (textes, images, vidéos, etc.), regroupés dans une optique précise.

Wikipédia

Dans notre cas, on n’entend par corpus que les éléments textuels.

Pour installer ces fameux corpus NLTK, et si comme moi vous utilisez Jupyter tapez simplement :

Python
import nltk
nltk.download()

Attendez quelques secondes et une fenêtre devrait s’ouvrir :

Téléchargement des corpus NLTK

Nous n’allons pas être sélectif et tout prendre pour ce tuto. Sélectionnez « All » et cliquez sur le bouton Download dans le coin inférieur gauche de la fenêtre. Puis patientez jusqu’à ce que tout soit téléchargé dans votre dossier de destination …

Commençons !

Maintenant que notre environnement NLTK est prêt, nous allons voir ensemble les fonctions de base de cette librairie. Pour celà nous allons utiliser ce texte :

Wikipédia est un projet wiki d’encyclopédie collective en ligne, universelle, multilingue et fonctionnant sur le principe du wiki. Aimez-vous l’encyclopédie wikipedia ?

Ensuite importons les librairies qui nous seront nécessaire:

Python
from nltk.corpus import stopwords
from nltk import word_tokenize
from nltk.tokenize import sent_tokenize
import re
data = u"""Wikipédia est un projet wiki d’encyclopédie collective en ligne, universelle, multilingue et fonctionnant sur le principe du wiki. Aimez-vous l'encyclopédie wikipedia ?"""

Les « stops words »

Avant toute chose il faudra retirer tous les mots qui n’apportent pas vraiment de valeurs à l’analyse globale du texte. On appelle ces mots les « stop words » et bien sur cette liste est propre à chaque langue. Bonne nouvelle, NLTK propose une liste de stop words en Français (toutes les langues ne sont en effet pas disponibles) :

Python
french_stopwords = set(stopwords.words('french'))
filtre_stopfr =  lambda text: [token for token in text if token.lower() not in french_stopwords]

Grâce à la fonction lambda de Python on créé une petite fonction qui nous permettra en une seule ligne de filtrer un texte à partir de la liste des stop words français.

french_stopwords = set(stopwords.words(‘french’)) filtre_stopfr = lambda text: [token for token in text if token.lower() not in french_stopwords]

Grâce à la fonction lambda de Python on créé une petite fonction qui nous permettra en une seule ligne de filtrer un texte à partir de la liste des stop words français.

Python
filtre_stopfr( word_tokenize(data, language="french") )
['Wikipédia',
 'projet',
 'wiki',
 '’',
 'encyclopédie',
 'collective',
 'ligne',
 ',',
 'universelle',
 ',',
 'multilingue',
 'fonctionnant',
 'principe',
 'wiki',
 '.',
 'Aimez-vous',
 "l'encyclopédie",
 'wikipedia',
 '?']

Voilà tous les mots (du genre articles, etc.) on été supprimés de la liste globale de mots. Cette fonction est vraiment utile, comparez par exemple avec un filtre qui n’utiliserait que des RegEx :

Python
sp_pattern = re.compile( """[\.\!\"\s\?\-\,\']+""", re.M).split
sp_pattern(data)

Tokenisation

Avec NLTK on peut découper par mot avec la fonction word_tokenize(…) ou par phrase sent_tokenize(…). Commençons par un découpage par phrase :

Python
sent_tokenize(data, language="french")
['Wikipédia est un projet wiki d’encyclopédie collective en ligne, universelle, multilingue et fonctionnant sur le principe du wiki.',
 "Aimez-vous l'encyclopédie wikipedia ?"]

Intéressant mais la tokenization par mot l’est encore plus bien sur :

Python
word_tokenize(data, language="french")
['Wikipédia',
 'est',
 'un',
 'projet',
 'wiki',
 'd',
...
 'Aimez-vous',
 "l'encyclopédie",
 'wikipedia',
 '?']

Et si on combine cette fonction avec le filtre des stops words vu précédemment, c’est encore plus intéressant :

Python
filtre_stopfr( word_tokenize(data, language="french") )
['Wikipédia',
 'projet',
 'wiki',
 '’',
 'encyclopédie',
 'collective',
 'ligne',
 ',',
 'universelle',
 ',',
 'multilingue',
 'fonctionnant',
 'principe',
 'wiki',
 '.',
 'Aimez-vous',
 "l'encyclopédie",
 'wikipedia',
 '?']

Fréquence de distribution des valeurs

Il peut être intéressant d’avoir la fréquence de distribution des valeurs, pour celà il existe bien entendu une fonction FreqDist():

Python
fd = nltk.FreqDist(phfr) 
print(fd.most_common())
[('wiki', 2), (',', 2), ('Wikipédia', 1), ('projet', 1), ('’', 1), ('encyclopédie', 1), ('collective', 1), ('ligne', 1), ('universelle', 1), ('multilingue', 1), ('fonctionnant', 1), ('principe', 1), ('.', 1), ('Aimez-vous', 1), ("l'encyclopédie", 1), ('wikipedia', 1), ('?', 1)]

Cette fonction renvoit un Tableau a deux dimensions dans lequel on trouve chaque valeur du corpus avec sa fréquence de distribution. A titre d’exemple le mot wiki est placé 2 fois dans le texte.

Stemmatisation

Maintenant il serait interressant de regrouper les mots ayant la même racine synthaxique, pour cela nous allons utiliser la fonction de stemmatisation de NLTK : stem(). Bonne nouvelle encore il existe une fonction pour le français FrenchStemmer() ! nous allons bien sur l’utiliser ici :

Python
example_words = ["donner","don","donne","donnera","dons","test"]
stemmer = FrenchStemmer()
for w in example_words:
    print(stemmer.stem(w))
don
don
don
don
don
test

La fonction de stemmatisation a bien retrouvé les racines du mot « don ». Honnêtement ça ne marche pas toujours aussi bien malheureusement, mais cette fonction peut néanmoins s’avérer utile pour un premier débroussaillage.

Conclusion

L’objectif de cet article étant de montrer les fonctionnalités de base de NLTK nous ne sommes pas entré dans le détail. Cette librairie est riche, très riche même mais nécessite pas mal d’ajustement si vous voulez créer des fonctions à base de NLP puissante. Les différences avec SpaCy ? en fait il en a beaucoup, la philosophie des ces deux librairie est totalement différente (objet vs approche traditionnelle pour NLTK par exemple) … en fait je pense qu’il faut plutot voir ces deux librairies comme complémentaires, chacune apportant à l’autre ses propres manques.

Partager cet article

6 Replies to “Du NLP avec Python NLTK”

  1. Merci pour cet article qui m’a permis de monter mon colab en y ajoutant BeautifulSoup pour aller un epu plus loin et scraper le contenu d’un site puis d’en analyser les entitées.
    Ce que je trouve dommage : la liste de stopwords n’est pas assez large. En effet, il reste à la fin des , . / ? ! $…
    Je ne suis pas dev et pas bon en python. j’ai essayé d’appliqyer la regex que tu mentionnes, en plus de la liste de stopwords, mais je me retrouve avec une erreur…
    Au plaisir,
    Clément

  2. Bonjour Benoit,
    A mon tour je te remercie pour ta présentation.
    Je partage l’avis de Clément, les « : » et « / » qui restent dans le texte proviennent de la concaténation des mots pour passer d’un filtre à l’autre.
    Une fois modifié ce point, je te proposerai également d’enlever le « set » de la ligne :
    french_stopwords = set(stopwords.words(‘french’)) D’ailleurs il apparaît en rouge
    Sans le « set » il est faile de « french_stopwords.append(‘re’) pour enrichir la liste de ‘re’ par exemple
    Qu’en penses tu ?
    Bien codialement,
    Maussa

  3. Merci bcp pour cet article et ce site, très intéressants.
    A la ligne fd = nltk.FreqDist(phfr), la variable phfr n’existe pas, mais il suffit de l’affecter à filtre_stopfr(word_tokenize(data, language= »french »))
    A la ligne stemmer = FrenchStemmer(), FrenchStemmer() n’est pas reconnu par Python. J’ai remplacé par stemmer=nltk.stem.SnowballStemmer(‘french’)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.