L’Analyse en Composante Principale (ACP) et la Classification Ascendante Hiérarchique (CAH) sont deux méthodes de statistiques descriptives souvent utilisées conjointement dans l’étude de gros jeux de données. L’ACP permet de réduire le nombre de dimensions (= colonnes du jeu de données) et la CAH permet de regrouper les unités (= lignes du jeu de données) qui se ressemblent.
De façon plus pratique, elles vont nous permettre de répondre à des questions telles que :
Ce tutoriel est utilisé pour apprendre à faire une ACP suivie d’une CAH sous R. Nous aurons besoin de plusieurs packages :
Avant de commencer, nous allons définir un répertoire de travail.
Cela permettra à R de savoir dans quel dossier de notre PC nous
souhaitons travailler - vous pouvez utiliser l’outil
Session>set working directory>choose directorypour
créer automatiquement le chemin vers votre environnement de travail.
Téléchargez les données au lien suivant : https://www.kaggle.com/datasets/abcsds/pokemon (un compte gratuit est nécessaire) , importez les sous R et décrivez les rapidement. (Nombre de lignes, signification des colonnes, type des variables)
Pokemon <- read.csv("~/UPPA/Cours/NEC/L3/Machine learning/TD_PCA/Pokemon.csv")
knitr::kable(summary(Pokemon))| X. | Name | Type.1 | Type.2 | Total | HP | Attack | Defense | Sp..Atk | Sp..Def | Speed | Generation | Legendary | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Min. : 1.0 | Length:800 | Length:800 | Length:800 | Min. :180.0 | Min. : 1.00 | Min. : 5 | Min. : 5.00 | Min. : 10.00 | Min. : 20.0 | Min. : 5.00 | Min. :1.000 | Length:800 | |
| 1st Qu.:184.8 | Class :character | Class :character | Class :character | 1st Qu.:330.0 | 1st Qu.: 50.00 | 1st Qu.: 55 | 1st Qu.: 50.00 | 1st Qu.: 49.75 | 1st Qu.: 50.0 | 1st Qu.: 45.00 | 1st Qu.:2.000 | Class :character | |
| Median :364.5 | Mode :character | Mode :character | Mode :character | Median :450.0 | Median : 65.00 | Median : 75 | Median : 70.00 | Median : 65.00 | Median : 70.0 | Median : 65.00 | Median :3.000 | Mode :character | |
| Mean :362.8 | NA | NA | NA | Mean :435.1 | Mean : 69.26 | Mean : 79 | Mean : 73.84 | Mean : 72.82 | Mean : 71.9 | Mean : 68.28 | Mean :3.324 | NA | |
| 3rd Qu.:539.2 | NA | NA | NA | 3rd Qu.:515.0 | 3rd Qu.: 80.00 | 3rd Qu.:100 | 3rd Qu.: 90.00 | 3rd Qu.: 95.00 | 3rd Qu.: 90.0 | 3rd Qu.: 90.00 | 3rd Qu.:5.000 | NA | |
| Max. :721.0 | NA | NA | NA | Max. :780.0 | Max. :255.00 | Max. :190 | Max. :230.00 | Max. :194.00 | Max. :230.0 | Max. :180.00 | Max. :6.000 | NA |
Il y a 800 lignes (ou individus), qui représentent chacune un pokémon et ses caractéristiques.
Il y a 13 colonnes, dont un identifiant (variable “X.”) :
Name : le nom du pokémon (Qualitative nominale)
Type 1 : Premier type du pokémon (Qualitative nominale)
Type 2 : Second type du pokémon (Qualitative nominale)
Total : Somme de toutes les stats (Quantitative continue)
HP : Nombre de points de vie (Quantitative Continue)
Attack : Stat attaque (Quantitative Continue)
Defense : Stat defense (Quantitative Continue)
Sp..Atk : Stat attaque speciale (Quantitative Continue)
Sp..Def : Stat defense spéciale (Quantitative Continue)
Speed : Vitesse (Quantitative Continue)
Generation : Numéro de génération (Qualitative ordinale)
Legendary : Si il est ou pas légendaire ? (Qualitative nominale)
Sélectionnez les colonnes sur lesquelles vous allez faire l’ACP (on ne sélectionne que les variables quantitatives)
data_pca <- Pokemon %>% select(Total, HP, Attack, Defense, Speed, Sp..Atk, Sp..Def)%>%
scale()
knitr::kable(summary(data_pca))| Total | HP | Attack | Defense | Speed | Sp..Atk | Sp..Def | |
|---|---|---|---|---|---|---|---|
| Min. :-2.1265 | Min. :-2.6732 | Min. :-2.2800 | Min. :-2.2077 | Min. :-2.1774 | Min. :-1.9198 | Min. :-1.86506 | |
| 1st Qu.:-0.8761 | 1st Qu.:-0.7542 | 1st Qu.:-0.7395 | 1st Qu.:-0.7646 | 1st Qu.:-0.8010 | 1st Qu.:-0.7050 | 1st Qu.:-0.78704 | |
| Median : 0.1242 | Median :-0.1668 | Median :-0.1233 | Median :-0.1232 | Median :-0.1128 | Median :-0.2390 | Median :-0.06836 | |
| Mean : 0.0000 | Mean : 0.0000 | Mean : 0.0000 | Mean : 0.0000 | Mean : 0.0000 | Mean : 0.0000 | Mean : 0.00000 | |
| 3rd Qu.: 0.6660 | 3rd Qu.: 0.4207 | 3rd Qu.: 0.6470 | 3rd Qu.: 0.5181 | 3rd Qu.: 0.7475 | 3rd Qu.: 0.6778 | 3rd Qu.: 0.65031 | |
| Max. : 2.8750 | Max. : 7.2741 | Max. : 3.4198 | Max. : 5.0077 | Max. : 3.8445 | Max. : 3.7033 | Max. : 5.68105 |
##
## Call:
## PCA(X = data_pca)
##
##
## Eigenvalues
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5 Dim.6 Dim.7
## Variance 3.709 1.094 0.779 0.722 0.429 0.267 0.000
## % of var. 52.992 15.623 11.126 10.316 6.122 3.821 0.000
## Cumulative % of var. 52.992 68.615 79.741 90.057 96.179 100.000 100.000
##
## Individuals (the 10 first)
## Dist Dim.1 ctr cos2 Dim.2 ctr cos2 Dim.3 ctr
## 1 | 2.027 | -1.840 0.114 0.824 | 0.025 0.000 0.000 | -0.665 0.071
## 2 | 0.897 | -0.444 0.007 0.244 | 0.051 0.000 0.003 | -0.669 0.072
## 3 | 1.646 | 1.480 0.074 0.809 | 0.058 0.000 0.001 | -0.628 0.063
## 4 | 3.318 | 3.061 0.316 0.851 | -0.712 0.058 0.046 | -0.999 0.160
## 5 | 2.230 | -2.046 0.141 0.842 | 0.711 0.058 0.102 | -0.408 0.027
## 6 | 1.001 | -0.501 0.008 0.250 | 0.749 0.064 0.560 | -0.405 0.026
## 7 | 1.865 | 1.569 0.083 0.708 | 0.840 0.081 0.203 | -0.449 0.032
## 8 | 3.352 | 3.120 0.328 0.867 | 0.385 0.017 0.013 | 0.127 0.003
## 9 | 3.744 | 3.242 0.354 0.749 | 1.052 0.126 0.079 | -1.163 0.217
## 10 | 2.078 | -1.934 0.126 0.866 | -0.471 0.025 0.051 | -0.570 0.052
## cos2
## 1 0.108 |
## 2 0.556 |
## 3 0.145 |
## 4 0.091 |
## 5 0.033 |
## 6 0.164 |
## 7 0.058 |
## 8 0.001 |
## 9 0.097 |
## 10 0.075 |
##
## Variables
## Dim.1 ctr cos2 Dim.2 ctr cos2 Dim.3 ctr cos2
## Total | 0.999 26.922 0.999 | 0.007 0.005 0.000 | 0.006 0.004 0.000 |
## HP | 0.634 10.845 0.402 | -0.092 0.776 0.008 | 0.412 21.777 0.170 |
## Attack | 0.728 14.294 0.530 | 0.009 0.008 0.000 | 0.524 35.212 0.274 |
## Defense | 0.603 9.806 0.364 | -0.660 39.820 0.435 | -0.061 0.480 0.004 |
## Speed | 0.561 8.473 0.314 | 0.697 44.390 0.485 | -0.070 0.627 0.005 |
## Sp..Atk | 0.751 15.217 0.564 | 0.316 9.116 0.100 | -0.273 9.540 0.074 |
## Sp..Def | 0.732 14.442 0.536 | -0.254 5.886 0.064 | -0.502 32.360 0.252 |
La dimension 1 explique plus de 52% de la variabilité du jeu de données, les variables qui contribuent le plus à sa construction sont Attack et Total. La dimension 2 explique 15 % de variabilité, les variables qui contribuent le plus à sa construction sont Speed (vers le positif) et Defense (vers le négatif).
Le premier graphique nous permet de connaître le pourcentage cumulé de variance expliquée par les différents axes. Ici, avec 3 axes factoriels, 80% de la variance du jeu de donnée est expliqué. On voit ensuite l’importance de chaque variable dans la construction des axes factoriels.
fviz_pca_var(res.pca, col.var = "cos2",
axes = c(1, 2),
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE # Évite le chevauchement de texte
) Quelles sont les variables qui contribuent le plus à la construction des axes ?
La variable “Total” est celle qui contribue le plus à l’axe 1, les variables “Defense” et “Speed” sont celles qui contribuent le plus à la formation de l’axe 2.
fviz_pca_ind(res.pca, col.ind = "cos2",
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
repel = TRUE, # Évite le chevauchement de texte
label = "none"
)On peut faire un graphique des lignes et des colonnes ensemble: le biplot.
La fonction biplot permet aussi de colorer les individus en fonction d’une variable qualitative (codée en facteur). Voici l’exemple avec la variable “géneration”.
fviz_pca_biplot(res.pca, label="var", habillage=as.factor(Pokemon$Generation),
addEllipses=TRUE, ellipse.level=0.95)La génération du pokémon n’a pas d’influence sur le regoupement des individus. Essayeons d’autres variables :
fviz_pca_biplot(res.pca, label="var", habillage=as.factor(Pokemon$Type.1),
addEllipses=TRUE, ellipse.level=0.95)fviz_pca_biplot(res.pca, label="var", habillage=as.factor(Pokemon$Legendary),
addEllipses=TRUE, ellipse.level=0.95)Cette approche est utile dans les situations où l’on dispose d’un grand ensemble de données contenant des variables continues : l’analyse en composantes principales peut être utilisée pour réduire la dimension des données avant l’analyse de regroupement hiérarchique. Au lieu d’analyser le regroupement de deux variables seulement, nous pouvons analyser le regroupement de l’ensemble des données.
pca2 = PCA(data_pca, ncp = 3, graph = FALSE)
hcpc <- HCPC(pca2, graph = FALSE)
fviz_dend(hcpc, cex = 0.8, palette = "Dark2", rect = T, rect_fill = T, rect_border = "Dark2", show_labels = F) Le graphique 2 produit un regroupement sur le tracé de l’ACP avec les mêmes dimensions que celles discutées précédemment. Il est maintenant clair que nous pouvons distinguer trois groupes distincts de Pokemon. Dans le groupe 1, on trouve des pokémons avec des bonnes stats défensives. Les groupes 2 et 3 contiennent des Pokemon médiocres et faibles en termes de défense et de vitesse (groupes 3 et 2, respectivement).