Modélisation des thèmes avec LDA
Découvrez les thèmes latents d’un corpus de documents avec le paquet topicmodels.
Modélisation des thèmes avec LDA est une leçon R Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage R Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours R Academy comprend 4 leçons au total.
Qu'est-ce que la modélisation thématique ?
La modélisation thématique est une technique d'apprentissage automatique non supervisé qui découvre la structure thématique latente d'un corpus. Latent Dirichlet Allocation (LDA) suppose que chaque document est un mélange de K thèmes et que chaque thème est une distribution de probabilités sur les mots.
# LDA key assumptions:
# 1. Each document is a mixture of K topics
# 2. Each topic is a distribution over all vocabulary words
# 3. Words are generated by first picking a topic, then a word from that topic
# Example: K=2 topics in a corpus about tech and cooking
# Topic 1 (Tech): neural(0.15) python(0.12) algorithm(0.10) ...
# Topic 2 (Cooking): recipe(0.14) flour(0.11) bake(0.10) ...
# A document about 'AI-generated recipes' might be:
# 70% Topic 1 (Tech) + 30% Topic 2 (Cooking)
cat('LDA parameters:\n')
cat('K = number of topics (you choose)\n')
cat('alpha = document-topic sparsity prior\n')
cat('beta = topic-word sparsity prior\n')DocumentTermMatrix avec tm
LDA nécessite une matrice document-termes (DTM) : les lignes sont les documents, les colonnes sont les mots et les cellules contiennent le nombre d'occurrences des mots. La fonction DocumentTermMatrix() du package tm et la fonction cast_dtm() de tidytext produisent toutes deux ce format.
library(tm)
# Build a corpus from raw text
docs <- c(
'machine learning neural networks training algorithms',
'deep learning gradient backpropagation optimizer',
'python scikit numpy pandas machine learning',
'database sql tables indexes queries joins',
'relational schema normalization foreign primary',
'nosql mongodb document store redis queries'
)
corpus <- Corpus(VectorSource(docs))
corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, removeWords, stopwords('english'))
corpus <- tm_map(corpus, stripWhitespace)
dtm <- DocumentTermMatrix(corpus)
cat('DTM shape:', nrow(dtm), 'docs x', ncol(dtm), 'terms\n')
cat('Sparsity: ', round(tm::sparsity(dtm) * 100, 1), '%\n')cast_dtm de tidytext
cast_dtm(document, term, value) convertit directement un tibble organisé de comptages de mots en un DocumentTermMatrix compatible avec le package topicmodels. Votre pipeline reste ainsi dans le style tidyverse.
library(tidytext)
library(dplyr)
# Tidy corpus
corpus <- tibble::tibble(
doc_id = c(rep(1, 3), rep(2, 3), rep(3, 3), rep(4, 3)),
text = c(
'neural networks deep learning training',
'gradient descent backpropagation optimizer',
'machine learning algorithms classification',
'database sql tables queries indexes',
'relational schema normalization joins',
'foreign primary key constraints transactions',
'recipe bake flour butter oven',
'cooking temperature simmer saute ingredients',
'kitchen knife herbs spices garnish'
)
)
dtm <- corpus |>
unnest_tokens(word, text) |>
anti_join(tidytext::stop_words, by = 'word') |>
count(doc_id, word) |>
cast_dtm(doc_id, word, n)
cat('DTM:', nrow(dtm), 'docs x', ncol(dtm), 'terms\n')LDA(dtm, k = 5) : ajuster le modèle
LDA(dtm, k = K, control = list(seed = 42)) ajuste un modèle LDA comportant K thèmes à l'aide de l'échantillonnage de Gibbs ou de VEM. Définissez toujours un seed pour assurer la reproductibilité : LDA est stochastique et les résultats varient d'une exécution à l'autre sans valeur de départ fixe.
library(tidytext)
library(dplyr)
library(topicmodels)
# Build DTM
corpus <- tibble::tibble(
doc_id = c(rep(1,3), rep(2,3), rep(3,3), rep(4,3), rep(5,3), rep(6,3)),
text = c(
'neural networks deep gradient','backpropagation training optimizer','learning model layers',
'database sql queries indexes','relational tables joins foreign','schema normalization constraints',
'recipe flour bake butter','cooking temperature oven simmer','kitchen knife herbs spices'
)[rep(c(1,2,3,4,5,6), each=1)]
)
dtm <- corpus |>
unnest_tokens(word, text) |>
count(doc_id, word) |>
cast_dtm(doc_id, word, n)
# Fit LDA with k=3 topics
lda_model <- LDA(dtm, k = 3, control = list(seed = 42))
cat('LDA model fitted: k=3 topics\n')
cat('Class:', class(lda_model), '\n')tidy(lda, matrix = 'beta') : probabilités thématiques par mot
tidy(lda_model, matrix = 'beta') extrait les probabilités thématiques par mot (la matrice bêta). Chaque ligne indique la probabilité qu'un mot donné ait été produit par un thème donné. Les mots présentant une probabilité élevée définissent le sujet de chaque thème.
library(topicmodels)
library(tidytext)
library(dplyr)
# Using the built-in AssociatedPress dataset
data('AssociatedPress', package = 'topicmodels')
lda <- LDA(AssociatedPress[1:50, ], k = 4, control = list(seed = 1234))
# Per-word topic probabilities (beta)
beta_tbl <- tidy(lda, matrix = 'beta')
cat('Beta matrix rows:', nrow(beta_tbl), '\n')
cat('Columns:', names(beta_tbl), '\n')
# Top words per topic
top_terms <- beta_tbl |>
group_by(topic) |>
slice_max(beta, n = 5) |>
ungroup()
cat('\nTop 5 words per topic:\n')
print(top_terms)Visualiser les mots des thèmes
Représentez les N mots principaux de chaque thème sous forme de graphique à barres par facettes. Triez les mots au sein de chaque thème selon la valeur bêta à l'aide de reorder_within() et scale_x_reordered() de tidytext, afin d'obtenir un ordre indépendant correct pour chaque facette.
library(topicmodels)
library(tidytext)
library(dplyr)
library(ggplot2)
data('AssociatedPress', package = 'topicmodels')
lda <- LDA(AssociatedPress[1:100, ], k = 4, control = list(seed = 42))
tidy(lda, matrix = 'beta') |>
group_by(topic) |>
slice_max(beta, n = 8) |>
ungroup() |>
mutate(term = reorder_within(term, beta, topic)) |>
ggplot(aes(term, beta, fill = factor(topic))) +
geom_col(show.legend = FALSE) +
facet_wrap(~topic, scales = 'free') +
scale_x_reordered() +
coord_flip() +
labs(x = NULL, y = 'Beta', title = 'Top Words per LDA Topic') +
theme_minimal(base_size = 10)tidy(lda, matrix = 'gamma') : probabilités thématiques par document
tidy(lda_model, matrix = 'gamma') extrait les probabilités thématiques par document (la matrice gamma). Chaque ligne indique la proportion d'un document estimée comme provenant d'un thème donné. Les documents dont la valeur gamma est élevée pour le thème 2 portent principalement sur le thème 2.
library(topicmodels)
library(tidytext)
library(dplyr)
data('AssociatedPress', package = 'topicmodels')
lda <- LDA(AssociatedPress[1:30, ], k = 3, control = list(seed = 99))
# Per-document topic proportions (gamma)
gamma_tbl <- tidy(lda, matrix = 'gamma')
cat('Gamma matrix rows:', nrow(gamma_tbl), '\n')
# Dominant topic per document
dominant_topic <- gamma_tbl |>
group_by(document) |>
slice_max(gamma, n = 1) |>
ungroup()
cat('\nDominant topic per document (first 8):\n')
print(head(dominant_topic, 8))Choisir K : nombre de thèmes
LDA vous demande de définir K à l'avance. Approches courantes : (1) la perplexité — une valeur plus faible est préférable, mais elle diminue monotoniquement avec K ; (2) le score de cohérence (package ldatuning) ; (3) les connaissances du domaine ; (4) essayer K = 5, 10, 20 et examiner manuellement les listes de mots.
library(topicmodels)
library(tidytext)
data('AssociatedPress', package = 'topicmodels')
# Evaluate perplexity for K = 2, 3, 4, 5
k_values <- 2:5
perplexities <- vapply(k_values, function(k) {
model <- LDA(AssociatedPress[1:50, ], k = k,
control = list(seed = 42))
perplexity(model)
}, numeric(1))
results <- data.frame(k = k_values, perplexity = round(perplexities, 1))
cat('Perplexity by K:\n')
print(results)
cat('\nNote: lower perplexity = better fit to training data\n')Attribuer des noms aux thèmes
LDA produit des thèmes anonymes (1, 2, 3…). L'analyste doit attribuer un nom à chaque thème en examinant ses mots principaux. Créez une table de correspondance reliant les numéros des thèmes à des noms descriptifs, puis joignez-la à vos résultats.
library(topicmodels)
library(tidytext)
library(dplyr)
data('AssociatedPress', package = 'topicmodels')
lda <- LDA(AssociatedPress[1:100, ], k = 4, control = list(seed = 7))
# Top 5 words per topic for manual labelling
tidy(lda, matrix = 'beta') |>
group_by(topic) |>
slice_max(beta, n = 5) |>
summarise(top_words = paste(term, collapse = ', ')) |>
print()
# After inspecting top words, assign human-readable labels
topic_labels <- tibble::tibble(
topic = 1:4,
label = c('Politics', 'Economy', 'Sports', 'Science') # your interpretation
)
cat('\nTopic labels assigned (example):\n')
print(topic_labels)LDA sur un corpus personnalisé
Voici un pipeline LDA complet, de bout en bout, appliqué à un corpus personnalisé : tokeniser, construire la DTM, ajuster LDA, extraire la matrice bêta et afficher les mots principaux de chaque thème.
library(tidytext)
library(dplyr)
library(topicmodels)
# 9 documents across 3 latent topics
docs <- tibble::tibble(
id = 1:9,
text = c(
'machine learning neural deep training',
'algorithm gradient backpropagation network',
'python tensorflow keras model layers',
'database sql relational tables queries',
'joins indexes schema foreign primary',
'transactions normalization constraints',
'recipe ingredients bake flour butter',
'cooking temperature simmer oven saute',
'kitchen knife herbs spices garnish'
)
)
dtm <- docs |>
unnest_tokens(word, text) |>
count(id, word) |>
cast_dtm(id, word, n)
lda <- LDA(dtm, k = 3, control = list(seed = 123))
tidy(lda, 'beta') |>
group_by(topic) |>
slice_max(beta, n = 4) |>
summarise(words = paste(term, collapse = ', ')) |>
print()Limites de LDA
LDA suppose un modèle en sac de mots (l'ordre des mots n'a pas d'importance), des thèmes statiques dans tout le corpus, et un choix préalable de K. Pour des thèmes dynamiques ou hiérarchiques, envisagez STM (Structural Topic Model) ou CTM (Correlated Topic Model), disponibles dans le package stm.
# LDA assumptions and limitations
limitations <- data.frame(
Assumption = c(
'Bag of words', 'Fixed K', 'Topic independence',
'Static topics', 'No metadata'
),
Alternative = c(
'word2vec / BERT',
'ldatuning for K selection',
'CTM (Correlated Topic Model)',
'DTM (Dynamic Topic Model)',
'STM (Structural Topic Model)'
)
)
print(limitations, row.names = FALSE)Vérification rapide
Dans LDA, que représente la matrice bêta ?
Récapitulatif : modélisation thématique avec LDA
Points essentiels :
- LDA découvre K thèmes latents sous forme de distributions de mots à partir d'une matrice document-termes
- Construisez la DTM avec
cast_dtm(document, word, n)(tidytext) ouDocumentTermMatrix()(tm) LDA(dtm, k = K, control = list(seed = 42))ajuste le modèletidy(lda, 'beta')= probabilités thématiques par mot (ce qui définit chaque thème)tidy(lda, 'gamma')= proportions thématiques par document (le sujet de chaque document)- Utilisez la perplexité ou les scores de cohérence pour guider le choix de K
- Examinez toujours manuellement les mots principaux pour nommer les thèmes
library(topicmodels)
library(tidytext)
library(dplyr)
data('AssociatedPress', package = 'topicmodels')
lda <- LDA(AssociatedPress[1:20, ], k = 2, control = list(seed = 1))
tidy(lda, 'beta') |>
group_by(topic) |>
slice_max(beta, n = 3) |>
summarise(top_words = paste(term, collapse = ', ')) |>
print()Questions Fréquemment Posées
La leçon « Modélisation des thèmes avec LDA » est-elle gratuite ?
Oui — le texte complet de « Modélisation des thèmes avec LDA » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours R Academy, passe à CoddyKit PRO. Le cours R Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Modélisation des thèmes avec LDA » ?
Découvrez les thèmes latents d’un corpus de documents avec le paquet topicmodels. Tu pratiques R Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer R Academy ?
Aucune expérience préalable n'est requise. R Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Modélisation des thèmes avec LDA » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon R Academy ?
Oui. Chaque leçon R Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Tokenisation et suppression des mots vides
- TF-IDF et analyse de la fréquence des termes
- Analyse des sentiments dans R
- Modélisation des thèmes avec LDA