Avant propos

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.

Exercice 4

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')