Dans le précédent document, nous avons introduit des outils utiles pour nettoyer une base de données, et visualiser directement une ou plusieurs de ses variables d'interêt. A présent, il est possible de faire usage de méthodes plus élaborées d'analyses de données, faisant appel à des notions d'algèbre linéaire, comme l'anayse en composante principale (ACP) ou l'analyse factorielle des correspondances (AFC). En termes pratiques, le package FactoMineR fournit un ensemble très complet d'implémentations de ces méthodes et d'autres.
Dans cet exercice, nous utilisons une base de données classique, nommée swiss, présente par défaut dans la version de base de R. Bien qu'il soit possible de l'utiliser telle quelle, on remarque que ce dataframe n'est pas au format tidy tel que définit dans le tidyverse : https://cran.r-project.org/web/packages/tidyr/vignettes/tidy-data.html . En effet, chaque ligne a un nom, et celui-ci devrait constituer plutôt une colonne du tableau. Ainsi, comme précédemment introduit, nous allons importer la base de données brute, puis créer une copie que l'on va mettre sous une forme correcte.
library(tidyverse)
library(gridExtra)
library(FactoMineR)
raw_db = swiss
db = raw_db %>% rownames_to_column(var = 'Province') %>% as_tibble
db
## # A tibble: 47 x 7
## Province Fertility Agriculture Examination Education Catholic
## <chr> <dbl> <dbl> <int> <int> <dbl>
## 1 Courtel~ 80.2 17 15 12 9.96
## 2 Delemont 83.1 45.1 6 9 84.8
## 3 Franche~ 92.5 39.7 5 5 93.4
## 4 Moutier 85.8 36.5 12 7 33.8
## 5 Neuvevi~ 76.9 43.5 17 15 5.16
## 6 Porrent~ 76.1 35.3 9 7 90.6
## 7 Broye 83.8 70.2 16 7 92.8
## 8 Glane 92.4 67.8 14 8 97.2
## 9 Gruyere 82.4 53.3 12 7 97.7
## 10 Sarine 82.9 45.2 16 13 91.4
## # ... with 37 more rows, and 1 more variable: Infant.Mortality <dbl>
Pour nous familiariser avec les données, nous pouvons utiliser quelques indicateurs et graphs descriptifs dans un premier temps.
summary(db)
## Province Fertility Agriculture Examination
## Length:47 Min. :35.00 Min. : 1.20 Min. : 3.00
## Class :character 1st Qu.:64.70 1st Qu.:35.90 1st Qu.:12.00
## Mode :character Median :70.40 Median :54.10 Median :16.00
## Mean :70.14 Mean :50.66 Mean :16.49
## 3rd Qu.:78.45 3rd Qu.:67.65 3rd Qu.:22.00
## Max. :92.50 Max. :89.70 Max. :37.00
## Education Catholic Infant.Mortality
## Min. : 1.00 Min. : 2.150 Min. :10.80
## 1st Qu.: 6.00 1st Qu.: 5.195 1st Qu.:18.15
## Median : 8.00 Median : 15.140 Median :20.00
## Mean :10.98 Mean : 41.144 Mean :19.94
## 3rd Qu.:12.00 3rd Qu.: 93.125 3rd Qu.:21.70
## Max. :53.00 Max. :100.000 Max. :26.60
gg1 = ggplot(db) + geom_boxplot(aes(y = Fertility))
gg2 = ggplot(db) + geom_boxplot(aes(y = Agriculture))
gg3 = ggplot(db) + geom_boxplot(aes(y = Examination))
gg4 = ggplot(db) + geom_boxplot(aes(y = Education))
gg5 = ggplot(db) + geom_boxplot(aes(y = Catholic))
gg6 = ggplot(db) + geom_boxplot(aes(y = Infant.Mortality))
grid.arrange(gg1, gg2, gg3, gg4, gg5, gg6, ncol = 3, nrow = 2)
Lorsque nous souhaitons afficher comme ceci le même type de graph pour un grand nombre de variable, il peut être plus pratique d'utiliser la fonction gather() du tidyverse. Cette fonction regroupe toutes les variables en un tibble avec seulement deux colonnes key et value, qui associé à l'argument facet_wrap, permet l'affichage de multiples graphs.
db %>% select_if(is.numeric) %>%
gather() %>%
ggplot(aes(x = value)) + facet_wrap(~ key) + geom_histogram()
Utilisons maintenant la fonction PCA() du package FactoMineR pour réaliser une analyse en composantes principales. Nous choisissons un nombre de composantes égal à 6 (le nombre de variables est le maximum). Par défaut, la fonction affiche la projection des individus et des variables dans le plan factoriel défini par les deux premières composantes.
swiss.acp = PCA(swiss, ncp = 6)
summary(swiss.acp)
##
## Call:
## PCA(X = swiss, ncp = 6)
##
##
## Eigenvalues
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5 Dim.6
## Variance 3.200 1.188 0.848 0.439 0.205 0.121
## % of var. 53.329 19.805 14.127 7.315 3.409 2.014
## Cumulative % of var. 53.329 73.134 87.261 94.577 97.986 100.000
##
## Individuals (the 10 first)
## Dist Dim.1 ctr cos2 Dim.2 ctr cos2
## Courtelary | 2.034 | -0.364 0.088 0.032 | 1.399 3.506 0.473 |
## Delemont | 2.169 | 1.634 1.776 0.568 | 1.026 1.885 0.224 |
## Franches-Mnt | 2.764 | 2.104 2.944 0.580 | 0.746 0.997 0.073 |
## Moutier | 1.596 | 0.748 0.372 0.219 | 0.596 0.636 0.139 |
## Neuveville | 1.182 | -0.382 0.097 0.104 | 0.449 0.361 0.144 |
## Porrentruy | 2.924 | 1.369 1.247 0.219 | 2.292 9.405 0.614 |
## Broye | 2.310 | 1.724 1.977 0.557 | 1.128 2.277 0.238 |
## Glane | 2.971 | 2.183 3.167 0.540 | 1.764 5.572 0.353 |
## Gruyere | 1.873 | 1.518 1.532 0.657 | 0.623 0.694 0.110 |
## Sarine | 2.247 | 0.962 0.615 0.183 | 1.895 6.431 0.711 |
## Dim.3 ctr cos2
## Courtelary -0.860 1.855 0.179 |
## Delemont 0.548 0.753 0.064 |
## Franches-Mnt 0.473 0.561 0.029 |
## Moutier -0.579 0.842 0.132 |
## Neuveville -0.628 0.991 0.283 |
## Porrentruy 0.351 0.308 0.014 |
## Broye 0.432 0.469 0.035 |
## Glane 0.398 0.398 0.018 |
## Gruyere 0.708 1.258 0.143 |
## Sarine 0.665 1.109 0.088 |
##
## Variables
## Dim.1 ctr cos2 Dim.2 ctr cos2 Dim.3 ctr
## Fertility | 0.817 20.884 0.668 | 0.351 10.370 0.123 | -0.160 3.019
## Agriculture | 0.759 17.996 0.576 | -0.449 16.934 0.201 | 0.035 0.147
## Examination | -0.912 25.983 0.831 | 0.136 1.563 0.019 | -0.084 0.832
## Education | -0.813 20.640 0.660 | 0.195 3.206 0.038 | 0.490 28.344
## Catholic | 0.626 12.258 0.392 | 0.159 2.128 0.025 | 0.743 65.093
## Infant.Mortality | 0.268 2.240 0.072 | 0.884 65.799 0.782 | -0.147 2.563
## cos2
## Fertility 0.026 |
## Agriculture 0.001 |
## Examination 0.007 |
## Education 0.240 |
## Catholic 0.552 |
## Infant.Mortality 0.022 |
Traçons l'ébouli des valeurs propres pour déterminer les composantes pertinentes.
vp = swiss.acp$eig %>% data.frame %>% rownames_to_column(var = 'Composante') %>% as_tibble
gg7 = ggplot(vp) + geom_col(aes(x = Composante, y = eigenvalue)) + ggtitle("Ebouli des valeurs propres")
En utilisant la règle de Kaiser, on peut voir graphiquement que l'on ne retiendrait que deux compostantes principales.
gg7 + geom_hline(aes(yintercept = 1), color = 'red')