Module 6 — Variables de texte : sacs de mots et n-grammes
Commentaires clients, descriptions de produits, tickets de support : le texte est partout, et aucun modèle tabulaire ne le consomme directement. Ce module donne les représentations classiques, qui restent d'excellentes lignes de base — souvent difficiles à battre, toujours rapides et interprétables, contrairement aux approches par plongements qu'aborderont les cours de traitement du langage.
Normaliser d'abord
Avant toute vectorisation, on réduit les variations qui n'apportent rien. « Excellent », « EXCELLENT » et « excellent! » désignent la même chose et doivent le devenir dans les données.
Les opérations usuelles : passer en minuscules, retirer la ponctuation, normaliser les espaces. Deux choix demandent en revanche une décision réfléchie.
Les mots vides (« le », « de », « et ») encombrent sans discriminer, et on les retire d'ordinaire. Mais pas toujours : dans une analyse de sentiment, la négation « ne… pas » est décisive, et la supprimer inverse le sens de la phrase. La liste de mots vides se choisit en fonction de la tâche, jamais par défaut aveugle.
La racinisation et la lemmatisation ramènent les formes fléchies à une base commune, afin que « courait », « courir » et « course » comptent ensemble. La racinisation tronque brutalement, la lemmatisation utilise un dictionnaire et produit un résultat linguistiquement correct ; elle est plus lente mais plus fiable.
Le sac de mots
L'idée du sac de mots est de compter les occurrences : chaque mot du vocabulaire devient une colonne, chaque document une ligne de comptes. On perd l'ordre — d'où le nom — mais on obtient une matrice numérique exploitable.
from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(
lowercase=True,
max_features=5000, # ne garde que les 5000 mots les plus frequents
min_df=5, # ignore les mots vus dans moins de 5 documents
max_df=0.8, # ignore les mots presents dans plus de 80 % des documents
)
X = vec.fit_transform(textes)
Les trois paramètres de filtrage font l'essentiel du travail. min_df élimine les fautes de frappe et les termes trop rares pour être appris ; max_df élimine les mots omniprésents, donc non discriminants ; max_features borne la dimension. Sans eux, la matrice atteint des dizaines de milliers de colonnes presque vides.
TF-IDF : pondérer par la rareté
Compter brut a un défaut : un mot fréquent dans tous les documents pèse lourd sans distinguer quoi que ce soit. La pondération TF-IDF corrige cela en combinant deux quantités : la fréquence du terme dans le document (TF) et l'inverse de sa fréquence documentaire (IDF), c'est-à-dire sa rareté dans le corpus.
Un mot qui apparaît souvent dans ce document mais rarement ailleurs obtient un poids élevé : c'est précisément un mot caractéristique. À l'inverse, un mot présent partout voit son poids s'effondrer.
from sklearn.feature_extraction.text import TfidfVectorizer
X = TfidfVectorizer(max_features=5000, min_df=5, ngram_range=(1, 2)).fit_transform(textes)
TF-IDF est le choix par défaut pour la classification de texte, et il surpasse presque toujours le comptage brut.
Les n-grammes : récupérer un peu d'ordre
Le sac de mots ignore l'ordre, ce qui pose un problème réel : « pas bon » et « bon » partagent le mot « bon ». Les n-grammes répondent en comptant des séquences de mots consécutifs. Avec ngram_range=(1, 2), on compte les mots seuls et les paires : « pas bon » devient une variable à part entière, distincte de « bon ».
Le coût est une explosion du vocabulaire, d'où l'importance de min_df et max_features. En pratique, les bigrammes apportent un gain net, les trigrammes rarement assez pour justifier la dimension supplémentaire.
Les variables descriptives, trop souvent oubliées
Avant de vectoriser, quelques variables simples se calculent en une ligne et se révèlent fréquemment très prédictives :
df["nb_caracteres"] = df["texte"].str.len()
df["nb_mots"] = df["texte"].str.split().str.len()
df["nb_majuscules"] = df["texte"].str.count(r"[A-Z]")
df["nb_exclamations"] = df["texte"].str.count("!")
La longueur d'un commentaire, la proportion de majuscules ou le nombre de points d'exclamation portent un signal réel — sur le mécontentement, sur le caractère indésirable d'un message. Ces variables coûtent presque rien et s'ajoutent aux variables tabulaires existantes, là où une matrice TF-IDF de 5 000 colonnes s'y intègre plus difficilement.
Sac de mots et TF-IDF traitent les mots comme des symboles indépendants : « voiture » et « automobile » restent deux colonnes sans rapport. Les représentations par plongements et par transformeurs, objets des cours 12 et 13, capturent cette proximité sémantique. Mais commencez ici : sur des corpus de taille modeste et pour une tâche de classification simple, TF-IDF plus régression logistique constitue une ligne de base rapide, interprétable, et fréquemment très proche des approches lourdes.
En résumé
- On normalise d'abord (minuscules, ponctuation) ; mots vides et lemmatisation se décident selon la tâche, la négation pouvant être essentielle.
- Le sac de mots compte les occurrences et perd l'ordre ;
min_df,max_dfetmax_featuresmaîtrisent la dimension. - TF-IDF pondère par la rareté dans le corpus et met en avant les mots caractéristiques : c'est le choix par défaut.
- Les n-grammes récupèrent une part de l'ordre (« pas bon ») ; et les variables descriptives simples sont peu coûteuses et souvent prédictives.
Module suivant : les variables issues d'agrégations et de fenêtres temporelles, où l'on construit de l'information à partir de plusieurs lignes.