Faire une ACP avec R : le décathlon
ACP guidée · R Lab — Antoine Géré
Le décathlon réunit dix épreuves d'athlétisme disputées sur deux jours : courses (100 m, 400 m, 110 m haies, 1500 m), sauts (longueur, hauteur, perche) et lancers (poids, disque, javelot). Chaque performance est convertie en points par un barème, et le classement se fait sur le total des points. Un entraîneur se demande quelles épreuves « vont ensemble », quelles qualités font gagner, et quels profils d'athlètes on rencontre.
Le fichier decathlon.txt (données du package FactoMineR) contient les performances de 41 athlètes lors de deux compétitions de 2004 : le Décastar de Talence et les Jeux olympiques d'Athènes. Chaque ligne correspond à un athlète ; le nom de l'athlète sert de nom de ligne. Les colonnes sont :
| Colonne | Signification | Colonne | Signification |
|---|---|---|---|
100m | 100 m (s) | Pole.vault | saut à la perche (m) |
Long.jump | saut en longueur (m) | Javeline | lancer du javelot (m) |
Shot.put | lancer du poids (m) | 1500m | 1500 m (s) |
High.jump | saut en hauteur (m) | Rank | classement dans la compétition |
400m | 400 m (s) | Points | total des points |
110m.hurdle | 110 m haies (s) | Competition | Decastar ou OlympicG |
Discus | lancer du disque (m) |
- Chaque question donne le code R à taper dans un script (à enregistrer dans votre dossier OneDrive :
STAT_Nom_Prenom), pas dans la console. Pour exécuter une ligne, placer le curseur dessus et taperCtrl + Entrée. - Après chaque bloc : exécuter, comparer la sortie aux lignes ✓ Contrôle, lire les encadrés Lecture, puis répondre.
- Tout ce qui suit le signe
#est un commentaire : R l'ignore.
Aperçu de l'ACP
Les deux sorties centrales de l'analyse : le cercle des corrélations (les épreuves) et la carte des individus (les 41 performances).
Exercice guidé — les performances de 41 décathloniens
- Préparer la séance.
- Dans votre dossier de travail OneDrive, placer
decathlon.txt(encadré « Récupérer les données » ci-dessus) dansdata_raw. Lancer RStudio à partir du fichier_stat_Istom.Rproj. - Installer les packages
FactoMineR,factoextraetcorrplot, puis les charger (à chaque séance) :library(FactoMineR) # pour l'ACP library(factoextra) # pour les graphiques de l'ACP (fonctions fviz_...) library(corrplot) # pour la matrice des correlations en couleurs - Importer les données :
deca <- read.table("data_raw/decathlon.txt", header = TRUE, sep = "\t") deca$Competition <- as.factor(deca$Competition) # variable qualitative (facteur) str(deca) # structure du tableau head(deca) # les 6 premieres lignesLectureheader = TRUE: la première ligne contient les noms de colonnes ;sep = "\t": colonnes séparées par des tabulations. La ligne d'en-tête ayant une colonne de moins que les lignes de données, R comprend que la première colonne (le nom de l'athlète) donne les noms de lignes.✓R a renomméContrôlestraffiche41 obs. of 13 variables; les douze premières colonnes sont numériques (num/int) etCompetitionest unFactor w/ 2 levels.100menX100m: pourquoi, à votre avis ? Quels sont les numéros de colonne deRank,PointsetCompetition? Combien d'individus et de variables compte le tableau ?
- Dans votre dossier de travail OneDrive, placer
- Les valeurs manquantes.
En pratique, il y a presque toujours des valeurs manquantes ; il faut les repérer avant toute analyse.
colSums(is.na(deca)) # nombre de valeurs manquantes par colonne mean(is.na(deca)) # proportion de cases manquantes dans tout le tableauLectureLe tableau contient-il des valeurs manquantes ? Pourquoi est-ce important pour l'ACP ?is.na(deca)remplace chaque case parTRUEsi elle est manquante ;colSumscompte lesTRUEde chaque colonne. Pour une vue graphique, le packageVIMproposeaggr(deca, numbers = TRUE, sortVars = TRUE). - Décrire les données avant l'ACP.
- Afficher un résumé de chaque variable et les écarts-types des dix épreuves :
summary(deca) round(apply(deca[, 1:10], 2, sd), 2) # ecart-type de chacune des colonnes 1 a 10✓Les épreuves ont-elles la même unité ? Pour quelles épreuves une petite valeur correspond-elle à une bonne performance ?Contrôlela moyenne deX100mvaut \(10{,}998\) s et celle deX1500m\(279{,}0\) s. - Tracer l'histogramme et la boîte à moustaches de chaque épreuve :
par(mfrow = c(2, 5)) # 10 graphiques sur 2 lignes et 5 colonnes for (v in names(deca)[1:10]) hist(deca[[v]], main = v, xlab = "", col = "steelblue") for (v in names(deca)[1:10]) boxplot(deca[[v]], main = v, col = "skyblue") par(mfrow = c(1, 1)) # retour a un seul graphique par fenetreLectureLes distributions sont-elles à peu près symétriques ? Repérer les valeurs isolées, puis retrouver les athlètes correspondants :La boucle
forrépète la commande pour chacun des dix noms de colonnes ;deca[[v]]extrait la colonne dont le nom est dansv. Sur une boîte à moustaches, les points isolés sont les valeurs à plus de \(1{,}5\) fois l'écart interquartile de la boîte.S'agit-il d'erreurs de saisie ? Faut-il retirer ces athlètes ?deca[deca$X1500m > 310, ] # qui a couru le 1500 m en plus de 310 s ? - Décrire la variable
Competition:Les deux compétitions sont-elles également représentées ? Affichertable(deca$Competition) round(prop.table(table(deca$Competition)), 3) barplot(prop.table(table(deca$Competition)), col = c("orange", "steelblue"))rownames(deca): que remarque-t-on sur l'écriture des noms ? Certains athlètes apparaissent-ils deux fois ?
- Afficher un résumé de chaque variable et les écarts-types des dix épreuves :
- Les corrélations entre épreuves.
On représente la matrice des corrélations des dix épreuves (coefficients en %) :
Matrice.Correlation <- cor(deca[, 1:10]) corrplot(Matrice.Correlation, method = "color", type = "upper", order = "hclust", tl.col = "black", tl.srt = 45, addCoef.col = "black", addCoefasPercent = TRUE, number.cex = 0.8)Lectureorder = "hclust"réordonne les variables pour rapprocher celles qui sont corrélées : des blocs de couleur apparaissent le long de la diagonale.✓Contrôle\(r(\texttt{X100m},\texttt{X110m.hurdle}) \approx 0{,}58\) et \(r(\texttt{Shot.put},\texttt{Discus}) \approx 0{,}62\).- Quels groupes d'épreuves sont corrélés entre eux ? Ces liaisons vous semblent-elles logiques pour un athlète ?
- La corrélation entre
X100metLong.jumpvaut \(-0{,}60\). Les bons sprinteurs sautent-ils donc moins loin ? Expliquer le signe. - Quelles épreuves sont peu corrélées à toutes les autres ? Qu'en attendre pour l'ACP ?
- Centrer et réduire les données.
data.CR <- scale(deca[, 1:10], center = TRUE, scale = TRUE) round(head(data.CR, 3), 2)- Vérifier à la main le coefficient de
SEBRLEpour le 100 m, à l'aide de la moyenne et de l'écart-type de la question 3. Que signifie une valeur positive pour une épreuve chronométrée ? - Pourquoi faut-il faire une ACP normée ? Calculer la part de la variance totale due au 1500 m sans réduction (
v <- apply(deca[, 1:10], 2, var)puisround(100 * v / sum(v), 1)).
- Vérifier à la main le coefficient de
- Lancer l'ACP.
- On construit les axes avec les dix épreuves seulement, et l'on garde le classement, les points et la compétition pour interpréter :
Expliquer le rôle de
res <- PCA(deca, scale.unit = TRUE, quanti.sup = 11:12, quali.sup = 13, graph = FALSE) names(res)scale.unit = TRUE,quanti.sup = 11:12,quali.sup = 13etgraph = FALSE. - Pourquoi
PointsetRankdoivent-ils être des variables supplémentaires et non actives ? - On n'a pas donné
data.CRà la fonctionPCA. Est-ce un problème ?
- On construit les axes avec les dix épreuves seulement, et l'on garde le classement, les points et la compétition pour interpréter :
- Combien d'axes faut-il regarder ?
Rappels
En ACP normée, chacune des \(K\) variables actives a une variance égale à 1 : l'inertie totale vaut \(K\). Le critère de Kaiser retient les axes tels que \(\lambda_s \ge 1\) (ici, avec \(K=10\), au moins \(10\,\%\) de l'inertie). Le critère du coude retient les axes situés avant la cassure de l'éboulis.
round(res$eig, 2) fviz_eig(res, addlabels = TRUE) # eboulis des valeurs propres (en %)✓Contrôle\(\lambda_1 \approx 3{,}27\) et \(\lambda_2 \approx 1{,}74\).- Que vaut la somme des valeurs propres (
sum(res$eig[, 1])) ? Pourquoi ? - Quel pourcentage d'inertie le plan \((1,2)\) restitue-t-il ? Est-il élevé ? Le relier aux corrélations de la question 4.
- Combien d'axes retenez-vous selon le critère de Kaiser ? selon le critère du coude ?
- Que vaut la somme des valeurs propres (
- Le cercle des corrélations : interpréter les axes.
Rappels
Une flèche longue (proche du cercle) est bien représentée ; une flèche courte ne s'interprète pas. Pour deux flèches bien représentées : angle proche de \(0^\circ\) → forte corrélation positive ; proche de \(90^\circ\) → absence de corrélation ; proche de \(180^\circ\) → forte corrélation négative.
- Tracer le cercle colorié selon la qualité de représentation, et afficher les résultats des variables :
fviz_pca_var(res, col.var = "cos2", repel = TRUE, gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07")) round(res$var$coord[, 1:3], 2) # coordonnees = correlations avec les axes round(res$var$cos2[, 1:3], 2) # qualite de representation round(res$var$contrib[, 1:3], 1) # contributions (en %)LectureLe \(\cos^2\) d'une variable sur le plan vaut \(\cos^2_1+\cos^2_2\) : le carré de la longueur de sa flèche. La contribution à l'axe \(s\) vaut \(100\times r^2(X_k,F_s)/\lambda_s\). La contribution moyenne vaut \(100/10 = 10\,\%\).
- Afficher les contributions des variables aux deux premiers axes :
fviz_contrib(res, choice = "var", axes = 1) # contributions a l'axe 1 fviz_contrib(res, choice = "var", axes = 2) # contributions a l'axe 2 fviz_cos2(res, choice = "var", axes = 1:2) # qualite sur le plan (1,2)LectureLes barres sont triées par ordre décroissant ; la ligne rouge pointillée indique la contribution moyenne (\(10\,\%\)).
- Axe 1. Quelles épreuves lui sont fortement corrélées ? Dans quel sens ? Attention au sens des épreuves chronométrées ! Proposer un nom pour cet axe.
- Axe 2. Mêmes questions.
- Quelles épreuves sont mal représentées sur le plan \((1,2)\) ? Sur quel axe se trouve leur information ?
- Faire le lien avec le cours. Pour
X100m, vérifier que \(\cos^2_1 = r^2(\texttt{X100m},F_1)\) et \(\operatorname{contrib}_1 = 100\times r^2(\texttt{X100m},F_1)/\lambda_1\). - Le cercle confirme-t-il les groupes d'épreuves de la question 4a ? Quels conseils d'entraînement en tirer pour un décathlonien ?
- Tracer le cercle colorié selon la qualité de représentation, et afficher les résultats des variables :
- La carte des athlètes.
- Tracer la carte coloriée selon la qualité de représentation, et afficher les résultats :
fviz_pca_ind(res, col.ind = "cos2", repel = TRUE) + scale_color_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0.5) round(res$ind$coord[, 1:2], 2) # coordonnees F1, F2 round(rowSums(res$ind$cos2[, 1:2]), 2) # qualite sur le plan (1,2) round(sort(res$ind$contrib[, 1], decreasing = TRUE)[1:5], 1) # 5 plus fortes contrib. axe 1 round(sort(res$ind$contrib[, 2], decreasing = TRUE)[1:5], 1) # idem pour l'axe 2✓ContrôleKarpov a la plus forte coordonnée sur l'axe 1 : \(F_1 \approx 4{,}62\). - Quels athlètes ont les meilleurs profils d'ensemble ? les moins bons ? Quels athlètes contribuent le plus aux axes 1 et 2 (comparer à la contribution moyenne \(100/41 \approx 2{,}4\,\%\)) ?
- Quel athlète est le plus mal représenté sur le plan ? Peut-on dire qu'il est « moyen dans toutes les épreuves » ?
- Retour aux données brutes. Afficher les performances de trois athlètes à trois coins différents de la carte :
Leurs performances sont-elles cohérentes avec les noms donnés aux axes ?
deca[c("Karpov", "Casarsa", "Drews"), 1:10] - Tracer le biplot des athlètes et des variables bien représentés :
Quel lien fait-on entre la position d'un athlète et la direction des flèches ?
fviz_pca_biplot(res, select.ind = list(cos2 = 0.5), select.var = list(cos2 = 0.5), repel = TRUE, col.ind = "blue", col.var = "red")
- Tracer la carte coloriée selon la qualité de représentation, et afficher les résultats :
- Les variables supplémentaires.
Rappel
Une variable supplémentaire n'intervient pas dans le calcul des axes : elle est projetée après coup. Quantitative, elle se lit sur le cercle ; qualitative, ses modalités se lisent sur la carte des individus (barycentres).
- Afficher la corrélation des points et du classement avec les axes :
Que confirme la position de
round(res$quanti.sup$coord[, 1:2], 2) round(res$quanti.sup$cos2[, 1:2], 2)Pointssur le cercle ? PourquoiRankest-il nettement moins corrélé à l'axe 1 quePoints? - Tracer la carte coloriée selon la compétition, et afficher les barycentres et leurs valeurs-test :
fviz_pca_ind(res, habillage = 13, addEllipses = TRUE, ellipse.level = 0.68, repel = TRUE) round(res$quali.sup$coord[, 1:2], 2) round(res$quali.sup$v.test[, 1:2], 2)LectureLes athlètes des Jeux olympiques ont-ils significativement de meilleurs profils que ceux du Décastar ?La valeur-test mesure si les athlètes d'une compétition ont, sur un axe, une position moyenne significativement différente de 0 : lien significatif (seuil 5 %) si \(|\texttt{v.test}| > 1{,}96\), soit environ 2.
- Neuf athlètes ont participé aux deux compétitions (ex.
SEBRLEau Décastar etSebrleaux Jeux olympiques) :Comment leur position évolue-t-elle entre les deux compétitions ? Cela nuance-t-il la conclusion précédente ?deca[c("SEBRLE", "Sebrle", "NOOL", "Nool"), ] res$ind$coord[c("SEBRLE", "Sebrle", "NOOL", "Nool"), 1:2] - Obtenir la description automatique des axes :
dimdesc(res, axes = 1:2, proba = 0.05)LectureQuelles variables décrivent le mieux chaque axe ? Pourquoi la compétition n'apparaît-elle pas ?Pour chaque axe,
$quantiliste les variables (actives ou supplémentaires) significativement corrélées, de la plus positive à la plus négative ;$qualiet$categoryn'apparaissent que si une variable qualitative est significativement liée à l'axe.
- Afficher la corrélation des points et du classement avec les axes :
- Synthèse. Rédiger, pour l'entraîneur, une synthèse de l'ACP en une dizaine de lignes : les groupes d'épreuves, les deux grandes dimensions du décathlon, ce qui fait gagner, les profils d'athlètes remarquables et des pistes d'entraînement. Préciser les limites de l'analyse.
Indications
- Si
read.tablene trouve pas le fichier, vérifier qu'il est bien dansdata_raw, que RStudio a été lancé depuis le.Rproj(getwd()) et que le chemin s'écrit avec/. En R, un nom de variable ne peut pas commencer par un chiffre. - Pour l'ACP, chaque individu doit avoir une valeur pour chaque variable active.
- Un temps court est une bonne performance ; une distance ou une hauteur grande aussi. Les noms en majuscules correspondent à l'une des deux compétitions.
- Comparer les corrélations entre épreuves de course, entre lancers, et entre courses et sauts. Penser au sens des performances avant d'interpréter un signe.
- Une valeur centrée réduite vaut \((x-\overline{x})/s\). Le 1500 m varie d'une trentaine de secondes d'un athlète à l'autre.
- Le total des points est calculé à partir des dix performances.
PCAcentre et réduit elle-même les variables actives quandscale.unit = TRUE. - L'inertie totale d'une ACP normée vaut le nombre de variables actives.
- Pour une épreuve chronométrée, une flèche dirigée vers la gauche signifie que les athlètes situés à droite ont des temps courts. La qualité d'une variable sur le plan est la somme de ses \(\cos^2\) sur les axes 1 et 2.
- La contribution moyenne d'un athlète vaut \(100/41\). Un athlète mal représenté peut être éloigné du centre dans d'autres dimensions.
- Le classement est calculé séparément dans chaque compétition. Pour comparer les deux compétitions, regarder la valeur absolue de la valeur-test.
Mise en forme par Antoine Géré.