Analyse des correspondances (AFC) en R avec FactoMineR

Transformez un tableau de contingence à deux entrées en une carte reliant les lignes aux colonnes

Un guide pratique de l’analyse des correspondances (AFC) en R : tester l’association d’un tableau de contingence avec le khi-deux, exécuter CA() de FactoMineR, lire les valeurs propres et l’éboulis, et visualiser l’association lignes-colonnes sur un biplot symétrique avec fviz_ca_biplot() de factoextra. Illustré sur les données housetasks, avec contributions et cos2.

Date de publication

24 juin 2026

Modifié

7 juillet 2026

AstucePoints clés
  • L’analyse des correspondances (AFC) est l’équivalent de l’ACP pour un tableau de contingence — elle cartographie l’association entre les lignes et les colonnes du croisement de deux variables catégorielles sur un graphique en 2-D.
  • Testez d’abord l’association. Réalisez un test du khi-deux d’indépendance ; si les lignes et les colonnes sont indépendantes, l’AFC n’a rien à révéler.
  • L’information totale que l’AFC décompose est l’inertie totale \(\phi^2 = \chi^2 / n\) — la statistique du khi-deux divisée par l’effectif total.
  • Calculez-la avec CA() de FactoMineR, puis lisez les valeurs propres / l’éboulis (fviz_eig) pour décider combien de dimensions conserver.
  • L’image standard est le biplot symétrique (fviz_ca_biplot) : des points-lignes proches partagent un profil, des points-colonnes proches partagent un profil — mais ne lisez jamais littéralement la distance ligne-colonne sur une carte symétrique.
  • Utilisez fviz_ca_row() / fviz_ca_col() colorés par contribution ou cos2 pour repérer quelles catégories définissent chaque axe.
Obtenez le livre — Principal Component Methods in R (PDF)

Introduction

L’analyse des correspondances (AFC) est une extension de l’analyse en composantes principales adaptée aux données catégorielles plutôt que continues. Là où l’ACP résume un tableau de mesures numériques, l’AFC résume un tableau de contingence — le croisement de deux variables catégorielles — et visualise l’association entre ses catégories en ligne et ses catégories en colonne sur une carte de faible dimension.

Utilisez-la lorsque votre question est « quelles catégories en ligne vont avec quelles catégories en colonne ? » — quels produits se vendent dans quelles régions, quels symptômes se regroupent avec quels diagnostics, quelles tâches ménagères incombent à quel membre du couple. L’AFC vous donne un graphique unique et interprétable où les catégories associées se retrouvent proches les unes des autres, ce qui vous permet de lire la structure d’un grand tableau croisé d’un coup d’œil.

Cette leçon fait partie de la série Réduction de dimension — le moderne Practical Guide to Principal Component Methods in R. L’AFC traite deux variables catégorielles (un seul tableau de contingence) ; pour plusieurs variables catégorielles, utilisez sa cousine l’analyse des correspondances multiples (ACM). Nous calculons l’AFC avec FactoMineR et la visualisons avec factoextra, exactement comme pour l’ACP.

Les données

Nous utiliserons le jeu de données housetasks fourni avec factoextra. C’est un tableau de contingence de 13 tâches ménagères (les lignes) et de la façon dont chacune est partagée dans un couple (les 4 colonnes) : réalisée par l’épouse seule, en alternance, par l’époux seul, ou conjointement. Chaque cellule est une fréquence — un décompte du nombre de fois qu’une tâche incombe à un arrangement donné.

library(factoextra)
data(housetasks)

# A contingency table: 13 tasks (rows) x 4 arrangements (columns)
head(housetasks)
           Wife Alternating Husband Jointly
Laundry     156          14       2       4
Main_meal   124          20       5       4
Dinner       77          11       7      13
Breakfeast   82          36      15       7
Tidying      53          11       1      57
Dishes       32          24       4      53

Le tableau est assez petit pour être lu à l’œil : Laundry, Main_meal et Dinner sont dominés par la colonne Wife ; Repairs et Driving par Husband ; Holidays se situe dans Jointly. Le travail de l’AFC est de transformer cette intuition en une carte précise — et de le faire automatiquement lorsque le tableau est bien trop grand pour être lu à l’œil.

NoteL’AFC a besoin de décomptes, pas de données brutes

L’entrée doit être un tableau de contingence de décomptes (un tableau croisé), pas un tableau de données brut avec une ligne par observation. Si vous avez des données brutes, construisez d’abord le tableau avec table(var1, var2), puis passez-le à CA().

Y a-t-il une association ? Le test du khi-deux

Avant de cartographier l’association, confirmez qu’il y en a une. Le test du khi-deux d’indépendance demande si les variables en ligne et en colonne sont liées le moins du monde.

NoteHypothèses
  • H₀ : les variables en ligne et en colonne sont indépendantes (aucune association — rien à montrer pour l’AFC).
  • Hₐ : les variables en ligne et en colonne sont associées (dépendantes).

chisq.test() prend directement le tableau de contingence :

library(factoextra)
data(housetasks)

chisq <- chisq.test(housetasks)
chisq

    Pearson's Chi-squared test

data:  housetasks
X-squared = 1944.5, df = 36, p-value < 2.2e-16

La statistique du khi-deux est de 1944.5 pour 36 degrés de liberté — les degrés de liberté valent \((r-1)(c-1) = (13-1)(4-1) = 36\) — avec une p-value bien en deçà de 0.05. Les lignes et les colonnes de housetasks sont fortement et significativement associées, il vaut donc la peine d’exécuter l’AFC pour voir comment.

L’AFC ne décompose pas la variance comme le fait l’ACP — elle décompose l’inertie, et l’inertie n’est qu’un khi-deux remis à l’échelle. Pour une cellule de décompte observé \(o\) et de décompte attendu sous indépendance \(e = (\text{row sum} \times \text{col sum}) / n\), la statistique du khi-deux est

\[ \chi^2 = \sum \frac{(o - e)^2}{e}. \]

L’inertie totale que l’AFC décompose est cette statistique divisée par l’effectif total \(n\) :

\[ \phi^2 = \frac{\chi^2}{n}. \]

Pour housetasks, \(\phi^2 = 1944.5 / 1744 = 1.115\) — ce qui correspond exactement à la somme des valeurs propres de l’AFC ci-dessous. L’AFC étale donc littéralement l’association du khi-deux sur quelques axes interprétables. La racine carrée de \(\phi^2\) (la trace) se comporte comme un coefficient de corrélation ; une valeur supérieure à 0.2 signale une dépendance ligne-colonne notable.

Calculer l’AFC

Le moteur est CA() de FactoMineR. L’appel minimal prend le tableau de contingence ; nous fixons graph = FALSE car nous tracerons nous-mêmes les (plus jolis) graphiques de factoextra :

library(FactoMineR)
data(housetasks)

res.ca <- CA(housetasks, graph = FALSE)

CA() renvoie un objet riche contenant les valeurs propres, ainsi que les coordonnées, le cos2, les contributions et l’inertie pour les lignes comme pour les colonnes. Son affichage liste chaque composante :

library(FactoMineR)
data(housetasks)
res.ca <- CA(housetasks, graph = FALSE)

print(res.ca)
**Results of the Correspondence Analysis (CA)**
The row variable has  13  categories; the column variable has 4 categories
The chi square of independence between the two variables is equal to 1944.456 (p-value =  0 ).
*The results are available in the following objects:

   name              description                   
1  "$eig"            "eigenvalues"                 
2  "$col"            "results for the columns"     
3  "$col$coord"      "coord. for the columns"      
4  "$col$cos2"       "cos2 for the columns"        
5  "$col$contrib"    "contributions of the columns"
6  "$row"            "results for the rows"        
7  "$row$coord"      "coord. for the rows"         
8  "$row$cos2"       "cos2 for the rows"           
9  "$row$contrib"    "contributions of the rows"   
10 "$call"           "summary called parameters"   
11 "$call$marge.col" "weights of the columns"      
12 "$call$marge.row" "weights of the rows"         

La statistique du khi-deux et sa p-value figurent en haut de summary(res.ca) / print(res.ca) — un khi-deux élevé signifie un lien ligne-colonne fort, ce que nous venons précisément de confirmer.

Valeurs propres et éboulis

Comme dans l’ACP, les valeurs propres vous indiquent quelle part de l’inertie totale chaque dimension (axe) capture, et donc combien de dimensions vous sont nécessaires. Extrayez-les avec get_eigenvalue() :

library(FactoMineR)
library(factoextra)
data(housetasks)
res.ca <- CA(housetasks, graph = FALSE)

get_eigenvalue(res.ca)
      eigenvalue variance.percent cumulative.variance.percent
Dim.1  0.5428893         48.69222                    48.69222
Dim.2  0.4450028         39.91269                    88.60491
Dim.3  0.1270484         11.39509                   100.00000

La dimension 1 explique 48.7% de l’inertie et la dimension 2 39.9% de plus, soit un cumul de 88.6% — un plan en 2-D conserve donc presque toute l’association des données. (Leurs valeurs propres, 0.543 + 0.445 + 0.127, somment à 1.115 — l’inertie totale \(\phi^2\) issue du khi-deux ci-dessus.)

Un éboulis (scree plot) montre la même chose visuellement. fviz_eig() (alias fviz_screeplot()) trace le pourcentage d’inertie par dimension ; le « coude » suggère où les axes supplémentaires cessent de compter :

library(FactoMineR)
library(factoextra)
data(housetasks)
res.ca <- CA(housetasks, graph = FALSE)

fviz_eig(res.ca, addlabels = TRUE, ylim = c(0, 50))

Scree plot of the percentage of inertia explained by each CA dimension of the housetasks data: about 49% for dimension 1, 40% for dimension 2, and 11% for dimension 3.

Il existe aussi une règle de coupure simple. Si les données étaient aléatoires, chaque axe porterait en moyenne \(1/(r-1) = 1/12 = 8.3\%\) de l’inertie des lignes, ou \(1/(c-1) = 1/3 = 33.3\%\) de l’inertie des colonnes ; un axe qui vaut la peine d’être conservé devrait dépasser la plus grande des deux (33.3%). Seules les dimensions 1 et 2 franchissent cette barre — la troisième n’explique que 11.4% — ce qui est précisément pourquoi le biplot en 2-D ci-dessous suffit.

Le biplot symétrique

La figure emblématique de l’AFC est le biplot symétrique — lignes et colonnes tracées dans le même espace. fviz_ca_biplot() le dessine :

library(FactoMineR)
library(factoextra)
data(housetasks)
res.ca <- CA(housetasks, graph = FALSE)

# repel = TRUE keeps the labels from overlapping
fviz_ca_biplot(res.ca, repel = TRUE)

Symmetric CA biplot of the housetasks data: blue points are house tasks and red triangles are the people who do them, arranged on dimensions 1 and 2 so that associated categories fall in the same region.

Les lignes (les tâches) sont des points bleus, les colonnes (les arrangements) des triangles rouges. Lecture de la carte :

  • Les tâches proches du triangle WifeLaundry, Main_meal, Dinner, Breakfeast — sont réalisées plus souvent par l’épouse.
  • Les tâches proches du triangle HusbandRepairs, Driving, Insurance — incombent à l’époux.
  • Holidays se situe à l’écart, près de Jointly ; Official et Finances se situent entre les pôles.
AvertissementLisez la distance ligne-colonne avec prudence

Sur un biplot symétrique, seules les distances ligne-à-ligne et colonne-à-colonne sont strictement interprétables — des points-lignes proches partagent un profil, des points-colonnes proches partagent un profil. La distance entre un point-ligne et un point-colonne n’est pas directement signifiante ; vous ne pouvez faire qu’une affirmation générale sur le motif d’ensemble (dans quelle région se trouve une catégorie). Pour comparer rigoureusement une ligne précise à une colonne précise, utilisez un biplot asymétrique (fviz_ca_biplot(res.ca, map = "rowprincipal", arrow = c(TRUE, TRUE))) et projetez la ligne sur la flèche de la colonne.

Lignes : contribution et qualité (cos2)

Pour aller au-delà de l’image d’ensemble, demandez-vous quelles catégories définissent chaque axe. Les fonctions factoextra get_ca_row() / get_ca_col() exposent les coordonnées, le cos2 (qualité de représentation) et la contribution de chaque point ; les graphiques fviz_ca_row() / fviz_ca_col() peuvent colorer les points par l’un ou l’autre.

Commencez par les lignes, colorées par contribution — les points qui construisent les axes :

library(FactoMineR)
library(factoextra)
data(housetasks)
res.ca <- CA(housetasks, graph = FALSE)

fviz_ca_row(res.ca, col.row = "contrib",
            gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
            repel = TRUE)

CA factor map of the housetasks rows, coloured by contribution from blue (low) to red (high); Repairs, Driving, Laundry and Main_meal contribute most and sit far from the origin.

Les points les plus rouges et les plus éloignés contribuent le plus. Repairs, Driving, Laundry et Main_meal construisent la dimension 1 (l’axe époux contre épouse), tandis que Holidays et Repairs construisent la dimension 2. En d’autres termes : la dimension 1 est l’opposition de Repairs/Driving (un pôle) à Laundry/Main_meal (l’ autre).

Les contributions numériques le confirment (valeurs en %, sommant à 100 par dimension) :

library(FactoMineR)
library(factoextra)
data(housetasks)
res.ca <- CA(housetasks, graph = FALSE)

row <- get_ca_row(res.ca)
round(head(row$contrib), 2)
           Dim 1 Dim 2 Dim 3
Laundry    18.29  5.56  7.97
Main_meal  12.39  4.74  1.86
Dinner      5.47  1.32  2.10
Breakfeast  3.82  3.70  3.07
Tidying     2.00  2.97  0.49
Dishes      0.43  2.84  3.63

L’autre angle est le cos2 — la qualité avec laquelle chaque ligne est représentée dans le plan en 2-D (1 = parfaitement). Un diagramme en barres du cos2 sur les deux premières dimensions signale toute catégorie à lire avec prudence :

library(FactoMineR)
library(factoextra)
data(housetasks)
res.ca <- CA(housetasks, graph = FALSE)

fviz_cos2(res.ca, choice = "row", axes = 1:2)

Bar plot of the cos2 (quality of representation) of the housetasks rows on dimensions 1 and 2; all rows are well represented except Official, whose bar is short.

Chaque tâche est bien représentée sur les deux premières dimensions sauf Official, dont le cos2 est faible — sa position sur la carte exige une troisième dimension pour être fiable, alors interprétez-la avec prudence.

Colonnes : où se situe chaque arrangement

Les colonnes fonctionnent de la même façon. Tracez-les colorées par cos2 pour voir avec quelle qualité chaque arrangement est capté par le plan en 2-D :

library(FactoMineR)
library(factoextra)
data(housetasks)
res.ca <- CA(housetasks, graph = FALSE)

fviz_ca_col(res.ca, col.col = "cos2",
            gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
            repel = TRUE)

CA factor map of the four housetasks columns (Wife, Alternating, Husband, Jointly) coloured by cos2; Wife, Husband and Jointly are well represented, Alternating less so.

Wife, Husband et Jointly sont bien représentés et se situent à des pôles nets ; seul Alternating a un cos2 plus faible, si bien que sa position exacte est moins certaine. Les contributions des colonnes racontent la même histoire :

library(FactoMineR)
library(factoextra)
data(housetasks)
res.ca <- CA(housetasks, graph = FALSE)

fviz_contrib(res.ca, choice = "col", axes = 1:2)

Bar plot of the contribution of the four housetasks columns to dimensions 1 and 2 combined, with a dashed line marking the expected average contribution.

La ligne pointillée marque la contribution attendue si chaque colonne comptait également ; les barres au-dessus (Wife, Husband, Jointly) sont les colonnes qui façonnent réellement la carte.

Mettre le tout ensemble

L’AFC nous a donné une lecture complète et interprétable d’un tableau de contingence 13×4 :

  • Le test du khi-deux a confirmé une association forte et significative (qui vaut la peine d’être analysée).
  • Les valeurs propres ont montré qu’un plan en 2-D conserve 88.6% de l’inertie — une excellente réduction.
  • Le biplot a révélé la structure : un axe épouse-contre-époux (dimension 1) et un axe conjointement-contre-le-reste (dimension 2), chaque tâche se situant près de l’arrangement qui la réalise.
  • La contribution a nommé les catégories qui construisent chaque axe (Repairs, Driving, Laundry, Main_meal, Holidays) ; le cos2 a signalé l’unique ligne (Official) et l’unique colonne (Alternating) à lire avec prudence.

Voilà tout le flux de travail de l’AFC — tester, calculer, éboulis, biplot, diagnostiquer — et il passe à l’échelle de tableaux de contingence bien trop grands pour être lus à l’œil.

Essayez en direct

Éditez et exécutez le code ci-dessous dans votre navigateur — aucune installation nécessaire. Essayez de passer à un biplot asymétrique (map = "rowprincipal") pour rendre les distances ligne-colonne interprétables, ou colorez les lignes par "cos2" au lieu de "contrib".

🟢 Avec un agent IA

Vous avez votre propre tableau croisé ? Demandez à Prova « y a-t-il une association dans mon tableau de contingence, et comment lire le biplot d’AFC ? » — elle répond avec du code R que vous pouvez exécuter sur votre propre tableau, vérifie d’abord le khi-deux, puis vous aide à interpréter les dimensions et les contributions. The runtime is the judge. Demander à Prova →

Problèmes courants

  • « all(dim(x) > 1) is not TRUE » ou une carte absurde. Vous avez passé des données brutes, pas un tableau de contingence. L’AFC a besoin d’un tableau croisé de décomptes. Construisez-en un d’abord : tab <- table(df$var1, df$var2), puis CA(tab). Un tableau de données avec une ligne par observation n’est pas un tableau de contingence.
  • Vous lisez la distance d’une ligne à une colonne sur le biplot symétrique. Cette distance n’est pas directement interprétable sur une carte symétrique — seules les distances ligne-à-ligne et colonne-à-colonne le sont. Pour une comparaison ligne-colonne fidèle, passez à un biplot asymétrique (fviz_ca_biplot(res.ca, map = "rowprincipal", arrow = c(TRUE, TRUE))) et projetez la ligne sur la flèche de la colonne.
  • Vous avez plus de deux variables catégorielles. L’AFC simple traite exactement deux variables (un seul tableau de contingence). Pour trois variables catégorielles ou plus, utilisez l’analyse des correspondances multiples (ACM), qui généralise l’AFC à tout un ensemble de variables catégorielles.
  • Une catégorie se situe loin à l’écart et écrase tout le reste. C’est une valeur aberrante avec une coordonnée et une contribution élevées. Elle peut dominer un axe ; envisagez de relancer l’AFC en la traitant comme un point supplémentaire (CA(x, row.sup = ...)) afin qu’elle soit projetée sur la carte sans la définir.

Questions fréquentes

L’analyse des correspondances (AFC) résume et visualise l’association entre deux variables catégorielles à partir de leur tableau de contingence. Elle place les catégories en ligne et les catégories en colonne sur une carte de faible dimension partagée, de sorte que les catégories qui apparaissent ensemble se retrouvent proches l’une de l’autre — ce qui vous laisse lire la structure d’un grand tableau croisé d’un coup d’œil. C’est la contrepartie de l’ACP pour les données catégorielles.

Construisez (ou fournissez) un tableau de contingence de décomptes, puis appelez CA() de FactoMineR et visualisez avec factoextra : res.ca <- CA(housetasks, graph = FALSE), puis fviz_ca_biplot(res.ca, repel = TRUE) pour la carte et get_eigenvalue(res.ca) / fviz_eig(res.ca) pour les dimensions. Testez d’abord le tableau avec chisq.test() pour confirmer qu’il y a une association à analyser.

L’ACP travaille sur des variables numériques continues et décompose leur variance ; l’AFC travaille sur un tableau de contingence de deux variables catégorielles et décompose leur inertie (\(\phi^2 = \chi^2/n\), un khi-deux remis à l’échelle). Toutes deux projettent les données sur quelques dimensions interprétables et utilisent les mêmes fonctions de tracé factoextra — l’AFC est essentiellement l’ACP adaptée aux données catégorielles.

Sur le biplot symétrique standard, des points-lignes proches partagent un profil, et de même pour des points-colonnes proches. Les catégories proches d’un pôle-colonne donné lui sont associées. Surtout, la distance entre un point-ligne et un point-colonne n’est pas directement signifiante sur une carte symétrique — lisez-la seulement comme un motif régional général. Utilisez la contribution et le cos2 de chaque point pour voir quelles catégories définissent les axes et lesquelles sont bien représentées.

Utilisez l’AFC simple lorsque vous avez exactement deux variables catégorielles (un seul tableau de contingence). Lorsque vous avez trois variables catégorielles ou plus — par exemple plusieurs questions d’enquête — utilisez l’analyse des correspondances multiples (ACM), qui généralise l’AFC à tout un ensemble de variables catégorielles.

Testez vos connaissances

Réalisez une analyse des correspondances sur le tableau de contingence intégré caith de MASS — un croisement de la couleur des yeux (lignes) et de la couleur des cheveux (colonnes) issu d’une étude menée à Caithness, en Écosse. Chargez-le, exécutez CA(), affichez les valeurs propres et tracez le biplot. Quelles catégories se situent aux pôles opposés de la dimension 1 ?

caith est déjà un tableau de contingence, alors passez-le directement à CA(). Utilisez get_eigenvalue(res.ca) pour les dimensions et fviz_ca_biplot(res.ca, repel = TRUE) pour la carte.

library(FactoMineR)
library(factoextra)
library(MASS)

data(caith)
res.ca <- CA(caith, graph = FALSE)

get_eigenvalue(res.ca)
fviz_ca_biplot(res.ca, repel = TRUE)

La dimension 1 sépare les yeux clairs avec cheveux blonds/roux à un pôle des yeux foncés avec cheveux foncés/noirs à l’autre — le gradient de coloration classique, capté par la première dimension de l’AFC.

Vérification rapide. Un collègue calcule une AFC et lit sur le biplot que « la catégorie en ligne A est associée à la catégorie en colonne B parce que leurs points sont proches ». Pourquoi devriez-vous être prudent, et quel graphique rendrait cette comparaison valide ?

Sur un biplot symétrique, la distance ligne-colonne n’est pas directement interprétable — seules les distances ligne-à-ligne et colonne-à-colonne le sont. Pour comparer une ligne précise à une colonne précise, dessinez un biplot asymétrique (fviz_ca_biplot(res.ca, map = "rowprincipal", arrow = c(TRUE, TRUE))) et projetez perpendiculairement le point-ligne sur la flèche de la colonne.

Conclusion

Vous avez testé un tableau de contingence pour l’association avec le khi-deux, exécuté CA() de FactoMineR, lu les valeurs propres et l’éboulis pour conserver deux dimensions (88.6% de l’inertie), et interprété le biplot symétrique — en utilisant la contribution et le cos2 pour nommer les catégories qui définissent chaque axe et signaler celles à lire avec soin. L’AFC est la méthode de référence pour deux variables catégorielles ; quand vous en avez plusieurs, poursuivez avec l’analyse des correspondances multiples (ACM), et pour des données continues, voir l’ACP.

Leçons connexes

Vous préférez un livre ? Principal Component Methods in R est disponible en PDF téléchargeable — toutes les leçons de cette série, hors ligne et à vous.

Obtenir le livre (PDF) →Les leçons restent gratuites en ligne.
Cette page vous a-t-elle été utile ?

Prouvez que vous savez le faire. Maîtrisez toute la série Réduction de dimension en R — suivez votre parcours, construisez des projets et obtenez un certificat.

Commencer gratuitement →

Passez à Pro — Prova illimité sur vos propres données et un certificat vérifiable qui atteste la compétence.

dès 15 $/mois facturé annuellement

Passer à Pro →

✓ Vous êtes Pro — continuez. The runtime is the judge.

Recevez les nouvelles leçons R & Python par e-mail

Pratique, reproductible, sans spam. Désinscription à tout moment.

Double opt-in. Nous ne partageons jamais votre e-mail.

Partager cette pageXLinkedInRedditHN
Note

Cette leçon est reproductible : chaque figure a été produite par le code montré — éditez n’importe quel bloc et exécutez-le, et le bac à sable + le quiz se réexécutent en direct dans votre navigateur. The runtime is the judge.

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {Analyse des correspondances (AFC) en R avec FactoMineR},
  date = {2026-06-24},
  url = {https://www.datanovia.com/learn/machine-learning/dimension-reduction/correspondence-analysis},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“Analyse des correspondances (AFC) en R avec FactoMineR.” 2026. June 24. https://www.datanovia.com/learn/machine-learning/dimension-reduction/correspondence-analysis.