Avant propos

La base de données utilisée en fil rouge de ce TP regroupe des informations sur les joueurs de football des 5 grands championnats européens (France, Italie, Allemagne, Espagne, Angleterre), regroupés par club, entre les années 2009 et 2016. L’objectif de cette étude de cas est de mener l’analyse statistique d’une base de données relativement riche en information de bout en bout, depuis le netoyage, la prise en main, jusqu’à l’utilisation de méthodes de visualisation et d’analyse plus sophistiquées (ACP, AFC, Clustering), précédemment vues en cours. Cette étude est prévue pour s’étendre sur une dizaine d’heures en ‘autonomie dirigée’, permettant de balayer au maximum les différentes approches et méthodes par vous même. L’évaluation finale consistera en une analyse (réduite) du même type, d’environ 1h30, sur une autre base de données. De nombreuses approches différentes pouvant être valable, il n’y a pas de réponse universelle et de correction unique de cette analyse, n’hésitez donc pas à essayer des choses et prendre des initiatives, c’est tout l’objectif de ce cours (cela sera valorisé dans l’évaluation). Pour tout de même offrir un support commun rassemblant, pour nos TPs à distance, une trame commune détaillant l’utilisation de quelques commandes, packages, et fonctions importantes, ce document sera mise à jour au fûr et à mesure de vos suggestions. Le notebook sera accessible dans sa version courante sur Moodle.

Comme pour toute étude, la première étape consiste en l’importation des packages et des données. Par convention, nous utiliserons dans la mesure du possible un nom générique pour les données brutes (raw_db), différent du tibble (ou dataframe) de travail (db) sur lequel seront faites les analyses.

library(tidyverse)
library(gridExtra)
library(FactoMineR)
library(factoextra)
# 
raw_db = read_csv("C:/Users/user/Google Drive/Travail/Enseignement/STID/2A/ADD/Codes R/Donnees/DB_Football_2009_2016_classif_4labels.csv")

str(raw_db)
## tibble [21,551 x 21] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ R                           : num [1:21551] 13 1 19 2 3 4 5 6 7 8 ...
##  $ année (début du championnat): num [1:21551] 2016 2016 2016 2016 2016 ...
##  $ Player                      : chr [1:21551] "Loic Badiashile" "Fabinho" "João Moutinho" "Thomas Lemar" ...
##  $ Club                        : chr [1:21551] "Monaco" "Monaco" "Monaco" "Monaco" ...
##  $ âge                         : chr [1:21551] " 19" " 23" " 30" " 21" ...
##  $ Position                    : chr [1:21551] "GK" "D" "M" "F" ...
##  $ Position 2                  : chr [1:21551] NA "DMC" NA NA ...
##  $ Position 3                  : chr [1:21551] NA NA NA NA ...
##  $ CM                          : num [1:21551] 186 188 170 170 184 177 172 190 173 183 ...
##  $ KG                          : num [1:21551] 80 78 61 58 70 72 63 80 64 72 ...
##  $ Apps                        : chr [1:21551] "0(1)" "33(4)" "19(12)" "28(6)" ...
##  $ Mins                        : num [1:21551] 45 3071 1768 2612 91 ...
##  $ Goals                       : num [1:21551] 0 9 2 9 1 21 6 0 8 0 ...
##  $ Assists                     : num [1:21551] 0 1 4 10 0 5 2 0 9 5 ...
##  $ Yel                         : num [1:21551] 0 8 0 1 0 2 1 1 3 0 ...
##  $ Red                         : num [1:21551] 0 0 0 0 0 0 0 0 0 0 ...
##  $ SpG                         : num [1:21551] 0 0.8 0.6 1.7 2 2.8 1.8 1 1.6 0.4 ...
##  $ PS%                         : num [1:21551] 85 84.4 85.2 82.8 76.5 78.9 76.1 67.6 81.1 79.3 ...
##  $ AerialsWon                  : num [1:21551] 0 1.8 0.5 0.3 2 1.4 0.3 1 0.5 2.1 ...
##  $ MotM                        : num [1:21551] 0 2 2 5 1 3 1 0 3 0 ...
##  $ Rating                      : num [1:21551] 7.16 7.51 6.92 7.48 7.42 7.38 7.35 7.31 7.29 7.29 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   R = col_double(),
##   ..   `année (début du championnat)` = col_double(),
##   ..   Player = col_character(),
##   ..   Club = col_character(),
##   ..   âge = col_character(),
##   ..   Position = col_character(),
##   ..   `Position 2` = col_character(),
##   ..   `Position 3` = col_character(),
##   ..   CM = col_double(),
##   ..   KG = col_double(),
##   ..   Apps = col_character(),
##   ..   Mins = col_double(),
##   ..   Goals = col_double(),
##   ..   Assists = col_double(),
##   ..   Yel = col_double(),
##   ..   Red = col_double(),
##   ..   SpG = col_double(),
##   ..   `PS%` = col_double(),
##   ..   AerialsWon = col_double(),
##   ..   MotM = col_double(),
##   ..   Rating = col_double()
##   .. )

Nous pouvons immédiatement remarquer que toutes les variables ont un type cohérent, sauf la variable âge qui est character putôt que numeric. Cette particularité est dûe à un soucis (très classique) de remplissage de la base de données, où un espace invisible s’est glissé avant chaque chiffre dans la colonne des âges. Un premier travail est donc nécessaire pour supprimer cet espace inutile et retransformer les âges en une variable numérique, comme cela est fait ci-dessous. De plus, nous allons aussi prendre la liberté de supprimer la première variable R, qui est tout à fait non informative.

db = raw_db %>%
  select(- R) %>% # Suppress the useless column 'R'
  mutatege = gsub("[[:space:]]", "", âge) %>% as.numeric)  # Remove the spaces 
  

str(db)
## tibble [21,551 x 20] (S3: tbl_df/tbl/data.frame)
##  $ année (début du championnat): num [1:21551] 2016 2016 2016 2016 2016 ...
##  $ Player                      : chr [1:21551] "Loic Badiashile" "Fabinho" "João Moutinho" "Thomas Lemar" ...
##  $ Club                        : chr [1:21551] "Monaco" "Monaco" "Monaco" "Monaco" ...
##  $ âge                         : num [1:21551] 19 23 30 21 21 31 21 24 23 21 ...
##  $ Position                    : chr [1:21551] "GK" "D" "M" "F" ...
##  $ Position 2                  : chr [1:21551] NA "DMC" NA NA ...
##  $ Position 3                  : chr [1:21551] NA NA NA NA ...
##  $ CM                          : num [1:21551] 186 188 170 170 184 177 172 190 173 183 ...
##  $ KG                          : num [1:21551] 80 78 61 58 70 72 63 80 64 72 ...
##  $ Apps                        : chr [1:21551] "0(1)" "33(4)" "19(12)" "28(6)" ...
##  $ Mins                        : num [1:21551] 45 3071 1768 2612 91 ...
##  $ Goals                       : num [1:21551] 0 9 2 9 1 21 6 0 8 0 ...
##  $ Assists                     : num [1:21551] 0 1 4 10 0 5 2 0 9 5 ...
##  $ Yel                         : num [1:21551] 0 8 0 1 0 2 1 1 3 0 ...
##  $ Red                         : num [1:21551] 0 0 0 0 0 0 0 0 0 0 ...
##  $ SpG                         : num [1:21551] 0 0.8 0.6 1.7 2 2.8 1.8 1 1.6 0.4 ...
##  $ PS%                         : num [1:21551] 85 84.4 85.2 82.8 76.5 78.9 76.1 67.6 81.1 79.3 ...
##  $ AerialsWon                  : num [1:21551] 0 1.8 0.5 0.3 2 1.4 0.3 1 0.5 2.1 ...
##  $ MotM                        : num [1:21551] 0 2 2 5 1 3 1 0 3 0 ...
##  $ Rating                      : num [1:21551] 7.16 7.51 6.92 7.48 7.42 7.38 7.35 7.31 7.29 7.29 ...

Nous avons bien le type voulu à présent, et pouvons donc passer à l’exploration à proprement dite, après un premier coup d’oeil général sur les différentes variables.

summary(db)
##  année (début du championnat)    Player              Club          
##  Min.   :2009                 Length:21551       Length:21551      
##  1st Qu.:2011                 Class :character   Class :character  
##  Median :2012                 Mode  :character   Mode  :character  
##  Mean   :2013                                                      
##  3rd Qu.:2015                                                      
##  Max.   :2016                                                      
##       âge          Position          Position 2         Position 3       
##  Min.   :16.00   Length:21551       Length:21551       Length:21551      
##  1st Qu.:26.00   Class :character   Class :character   Class :character  
##  Median :30.00   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :29.97                                                           
##  3rd Qu.:33.00                                                           
##  Max.   :47.00                                                           
##        CM            KG             Apps                Mins     
##  Min.   :159   Min.   : 52.00   Length:21551       Min.   :   1  
##  1st Qu.:178   1st Qu.: 72.00   Class :character   1st Qu.: 382  
##  Median :182   Median : 76.00   Mode  :character   Median :1208  
##  Mean   :182   Mean   : 76.49                      Mean   :1325  
##  3rd Qu.:186   3rd Qu.: 81.00                      3rd Qu.:2174  
##  Max.   :203   Max.   :104.00                      Max.   :3420  
##      Goals           Assists            Yel              Red        
##  Min.   : 0.000   Min.   : 0.000   Min.   : 0.000   Min.   :0.0000  
##  1st Qu.: 0.000   1st Qu.: 0.000   1st Qu.: 0.000   1st Qu.:0.0000  
##  Median : 0.000   Median : 0.000   Median : 2.000   Median :0.0000  
##  Mean   : 1.766   Mean   : 1.231   Mean   : 2.697   Mean   :0.1605  
##  3rd Qu.: 2.000   3rd Qu.: 2.000   3rd Qu.: 4.000   3rd Qu.:0.0000  
##  Max.   :50.000   Max.   :20.000   Max.   :18.000   Max.   :5.0000  
##       SpG              PS%           AerialsWon          MotM        
##  Min.   :0.0000   Min.   :  0.00   Min.   :0.0000   Min.   : 0.0000  
##  1st Qu.:0.2000   1st Qu.: 70.90   1st Qu.:0.3000   1st Qu.: 0.0000  
##  Median :0.6000   Median : 77.50   Median :0.7000   Median : 0.0000  
##  Mean   :0.7747   Mean   : 75.31   Mean   :0.9607   Mean   : 0.6715  
##  3rd Qu.:1.1000   3rd Qu.: 82.70   3rd Qu.:1.4000   3rd Qu.: 1.0000  
##  Max.   :7.4000   Max.   :100.00   Max.   :9.5000   Max.   :25.0000  
##      Rating      
##  Min.   : 3.700  
##  1st Qu.: 6.430  
##  Median : 6.710  
##  Mean   : 6.701  
##  3rd Qu.: 6.960  
##  Max.   :10.000

Pour commencer, nous pouvons par exemple étudier les différences morphologiques des différents postes, pour mieux appréhender nos données, et offrir un premier éclairage facile et à priori attendu dans ce contexte. Par exemple, la réparition des tailles par poste nous montre que les gardiens, et dans une moindre mesure les défenseurs semblent plus grands que leurs partenaires (N’hésitez pas essayer différente représentations graphiques, ici boxplots et violon plots).

gg1 = ggplot(db) + geom_boxplot(aes(x = Position, y = CM, color = Position)) + theme_classic() + labs(title = "Boxplot des tailles par poste")

gg2 = ggplot(db) + geom_violin(aes(x = Position, y = KG, color = Position)) + theme_classic() + labs(title = "Violin plot des poids par poste")

gg3 = ggplot(db) + geom_boxplot(aes(y = Position, x = âge, color = Position)) + theme_classic() + labs(title = "Boxplot des âges par poste")

gg4 = ggplot(db) + geom_violin(aes(y = Position, x = Rating, color = Position)) + theme_classic() + labs(title = "Violin plot des notes par poste")

grid.arrange(gg1, gg2, gg3, gg4, ncol = 2, nrow = 2)

De manière analogue, et plutôt logiquement, la répartition des poids par poste semble suivre la même forme. Quand aux âges, les différences sont moindres, alors que pour les notes, c’est la réparition qui différe beaucoup, malgré une moyenne relativement similaire entre les postes.

db %>% filter(Position == 'F') %>%  ggplot() + geom_point(aes(x = âge, y =  Goals))

Sur le graphe ci-dessus, on remarque de manière assez surprenante que le plus grand nombre de but est marqué par des joueurs d’environ 30 ans, avec une distribution très symétrique autour de cet âge. Il y a quasiment autant de buts marqués par des joueurs de plus de 40 ans que par des joueurs de moins de 25, ce qui est très surprenant, et mériterait probablement d’être creusé plus tard.

Maintenant qu’une première prise en main a permis de visualiser quelques informations brutes, il est temps à présent de plonger dans une analyse en composante principale plus poussée. Pour se faire, il est d’abord nécessaire d’extraire seulement les variables numériques dans une sous base db_pca, et de bien penser à centrer et réduire les données qui ont des ordres de grandeurs très différents (à l’aide de l’argument scale.unit = TRUE, dont c’est la valeur par défaut). Pour le reste la fonction PCA() du package FactoMineR implémente d’elle même une ACP très complète, dont il est ensuite nécessaire d’étudier précisement les résultats.

db_pca = db %>% select(âge, CM, KG, Mins, Goals, Assists, Yel, Red, SpG, `PS%`,  AerialsWon, MotM, Rating)

res_pca = PCA(db_pca, scale.unit = T)

Dans un premier temps, il est nécessaire d’interpréter le cercle des corrélations. Les ‘petites’ fléches qui sont loins du cercle correspondent au variables (âge, Red, PS%) très mal représentées sur ces deux premiers axes factorielles et peuvent donc être mises de côtés. Pour ce qui est de la première composante principale, on voit que les variables, Mins, Ratin, MotM, Goals, SpG, Assists sont toutes positivement bien corrélées avec elles. Ces variables semblent nous indiquer que cette axe indique probablement une notion de ‘bonne performance’ et les individus sur la droite du graphique auront tendance à avoir de grosses valeurs dans toutes ces catégories, et sont donc probablement les meilleurs footballeurs. A contrario, ceux placés à droite seront les individus les moins performants. Pour ce qui est du deuxième axe, il est extrémement clair qu’il nous renseigne sur la morphologie du footballeur, avec des variables de taille (CM) et de poids (KG) qui lui sont très corrélés. Les joueurs grands et massifs se trouveront sur le haut du graphs et les plus petits et/ou légers se trouveront vers le bas.

Nous pouvons ainsi passer au deuxième graphe qui nous montre la projection des individus dans le premier plan factoriel composé des deux composantes principales les plus informatives. Grâce aux informations déduites précédemment, il est possible de définir 4 grands ‘cadrans’ dans notre graph, où on aurait (de manière caricaturale bien sûr) les footballeurs costauds et talentueux en haut à droite, talentueux et plus petit/léger en bas à droite. Quand aux grands moins performants, ils se trouvent en haut à gauche, et en bas à gauche pour les joueurs petits et peu performants. Il est toujours intéressant de vérifier ces affirmations en procédant à des vérifications de par notre connaissance qui dépendent du contexte et de nos connaissances. Par exemple, il y a en bas à droite quelques points très éloignés des autres dans le cadrant des ‘petits/talentueux’. Un suiveur, même lointain, du football européen aura tôt fait de penser à Lionel Messi, et il s’agit en effet de lui, pour différente années de performances. Une simple ACP nous aura donné en quelques secondes une illustration extrémement claire de ce que tous les spécialistes du football s’accorde à dire: ce joueur sort complétement de l’ordinaire! Et quelques calculs d’algèbre linéaire, sans la moindre notion de contexte sportif réussissent à le mettre en évidence. Impressionnant, et prometteur pour la suite.

Pour choisir le nombre d’axes à retenir et les analyser plus en détail, il sera nécessaire de bien regarder (au moins) le summary des résultats

summary(res_pca)
## 
## Call:
## PCA(X = db_pca, scale.unit = T) 
## 
## 
## Eigenvalues
##                        Dim.1   Dim.2   Dim.3   Dim.4   Dim.5   Dim.6   Dim.7
## Variance               3.914   2.222   1.401   1.028   0.913   0.814   0.667
## % of var.             30.107  17.095  10.779   7.909   7.021   6.258   5.132
## Cumulative % of var.  30.107  47.202  57.981  65.890  72.911  79.169  84.301
##                        Dim.8   Dim.9  Dim.10  Dim.11  Dim.12  Dim.13
## Variance               0.546   0.438   0.349   0.289   0.217   0.202
## % of var.              4.202   3.369   2.683   2.221   1.670   1.554
## Cumulative % of var.  88.503  91.873  94.555  96.776  98.446 100.000
## 
## Individuals (the 10 first)
##                Dist    Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3
## 1          |  3.601 | -1.613  0.003  0.201 | -0.012  0.000  0.000 | -0.550
## 2          |  4.540 |  3.273  0.013  0.520 |  0.951  0.002  0.044 |  0.277
## 3          |  3.745 |  0.900  0.001  0.058 | -3.010  0.019  0.646 |  0.443
## 4          |  7.522 |  4.946  0.029  0.432 | -4.472  0.042  0.353 | -1.371
## 5          |  3.776 |  0.309  0.000  0.007 | -0.550  0.001  0.021 | -1.108
## 6          |  7.082 |  5.374  0.034  0.576 | -2.052  0.009  0.084 | -2.894
## 7          |  4.188 |  1.009  0.001  0.058 | -3.108  0.020  0.551 | -0.981
## 8          |  3.011 | -0.752  0.001  0.062 |  0.994  0.002  0.109 | -1.111
## 9          |  5.885 |  4.158  0.020  0.499 | -3.290  0.023  0.313 | -0.801
## 10         |  3.561 |  0.367  0.000  0.011 | -0.482  0.000  0.018 | -0.226
##               ctr   cos2  
## 1           0.001  0.023 |
## 2           0.000  0.004 |
## 3           0.001  0.014 |
## 4           0.006  0.033 |
## 5           0.004  0.086 |
## 6           0.028  0.167 |
## 7           0.003  0.055 |
## 8           0.004  0.136 |
## 9           0.002  0.019 |
## 10          0.000  0.004 |
## 
## Variables (the 10 first)
##               Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr   cos2
## âge        |  0.158  0.640  0.025 |  0.245  2.705  0.060 |  0.199  2.833  0.040
## CM         | -0.028  0.020  0.001 |  0.867 33.830  0.752 | -0.264  4.975  0.070
## KG         |  0.018  0.008  0.000 |  0.847 32.318  0.718 | -0.283  5.706  0.080
## Mins       |  0.760 14.763  0.578 |  0.197  1.747  0.039 |  0.299  6.396  0.090
## Goals      |  0.759 14.714  0.576 | -0.168  1.268  0.028 | -0.427 13.035  0.183
## Assists    |  0.717 13.145  0.515 | -0.316  4.507  0.100 | -0.157  1.749  0.025
## Yel        |  0.583  8.691  0.340 |  0.149  1.004  0.022 |  0.547 21.325  0.299
## Red        |  0.198  1.005  0.039 |  0.184  1.516  0.034 |  0.442 13.916  0.195
## SpG        |  0.682 11.893  0.465 | -0.270  3.275  0.073 | -0.387 10.697  0.150
## PS%        |  0.165  0.696  0.027 | -0.291  3.807  0.085 |  0.427 12.989  0.182
##             
## âge        |
## CM         |
## KG         |
## Mins       |
## Goals      |
## Assists    |
## Yel        |
## Red        |
## SpG        |
## PS%        |

Cette commande nous permet de balayer rapidement trois aspects fondamentaux de l’ACP: la variance exprimée par chaque composante principale, les contributions des individus (les 10 premiers), les contributions des variables (les 10 premières). Pour les petits jeux de données, ou si l’on a peu de temps, ce summary peut suffire à un première analyse rapide des données.

Si l’on souhaite avoir une vision plus globale et graphique pour sélectionner le nombre d’axes à retenir, on pourra afficher un figure appelée ‘ébouli des valeurs propres’. Le package factoextra nous propose une fonction bien pratique effectuer pour cette tâche (l’argument addlabels sert uniquement à afficher les pourcentages explicitement).

fviz_screeplot(res_pca, addlabels = T)

En pratique, le choix du nombre d’axes est relativement arbitraire, bien qu’il existe différents critères objectifs (critère du coude, règle de Kayser, …), en fonction du contexte et surtout du temps disponible pour notre analyse. Ici, on sélectionne 3 axes à analyser, ce qui nous donne déjà environ 58% de variance expliquée.

Pour pouvoir interpréter correctement chaque axe retenu, il est nécessaire d’étudier plus en détail la façon dont ils ont été construits. Pour cela, il peut être intéressant d’étudier la contribution de chaque variable aux composantes principales, ainsi que leur qualité de représentation, avec les commandes ci-dessous.

res_pca$var$contrib
##                   Dim.1       Dim.2     Dim.3        Dim.4        Dim.5
## âge         0.639972121  2.70539508  2.833371 53.504623571 12.820571703
## CM          0.020283700 33.82972898  4.975023  1.251309856  0.070356470
## KG          0.008185462 32.31753359  5.706443  0.020267359  0.401387865
## Mins       14.762798230  1.74691774  6.395595  2.318290548  0.068266488
## Goals      14.713854330  1.26754944 13.034755  0.001207545  0.783013868
## Assists    13.145460851  4.50663921  1.748961  0.910580186  0.001241685
## Yel         8.690630907  1.00436281 21.324697  0.062767948  0.003126891
## Red         1.004906133  1.51587923 13.916214  0.072160617 62.178312439
## SpG        11.892617031  3.27546385 10.696821  0.845926352  0.452739921
## PS%         0.695581268  3.80711645 12.989357 22.122915244 18.597007616
## AerialsWon  3.305620330 12.96375759  1.179799 18.314352346  0.450380062
## MotM       15.471539560  0.05245911  4.014579  0.120038505  0.397455548
## Rating     15.648550077  1.00719690  1.184385  0.455559925  3.776139443
res_pca$var$cos2
##                   Dim.1       Dim.2      Dim.3        Dim.4        Dim.5
## âge        0.0250480296 0.060124693 0.03970174 5.500841e-01 1.170209e-01
## CM         0.0007938888 0.751831803 0.06971097 1.286479e-02 6.421849e-04
## KG         0.0003203728 0.718224777 0.07995977 2.083699e-04 3.663703e-03
## Mins       0.5778048683 0.038823495 0.08961630 2.383448e-02 6.231084e-04
## Goals      0.5758892407 0.028170015 0.18264549 1.241484e-05 7.147029e-03
## Assists    0.5145034944 0.100155537 0.02450678 9.361727e-03 1.133359e-05
## Yel        0.3401447861 0.022320956 0.29880574 6.453209e-04 2.854098e-05
## Red        0.0393312736 0.033688896 0.19499666 7.418875e-04 5.675381e-01
## SpG        0.4654681254 0.072793900 0.14988591 8.697018e-03 4.132424e-03
## PS%        0.0272245300 0.084609346 0.18200937 2.274470e-01 1.697458e-01
## AerialsWon 0.1293795045 0.288106513 0.01653156 1.882909e-01 4.110884e-03
## MotM       0.6055444732 0.001165851 0.05625306 1.234123e-03 3.627811e-03
## Rating     0.6124725323 0.022383941 0.01659583 4.683638e-03 3.446705e-02

Si l’on préfère avoir ces informations sous la forme d’un graphique, il sera encore une fois possible de faire appel au package factoextra:

fviz_contrib(res_pca, choice = 'var', axes = 1)

fviz_contrib(res_pca, choice = 'var', axes = 2)

On retrouve bien sur les deux premiers axes les variables que l’on avait retenu dans notre analyse préalable. Regardons maintenant les nouvelles variables d’influence sur le troisième axe.

fviz_contrib(res_pca, choice = 'var', axes = 3)

Les cartons, le nombre de tirs, de buts, et le pourcentage de passes réussies sont donc les variables les plus influentes sur ce troisième axe et serviront principalement à son interprétatation. En affichant le cercle des corrélations utilisant les 2ème et 3ème composantes principales, on peut remarquer que ce 3ème axe semble opposer les attaquants, qui tirent et marquent beaucoup, aux défenseurs/milieux, qui réussissent beaucoup de passes et prennent beaucoup de cartons.

fviz_pca_var(res_pca, axes = c(2,3))

On pourra constater que cette interprétation est logique sur le graphique ci-dessous en prenant un exemple. En effet, l’individu 293 n’est autre que Marco Verrati, qui est situé dans le cadrant en haut à gauche. D’après notre interprétation, il s’agit d’une position qui correspond à un joueur plutôt petit et maigre, qui réussit beaucoup de passes et prend beaucoup de cartons, ce qui est exactement le profil de Verrati. Nous sommes donc rassurés sur notre interprétation.

fviz_pca_ind(res_pca, axes = c(2,3))

Pour résumer, voici ci-dessous les étapes importantes à mettre en place dans une ACP (cela sera vrai aussi pour l’AFC que l’on voit par la suite):

  1. Choix du nombre de composantes principales que l’on retient.
  2. Analyse des composantes principales retenues:
  1. Contributions/qualités de représentations de chaque variables à l’axe 1/2/3…,
  2. Sélection des variables importantes pour chaque axe,
  3. Interprétation de chaque composante principale retenue à l’aide de ces variables.
  1. Analyse des individus sur les différents plans factoriels.

Analyse Factorielle des Correspondances (AFC)

Lorsque les variables que l’on souhaite analyser ne sont plus quantitatives mais qualitatives, il n’est plus possible d’effectuer une ACP. Une solution possible est d’avoir recours à l’Analyse Factorielle des Correspondances (AFC). Cette méthode, un cas particulier d’ACP, permet d’étudier deux variables qualitatives, en analysant les différentes modalités prises par ces deux variables. Pour cela, il est nécessaire tout d’abord de sélectionner deux variables pouvant être considérées comme qualitatives. Ici on choisira par exemple le poste du joueur et le nombre de carton rouge reçu (qui est certes numérique, mais qui peut être considérée comme qualitative pour l’occasion).

db_ca = db %>% select(Red, Position)

Ensuite, on transforme notre base de données en tableau de contigence, qui va compter pour chaque modalité, le nombre d’individus correspondants.

tab_ca = table(db_ca$Red, db_ca$Position)
tab_ca
##    
##        D    F   GK    M
##   0 7348 4957 1539 4636
##   1 1493  458  151  612
##   2  223   33    8   65
##   3   20    3    0    3
##   4    1    0    0    0
##   5    1    0    0    0

On peut déjà remarquer dans ce tableau que les modalités 4 et 5 pour les cartons rouges sont très mal représentées avec un seul individu. En général, il est plus sage de retirer ces modalités de l’analyse car elles biaisent souvent l’AFC comme nous le verrons ci-dessous. Plutôt que de les retirer à la main, la fonction CA permettant d’effectuer une AFC, propose une argument row.sup permettant d’indiquer des lignes à mettre en ‘supplémentaire’. Ces modalités ne serviront pas à construire les axes, mais seront tout de même projetées sur le plan factoriel pour information.

res_ca = CA(tab_ca, row.sup = c(5,6))

On peut en effet voir sur ce graph que les modalités 4 et 5 sont en bleus foncés, et donc traitées à part dans l’AFC.

summary(res_ca)
## 
## Call:
## CA(X = tab_ca, row.sup = c(5, 6)) 
## 
## The chi square of independence between the two variables is equal to 364.5086 (p-value =  5.047295e-73 ).
## 
## Eigenvalues
##                        Dim.1   Dim.2   Dim.3
## Variance               0.017   0.000   0.000
## % of var.             99.561   0.411   0.028
## Cumulative % of var.  99.561  99.972 100.000
## 
## Rows
##      Iner*1000    Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr
## 0  |     2.236 |  0.051 13.272  1.000 | -0.001  0.569  0.000 |  0.000  0.401
## 1  |     9.555 | -0.275 56.667  0.999 |  0.009 15.421  0.001 |  0.002 15.317
## 2  |     4.509 | -0.543 26.716  0.998 | -0.022 10.326  0.002 | -0.014 61.432
## 3  |     0.616 | -0.683  3.345  0.915 | -0.206 73.684  0.083 |  0.030 22.850
##      cos2  
## 0   0.000 |
## 1   0.000 |
## 2   0.001 |
## 3   0.002 |
## 
## Columns
##      Iner*1000    Dim.1    ctr   cos2    Dim.2    ctr   cos2    Dim.3    ctr
## D  |     8.827 | -0.145 52.402  1.000 | -0.002  3.102  0.000 |  0.001  2.341
## F  |     5.818 |  0.151 34.384  0.995 | -0.010 39.608  0.005 |  0.000  0.712
## GK |     1.746 |  0.148 10.279  0.991 |  0.012 17.248  0.007 |  0.006 64.593
## M  |     0.524 |  0.045  2.935  0.944 |  0.011 40.042  0.053 | -0.002 32.354
##      cos2  
## D   0.000 |
## F   0.000 |
## GK  0.002 |
## M   0.003 |
## 
## Supplementary rows
##       Dim.1   cos2    Dim.2   cos2    Dim.3   cos2  
## 4  | -1.115  0.906 | -0.271  0.054 |  0.236  0.040 |
## 5  | -1.115  0.906 | -0.271  0.054 |  0.236  0.040 |

Encore une fois, le summary des résultats de l’AFC peuvent nous permettre une première analyse plus fine pour une meilleure interprétation du gaphique.