LDA (Latent Dirichlet Allocation) : Guide complet — Principes, Exemples et Implémentation Python
Résumé
Le LDA (Latent Dirichlet Allocation) est un modèle probabiliste génératif utilisé pour le topic modelling en traitement automatique du langage naturel (NLP). Il permet de découvrir automatiquement les thèmes latents présents dans un corpus de documents, sans aucune annotation manuelle. Chaque document y est représenté comme un mélange probabiliste de plusieurs topics, et chaque topic est lui-même une distribution de probabilité sur le vocabulaire. Le LDA repose sur la distribution de Dirichlet et utilise des méthodes d’inférence approximative telles que l’échantillonnage de Gibbs ou la variational Bayes pour estimer les paramètres cachés à partir des données observées.
Principe mathématique : le modèle génératif
Le LDA est un modèle génératif bayésien. Son idée fondamentale est la suivante : chaque document a été « généré » par un processus aléatoire qui mélange plusieurs topics selon certaines proportions. Pour comprendre le LDA, il faut décrire ce processus de génération en le renversant : on observe les documents, et on tente d’inférer a posteriori la structure de topics qui les a produits.
Le processus de génération
Voici le modèle génératif complet du LDA, document par document :
-
Générer les distributions de mots par topic : pour chaque topic k ∈ {1, …, K}, tirer une distribution sur les mots
φ__k ~ Dirichlet(β)
où β est le paramètre de concentration (souvent un vecteur symétrique β·1). -
Pour chaque document d ∈ {1, …, D} :
– Tirer la distribution des topics du document :
θ__d ~ Dirichlet(α)
où α est le paramètre de concentration prior sur les mélanges de topics.
– Pour chaque mot n dans le document d (total de N__d mots) :- Tirer une affectation de topic :
z__{d,n} ~ Multinomiale(θ__d) - Tirer le mot observé :
w_{d,n} ~ Multinomiale(φ_)}
- Tirer une affectation de topic :
Le graphe probabiliste
Le LDA possède une structure conditionnelle qui se représente par un plateau graphique (graphical model) :
- α (hyperparamètre) → θ__d (distribution topics du document) → z__{d,n} (affectation de chaque mot)
- β (hyperparamètre) → φ__k (distribution mots du topic) → w__{d,n} (mot observé)
Les seules variables observées sont les mots w__{d,n}. Tout le reste — les distributions θ_d, φ__k et les affectations z_ — est latent et doit être inféré.
Inférence : échantillonnage de Gibbs et Variational Bayes
Le calcul exact de la distribution a posteriori p(θ, φ, z | w, α, β) est intraitable pour des corpus de taille réaliste, car il nécessite d’intégrer sur un espace combinatoire gigantesque (chaque mot de chaque document peut appartenir à n’importe quel topic). Deux méthodes d’approximation sont couramment utilisées :
Échantillonnage de Gibbs collapsed (CGS) — C’est la méthode historique. On itère sur chaque mot de chaque document, et on rééchantillonne son affectation de topic z__{d,n} conditionnellement à toutes les autres affectations :
p(z_{d,n} = k | z_{¬(d,n)}, w, α, β) ∝
(n_{d,k}^{¬(d,n)} + α_k) × (n_{k,w}^{¬(d,n)} + β_w) / (n_k^{¬(d,n)} + Σ β)
où n_{d,k} est le nombre de mots du document d affectés au topic k, et n_ est le nombre de fois que le mot w apparaît dans le topic k.
Variational Bayes (VBI) — Introduite par Blei et al. (2003), cette méthode construit une distribution variationnelle q(θ, φ, z) qui minimise la divergence de Kullback-Leibler avec la vraie distribution a posteriori. C’est un algorithme de type EM (Expectation-Maximization) qui alterne entre mise à jour des paramètres variationnels et de la borne inférieure (ELBO). sklearn.LatentDirichletAllocation utilise la variational Bayes par défaut.
Intuition : le LDA expliqué simplement
Imaginez que vous êtes chef cuisinier et que vous goûtez à un plat sans connaître la recette. Votre tâche est de deviner quels ingrédients ont été utilisés et dans quelles proportions.
Dans cette analogie :
– Le plat, c’est un document.
– Les ingrédients de base (sel, tomates, basilic, fromage…), ce sont les topics.
– Chaque plat est un mélange de plusieurs ingrédients en proportions différentes : une pizza contient beaucoup de tomate et de fromage, un peu de basilic ; une margherita contient surtout de la mozzarella et de la tomate.
– De même, un document d’actualité sur l’énergie contient un peu de topic « politique », un peu de topic « technologie », et un gros topic « environnement ».
Le but du LDA est exactement cela : analyser un grand nombre de « plats » (documents) pour découvrir quels sont les ingrédients fondamentaux (topics) et reconstituer la recette (mélange de topics) de chaque document.
Et comme le chef qui doit deviner la recette sans la connaître, le LDA ne connaît ni les topics ni leurs proportions à l’avance. Il les découvre automatiquement en observant les cooccurrences de mots à travers tous les documents. Si les mots « vote », « scrutin » et « parlement » apparaissent toujours ensemble, le LDA regroupe ces mots en un topic « politique ».
Implémentation Python du LDA
1. LDA avec scikit-learn (LatentDirichletAllocation)
Scikit-learn propose une implémentation efficace de la variational Bayes pour le LDA. C’est l’approche la plus accessible pour démarrer.
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np
# Données : petit corpus de documents
documents = [
"Le vote des citoyens influence la composition du parlement.",
"L'intelligence artificielle révolutionne le secteur technologique.",
"Les actions cotées en bourse atteignent des sommets historiques.",
"Les élections législatives redessinent le paysage politique.",
"Le machine learning transforme l'industrie du numérique.",
"Le marché boursier réagit aux annonces de la BCE.",
"Le gouvernement propose une nouvelle réforme fiscale.",
"Les réseaux neuronaux profonds surpassent les méthodes classiques.",
"Les investisseurs craignent une correction du marché financier.",
"Le président annonce des mesures pour l'enseignement public."
]
# Étape 1 : Vectorisation (sac-de-mots)
vectorizer = CountVectorizer(
max_features=500, # Limiter le vocabulaire
stop_words=None, # À adapter selon la langue
min_df=1,
max_df=0.95 # Éliminer les mots trop fréquents
)
X = vectorizer.fit_transform(documents)
vocab = vectorizer.get_feature_names_out()
# Étape 2 : Appliquer le LDA
n_topics = 3
lda = LatentDirichletAllocation(
n_components=n_topics,
learning_method='batch', # 'batch' ou 'online'
learning_decay=0.7,
doc_topic_prior=None, # Auto (1/n_topics)
topic_word_prior=None, # Auto (1/n_topics)
max_iter=20,
random_state=42,
n_jobs=-1, # Parallélisation
verbose=1
)
# Ajustement
doc_topic_dist = lda.fit_transform(X)
# Étape 3 : Afficher les topics
def afficher_topics(model, feature_names, n_top_words=8):
for idx, topic in enumerate(model.components_):
print(f"\nTopic {idx + 1}:")
top_words_idx = topic.argsort()[:-n_top_words - 1:-1]
top_words = [feature_names[i] for i in top_words_idx]
print(" " + ", ".join(top_words))
afficher_topics(lda, vocab, n_top_words=6)
2. Distribution des documents sur les topics
Une fois le modèle entraîné, on peut examiner la distribution thématique de chaque document :
# Proportion de chaque topic dans chaque document
print("Distribution topics par document :")
for d_idx, dist in enumerate(doc_topic_dist):
dominant_topic = dist.argmax()
proportions = ", ".join(f"T{i}={v:.2f}" for i, v in enumerate(dist))
print(f" Doc {d_idx + 1}: {proportions} → Topic dominant: T{dominant_topic + 1}")
3. Choix du nombre de topics avec la perplexité
La perplexité mesure la qualité d’un modèle probabiliste : plus elle est basse, mieux le modèle généralise. C’est l’outil classique pour choisir K (le nombre de topics).
import matplotlib.pyplot as plt
perplexities = []
topic_range = range(2, 8)
for k in topic_range:
lda_k = LatentDirichletAllocation(
n_components=k,
random_state=42,
max_iter=20,
verbose=0
)
lda_k.fit(X)
perplexity = lda_k.perplexity(X)
perplexities.append(perplexity)
print(f"K={k}: perplexité = {perplexity:.2f}")
plt.figure(figsize=(8, 5))
plt.plot(topic_range, perplexities, 'bo-')
plt.xlabel("Nombre de topics (K)")
plt.ylabel("Perplexité")
plt.title("Perplexité en fonction du nombre de topics")
plt.grid(True, alpha=0.3)
plt.show()
4. Visualisation interactive avec pyLDAvis
# pip install pyLDAvis gensim
import gensim.corpora as corpora
import gensim
import pyLDAvis
import pyLDAvis.gensim_models as gensimvis
# Créer le dictionnaire et le corpus au format gensim
texts = [doc.lower().split() for doc in documents]
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]
# Entraîner le LDA gensim
lda_gensim = gensim.models.LdaModel(
corpus,
id2word=dictionary,
num_topics=3,
random_state=42,
passes=20
)
# Visualiser avec pyLDAvis
vis = gensimvis.prepare(lda_gensim, corpus, dictionary)
pyLDAvis.display(vis)
pyLDAvis offre une visualisation interactive : un scatter plot 2D des topics (proximité sémantique via MDS) et, au clic sur un topic, un histogramme des mots les plus associés. C’est l’outil de référence pour explorer et interpréter les résultats du LDA.
Hyperparamètres du LDA
Le choix des hyperparamètres influence profondément la qualité des topics découverts :
| Hyperparamètre | Description | Valeur typique |
|---|---|---|
n_components |
Nombre de topics K | 5–100 selon la taille du corpus |
learning_method |
'batch' (VBI classique) ou 'online' (VBI incrémentale) |
'online' pour les gros corpus |
learning_decay |
Taux d’apprentissage pour la méthode online | 0.5–0.9 (défaut : 0.7) |
doc_topic_prior (α) |
Contrôle la dispersion des topics par document | 1/K (défaut si None : sparse α) |
topic_word_prior (β) |
Contrôle la dispersion des mots par topic | 1/K (défaut si None : φ concentré) |
max_iter |
Nombre maximum d’itérations | 10–50 (surveiller la convergence via la log-vraisemblance) |
evaluate_every |
Fréquence d’évaluation de la perplexité | 0–10 |
L’impact de α (alpha)
- α faible (< 1/K) : chaque document se concentre sur peu de topics (distribution claire).
- α élevé (> 1/K) : chaque document contient beaucoup de topics (distribution uniforme).
- Règle pratique : démarrer avec α = 50/K et β = 0.1 pour des courts documents ; ajuster selon la cohérence.
L’impact de β (beta)
- β faible : chaque topic utilise peu de mots distinctifs (topics précis mais potentiellement fragiles).
- β élevé : les mots sont répartis uniformément entre les topics (topics moins distinctifs).
- La valeur par défaut
1/Kfonctionne généralement bien pour commencer.
Avantages du LDA
- Interprétabilité directe : Chaque topic est une liste pondérée de mots lisibles par un humain. C’est un atout majeur pour l’analyse exploratoire et la communication de résultats.
- Représentation soft : Contrairement au clustering dur (k-means), un document peut appartenir simultanément à plusieurs topics avec des degrés d’appartenance. Cela reflète bien la réalité des textes qui traitent souvent de plusieurs sujets.
- Fondation théorique solide : Le modèle génératif bayésien offre un cadre probabiliste rigoureux avec des garanties statistiques sur l’inférence.
- Non supervisé : Aucune annotation manuelle n’est nécessaire. Le LDA découvre les structures thématiques à partir des données brutes.
- Généralisation : Le modèle peut inférer la distribution de topics pour de nouveaux documents non vus pendant l’entraînement (transform dans scikit-learn).
- Évolutivité : La variante online LDA permet de traiter des corpus de millions de documents sans charger l’intégralité des données en mémoire.
Limites du LDA
- Indépendance des mots (sac-de-mots) : Le LDA ignore l’ordre des mots et la syntaxe. Les modèles à embeddings contextuels (BERT, Word2Vec) capturent mieux la sémantique fine.
- Choix de K : Il n’existe pas de méthode automatique fiable pour déterminer le nombre optimal de topics. La perplexité et la cohérence donnent des indications, mais le choix reste semi-empirique.
- Cohérence sémantique imparfaite : Les topics automatiques ne correspondent pas toujours à des catégories intuitives pour un humain. Un topic peut mélanger des concepts sans rapport apparent.
- Hypothèse d’échangeabilité : Le LDA suppose que les mots sont échangeables au sein d’un document. Cette hypothèse est forte et ne modélise ni la structure narrative ni les relations entre mots.
- Sensibilité au prétraitement : Le résultat dépend fortement du nettoyage (stop-words, lemmatisation, stemming, suppression des mots rares). Un pipeline NLP mal calibré produit des topics inexploitables.
- Pas de hiérarchie : Le LDA standard ne modélise pas la hiérarchie naturelle des topics (un topic « sport » contient des sous-topics « football », « tennis »). Pour cela, il faut des extensions comme le hLDA (hierarchical LDA).
- Sensibilité aux initialisations aléatoires : Différentes graines aléatoires produisent des topics sensiblement différents. Il est recommandé d’exécuter le LDA plusieurs fois et de retenir le résultat avec la meilleure log-vraisemblance.
4 cas d’usage concrets
Cas d’usage 1 : Exploration de corpus journalistique
Un média possède 50 000 articles publiés sur 10 ans. Le LDA permet de découvrir automatiquement les grandes lignes éditoriales, d’identifier les nouvelles tendances émergentes, et de visualiser l’évolution thématique du journal au fil du temps. Combiné à un découpage temporel, on obtient un suivi de l’émergence et du déclin de chaque sujet.
Cas d’usage 2 : Tri et routage de tickets clients
Une entreprise reçoit 3 000 tickets de support par semaine. Le LDA identifie automatiquement les grandes catégories de problèmes (facturation, bug technique, demande de fonctionnalité, question commerciale). Chaque ticket est affecté à sa distribution de topics, permettant un routage automatique vers le service compétent sans étiquetage manuel préalable.
Cas d’usage 3 : Analyse de recherche bibliographique
Un chercheur veut comprendre rapidement les axes de recherche d’un domaine scientifique. En appliquant le LDA sur 10 000 résumés d’articles extraits de PubMed ou arXiv, il identifie les courants scientifiques dominants, repère les zones peu explorées (topics faibles = opportunités de recherche), et cartographie l’évolution des thématiques sur plusieurs années.
Cas d’usage 4 : Analyse d’opinion et veille concurrentielle
En analysant 100 000 avis clients sur des plateformes e-commerce, le LDA révèle les axes thématiques de satisfaction et d’insatisfaction (qualité du produit, livraison, SAV, rapport qualité-prix, design). En appliquant le même modèle aux avis des concurrents, on obtient une cartographie comparative des forces et faiblesses perçues sur le marché.
Bonnes pratiques pour un LDA réussi
- Nettoyage agressif du texte : Supprimez les stop-words, appliquez la lemmatisation, filtrez les mots trop rares (min_df ≥ 2) et trop fréquents (max_df ≤ 0.95).
- Testez plusieurs valeurs de K : Exécutez le LDA pour K ∈ {5, 10, 20, 50, 100} et comparez la perplexité ainsi que la cohérence des topics (mesurée avec C_v ou UMass).
- Exécutez plusieurs graines : Lancez 5–10 exécutions avec des seeds différents et retenez celle qui maximise la log-vraisemblance.
- Validez avec un humain : Un topic n’est utile que s’il est interprétable. Demandez à un expert métier de lire les tops words de chaque topic et de juger leur pertinence.
- Combinez avec d’autres méthodes : Le LDA seul peut être fragile. Combine-le avec la NMF (Non-negative Matrix Factorization) pour valider la stabilité des topics, ou avec Word2Vec pour enrichir la représentation sémantique.
Voir aussi
- Maîtrisez L’Hypocycloïde et Points de Grille avec Python : Un Guide Complet
- Python et le Paradigme de l’Hôtel de Hilbert : Modélisation et Applications Innovantes

