Tu as cinq mille avis clients, douze mille tickets de support ou trois ans d'articles, et personne n'a le temps de tout lire. Le topic modeling est fait pour ça : une méthode non supervisée qui regarde ton corpus et en ressort les thèmes qui reviennent, sans que tu aies à étiqueter la moindre ligne. Avec gensim, la référence du traitement de texte en Python, tu obtiens ces thèmes en quelques lignes de code. On part d'un petit corpus d'exemple pour comprendre le mécanisme, puis tu le brancheras sur tes vrais textes.
L'idée de LDA tient en une phrase : des mots qui apparaissent souvent ensemble dans les mêmes documents forment un thème. Le modèle ne sait rien de tes textes à l'avance — il déduit tout seul cette structure cachée. C'est pour ça qu'on parle d'apprentissage non supervisé : pas d'étiquettes, pas d'exemples corrigés, juste du texte brut.
Étape 1 — Installer gensim
Une commande suffit. gensim embarque tout ce qu'il faut pour le topic modeling : la tokenisation, la construction du dictionnaire et le modèle LDA (Latent Dirichlet Allocation), l'algorithme qui découvre les thèmes.
pip install gensimÉtape 2 — Préparer le corpus
Un corpus, c'est une simple liste de textes. Pour l'exemple, on en prend vingt-quatre qui tournent autour de quatre univers : le sport, la programmation, la cuisine et la politique. Quelques mots qui se répètent dans chaque groupe suffisent à LDA pour deviner les thèmes.
documents = [
# sport
"le match a été intense et l'équipe a arraché la victoire dans les dernières minutes",
"le but inscrit en fin de match offre la victoire aux supporters du stade",
"la victoire en championnat passe par un bon début de match",
"les supporters du stade ont vu leur équipe marquer un but décisif",
"ce match nul ne satisfait personne malgré une belle prestation",
"le but de la victoire est célébré par tout le stade en délire",
# programmation
"j'écris du code python pour entraîner un modèle sur des données",
"le code python de ce programme charge les données puis le modèle",
"ce modèle apprend à partir des données grâce à du code python",
"les données sont transformées avant d'être données au modèle",
"le programme python exécute le modèle sur de nouvelles données",
"un modèle de machine learning a besoin de code et de données",
# cuisine
"la recette de la pâte demande une cuisson lente au four",
"le cuisinier prépare la pâte puis la met au four pour la cuisson",
"cette recette réussit grâce à une cuisson précise au four",
"la pâte repose avant la cuisson au four selon la recette",
"pour cette recette, la cuisson au four dure trente minutes",
"le four doit être chaud avant d'enfourner la pâte de la recette",
# politique
"le gouvernement propose une loi examinée au parlement",
"les députés votent la loi après un débat au parlement",
"le parlement examine la loi proposée par le gouvernement",
"cette loi divise le gouvernement et les députés",
"le vote au parlement décidera du sort de la loi",
"le gouvernement défend sa loi devant le parlement réuni",
]Étape 3 — Tokeniser et nettoyer
LDA travaille sur des listes de mots, pas sur des phrases. simple_preprocess découpe le texte en jetons, retire la ponctuation et, grâce à deacc=True, enlève les accents. Reste à virer les mots vides (« le », « de », « et ») qui pollueraient les thèmes. gensim n'embarque pas de stopwords français, alors on en fournit une petite liste.
from gensim.utils import simple_preprocess
STOPWORDS = {
"le", "la", "les", "des", "du", "de", "un", "une", "et", "a", "au", "aux",
"ce", "cette", "ces", "que", "qui", "dans", "pour", "par", "sur", "avec",
"est", "sont", "ne", "pas", "mais", "ou", "comme", "plus", "aussi", "tres",
"bien", "etre", "avoir", "faire", "d", "l", "s", "tout", "tous", "sa", "son",
"ses", "on", "il", "elle", "ils", "elles", "apres", "grace", "moi", "toi",
"avant", "alors", "quand", "encore", "en", "puis", "ete",
}
textes = [
[mot for mot in simple_preprocess(doc, deacc=True) if mot not in STOPWORDS]
for doc in documents
]Petit piège : deacc=True retire les accents, donc on écrit « tres » et « apres » sans accent dans la liste des mots vides. simple_preprocess met aussi tout en minuscules, ce qui évite de compter « Python » et « python » comme deux mots différents.
Étape 4 — Dictionnaire et sac de mots
LDA ne comprend que des entiers. On assigne un identifiant à chaque mot (le dictionnaire), puis on transforme chaque texte en sac de mots (bag-of-words) : une liste de couples (id_mot, fréquence).
from gensim import corpora
dictionnaire = corpora.Dictionary(textes)
dictionnaire.filter_extremes(no_below=1, no_above=0.8)
corpus_bow = [dictionnaire.doc2bow(t) for t in textes]filter_extremes supprime les mots qui apparaissent presque partout (no_above=0.8) ou presque nulle part. On obtient une matrice creuse, exactement le format que LDA attend.
Étape 5 — Entraîner LDA et lire les thèmes
On entraîne le modèle en lui demandant quatre thèmes. passes contrôle le nombre de passages sur le corpus : plus c'est haut, plus le résultat est stable, au prix d'un entraînement plus long.
from gensim.models import LdaModel
modele = LdaModel(
corpus=corpus_bow,
num_topics=4,
id2word=dictionnaire,
passes=100,
random_state=9,
)
for idx, sujet in modele.print_topics(num_words=4):
print(f"Sujet {idx}: {sujet}")Et le résultat :
Sujet 0: 0.104*"four" + 0.088*"recette" + 0.088*"cuisson" + 0.071*"pate"
Sujet 1: 0.110*"loi" + 0.093*"parlement" + 0.075*"gouvernement" + 0.040*"deputes"
Sujet 2: 0.127*"donnees" + 0.109*"modele" + 0.074*"python" + 0.074*"code"
Sujet 3: 0.068*"victoire" + 0.067*"but" + 0.067*"stade" + 0.047*"match"Quatre sujets, quatre univers, sans avoir étiqueté un seul document : la cuisine (four, recette, cuisson), la politique (loi, parlement, gouvernement), la programmation (données, modèle, python, code) et le sport (victoire, but, stade, match). Le nombre devant chaque mot, c'est son poids dans le thème.
Une astuce pour nommer tes thèmes : lis à voix haute les trois mots les plus lourds de chaque sujet. « four, recette, cuisson » se comprend instantanément comme « cuisine ». Sur un vrai corpus, c'est souvent tout ce qu'il faut pour étiqueter tes sujets sans les relire un par un.
random_state=9 fige l'aléa pour rendre le résultat reproductible : relance le script, tu retombes sur les mêmes thèmes.
Étape 6 — Classer un nouveau document
La partie la plus utile : un nouveau texte arrive, et tu veux savoir de quoi il parle. On le tokenise de la même façon, on le convertit, et le modèle renvoie sa répartition sur les quatre thèmes.
nouveau = [mot for mot in simple_preprocess(
"j'écris du code python et j'entraîne un modèle sur des données", deacc=True
) if mot not in STOPWORDS]
nouveau_bow = dictionnaire.doc2bow(nouveau)
for sujet, poids in sorted(modele.get_document_topics(nouveau_bow), key=lambda x: -x[1]):
print(f"Sujet {sujet}: {poids:.2f}")Sortie :
Sujet 2: 0.87
Sujet 3: 0.04
Sujet 1: 0.04
Sujet 0: 0.04Le sujet 2 (la programmation) écrase tout à 0,87. Tu peux donc trier des milliers de messages en un tour de boucle, ou faire remonter les textes hors sujet dont aucun thème ne dépasse un seuil.
Ce corpus d'exemple est minuscule : sur de vrais volumes — des milliers d'avis — les thèmes deviennent bien plus nets. Deux réglages à retenir : num_topics, le nombre de thèmes que tu soupçonnes (fais-le varier pour voir), et passes, la stabilité au prix du temps de calcul. Côté usages, le topic modeling sert partout où le volume de texte dépasse ce qu'un humain peut lire : trier les tickets de support, repérer les sujets qui reviennent dans les avis, ou faire une première passe sur un corpus avant de le confier à un LLM pour le résumé. Le LLM résume un texte à la fois ; LDA, lui, te dit de quoi parle tout le corpus d'un coup.
Auteur
Krugz
Développeur fullstack
Développeur fullstack qui tente, tant bien que mal, de suivre l'actualité de l'IA au milieu d'une marée d'informations imbuvables et des milliers d'outils et de modèles qui sortent chaque jour.






