Dans cet article, nous découvrons les fondamentaux du Natural Language Processing en se concentrant sur le preprocessing des données.


Sommaire

I. Introduction
• A. Le Natural Language Processing
• B. Du texte à la matrice : le bag-of-words

II. Preprocessing
• A. Récupération du corpus
• B. La tokenization
• C. Reformatage (Regex, lowercase)
• D. Suppression des stop-words
• E. Les mots les plus fréquents
• F. La lemmatisation
• G. Le stemming


I. Introduction

A. Le Natural Language Processing

Le Natural Language Processing (ou NLP) est un ensemble de méthodes informatiques permettant de comprendre ou d’analyser le langage humain. On parle de corpus pour désigner l’ensemble des documents analysés.

On peut avoir une approche purement statistique (on parle alors de lexicométrie) en étudiant des données telles que les occurrences des mots par exemple.
Plus largement, le NLP va permettre de modéliser des motifs dans le texte en s’intéressant à la co-occurence de certains mots par exemple. Ainsi, si il est extrêmement difficile de trouver des règles tout à fait générales en NLP, le Machine Learning va permettre de les découvrir et de les appliquer aux corpus suivants.

whatisnlp

Looks fascinating, right?

Voici, entre autres, quelques sujets sur lesquels travailler avec du NLP :

  • l’analyse de sentiments,
  • la modĂ©lisation de thĂ©matiques,
  • la traduction automatique…

B. Du texte Ă  la matrice : le bag-of-words

Comme introduit dans mon article sur le Machine Learning, il est nécessaire de représenter nos données sous forme de matrices pour - in fine - leur appliquer des modèles prédictifs. Prenons le corpus suivant : “Je suis un homme. Un homme souvent paradoxal.”.
Il est possible de représenter ce corpus sous forme de vecteur. A chaque fois qu’un nouveau mot apparaît, il est ajouté au vecteur : [je suis un homme souvent paradoxal]

Pour décrire une phrase, on va ensuite attribuer 1 si le mot est présent, 0 sinon. “Un homme souvent paradoxal” devient [0 0 1 1 1 1].

On forme ce qu’on appelle des bag-of-words !

  • Le bag-of-words : Pour que chaque occurence de mots ne viennent pas agrandir le vecteur, nous les regroupons en les ajoutant Ă  leur première apparition. Cela va former un vecteur dont la longueur est l’ensemble du vocabulaire (c’est-Ă -dire des mots diffĂ©rents) dans l’ensemble des documents du corpus. Chaque document pourra ainsi ĂŞtre dĂ©crit par ce mĂŞme vecteur [a b c …] avec a, b, c, … le nombre d’occurences – dans le document – du mot reprĂ©sentĂ©.

Par ailleurs, forcer le vecteur à attribuer une position fixe à chaque mot commence à répondre à une problématique inhérente au NLP. Plus le corpus est grand, plus le vecteur va contenir de mots et donc devenir coûteux d’un point de vue calcul machine. Il existe donc des méthodes permettant, par exemple, de regrouper les mots sous la forme de leur radical : [découper, coupant, couperaient] deviennent [coupe]. Cela permet de limiter le temps de calcul tout en conservant (généralement) le sens des mots. Mais passons à la pratique.


II. Preprocessing

Dans cet article, j’ai choisi de travailler avec la librairie NLTK. Il en existe d’autres telles que les librairies spaCy et Gensim qui permettent elles aussi de réaliser la plupart des étapes qui vont suivre.

A. Récupération du corpus

La première étape consiste à récupérer le corpus sur lequel on souhaite travailler. Pour se faire, il existe différentes méthodes qui ne seront pas décrites en détail dans cet article.
On pourrait par exemple récupérer des fichiers de données sur des plateformes opendata (comme Kaggle) ou scraper des pages web pour en extraire le contenu (voir mon article sur le scraping).
Pour avoir une première intuition des fonctions que nous allons utiliser, prenons les phrases suivantes en guise de corpus :

# Import de NLTK, librairie phare du NLP
import nltk
nltk.download('punkt')

# Génération du corpus
corpus = "Ceci est une introduction à l’analyse textuelle. Do$nt l'analyse pour’rait po$$ser problème." 

On va maintenant se rapprocher de la représentation vectorielle attendue. Pour se faire, on peut tokenizer notre corpus.

B. La tokenization

  • La tokenization : permet le dĂ©coupage en mots des diffĂ©rents documents qui constituent le corpus.
# Tokenization en vecteur de mots
clean_corpus = nltk.word_tokenize(corpus)

Il est maintenant possible de nettoyer le texte pour le préparer à l’analyse.
Il s’agit de normaliser le vecteur de mots dans le but de supprimer des détails inutiles au dictionnaire qu’on souhaite construire (ponctuation, caractères spéciaux, conjugaison, mots ayant trop de poids dans le cadre d’un modèle prédictif de thématiques…). Pour cela, voici les méthodes les plus communément appliquer.

C. Reformatage (Regex, lowercase)

  • Les Regex : (ou expressions rĂ©gulières) permettent de filtrer les chaĂ®nes de caractères pour se dĂ©barasser de certains caractères inutiles comme des Ă©lĂ©ments de ponctuation.
# Tokenization avec application d’une regex pour se débarrasser des caractères inutiles
tokenizer = nltk.RegexpTokenizer(r'\w+')
clean_corpus = tokenizer.tokenize(corpus)

On peut maintenant compter le nombre de mots qui composent le corpus.

# Longueur du corpus (mots)
print(len(clean_corpus))
  • Le lowercase : consiste Ă  passer toutes les lettres des mots en minuscules. Ceci permet d’éviter qu’un mĂŞme mot soit prĂ©sent deux fois dans le vecteur (ex : “Je” et “je”).
# Passage au lowercase
clean_corpus = [w.lower() for w in clean_corpus]

D. Suppression des stop-words

  • Suppression des stop-words : qui sont les mots très courants dans la langue Ă©tudiĂ©e (“et”, “à”, “le”… en français) et qui n’apportent pas rĂ©ellement de valeur informative pour la comprĂ©hension du sens du texte.
from nltk.corpus import stopwords

# Stockage des stop-words français
stop_words = stopwords.words('french')

# Ajout manuel de stop-words
other_stop_words = ['dont', 'ceci']
for w in other_stop_words:
    stop_words.append(w)

print(stop_words)
# Suppression des stop-words du corpus
clean_corpus = [w for w in clean_corpus if not w in stop_words]

Il est désormais intéressant de visualiser les mots les plus fréquents.

E. Les mots les plus fréquents

# Fréquence des mots
fdist1 = nltk.FreqDist(clean_corpus)
print(fdist1.most_common(50))
fdist1.plot(50)

wordfreq

A ce niveau, les mots les plus fréquents le sont souvent car ils sont présents dans tous les textes. Ils restent largement informatifs mais sont peu discriminants dans le cas où on souhaiterait trouver ce qui distingue les textes les uns des autres.

  • Suppression des mots les plus frĂ©quents : dans le cas oĂą on souhaite distinguer des types de textes, il convient de supprimer les mots qu’ils ont en commun pour ne garder que ceux qui permettent de les distinguer.

F. La lemmatisation

  • La lemmatisation : qui consiste Ă  reprĂ©senter les mots sous leur forme canonique. Les verbes conjuguĂ©s vont ĂŞtre passĂ©s Ă  l’infinitif, les noms au masculin singulier…

G. Le stemming

  • Le stemming : qui permet de supprimer les prĂ©fixes/suffixes connus pour ne garder que la racine (donc la partie la plus porteuse de sens) des mots.