Nettoyage des données

# Les packages nécessaires
library(dplyr)
## 
## Attachement du package : 'dplyr'
## Les objets suivants sont masqués depuis 'package:stats':
## 
##     filter, lag
## Les objets suivants sont masqués depuis 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
library(FactoMineR)
## Warning: le package 'FactoMineR' a été compilé avec la version R 4.2.3
library(explor)
## Warning: le package 'explor' a été compilé avec la version R 4.2.3
library(reshape2)
library(factoextra)
## Warning: le package 'factoextra' a été compilé avec la version R 4.2.3
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
# Lecture du fichier de données
df <- read.csv("D:/BUT-2/Classification/foot.csv", sep=";", encoding="latin1")

# Supprimation des doublons basés sur la colonne player
df <- df %>% distinct(Player, .keep_all = TRUE)

# Les lignes sont les noms des joueurs
row.names(df) <- df$Player

Pour effectuer une analyse pertinente des performances des joueurs au cours de la saison, nous avons choisi de conserver uniquement ceux qui ont participé de manière significative. Concrètement, cela signifie que nous nous concentrons sur les joueurs ayant disputé plus de 5 matchs et ayant un temps de jeu moyen de plus de 45 minutes par match.

df <- df[df$Min/df$MP >= 45 & df$MP > 5,]

Afin de faciliter notre analyse nous avons choisi de rassembler les postes des joueurs afin d’avoir d’un poste par joueur soit DF, soit FW , soit MF ou G.

table(df$Pos)
## 
##   DF DFFW DFMF   FW FWDF FWMF   GK   MF MFDF MFFW 
##   89    3   10   30    1   11   18   45    6   18
df <- df %>% mutate(Pos = recode(Pos,"DFFW" = "DF", "DFMF" = "DF", "FWDF" = "FW", "FWMF" = "FW", "MFDF" = "MF", "MFFW" = "MF"))
table(df$Pos)
## 
##  DF  FW  GK  MF 
## 102  42  18  69

Ces variables ont été supprimées car elles contenaient un nombre excessif de valeurs nulles (0). Un nombre trop élevé de valeurs nulles dans une variable signifie qu’elle ne varie pas suffisamment pour fournir des informations utiles ou différencier les performances des joueurs. Ainsi, leur pertinence pour l’analyse est grandement diminuée, rendant ces variables peu utiles pour notre étude.

df <- df %>% select(-Off, -Err, -PasShoCmp.,-PasMedCmp.,-PasLonCmp., -Born)

On peut regrouper les variables Rec, Recov, Blocks et Int car elles représentent toutes la récupération de la balle. Étant donné que ces valeurs sont calculées en proportion, nous avons décidé de les fusionner en prenant leur moyenne, ce qui simplifie l’analyse tout en conservant une mesure globale de l’efficacité des joueurs dans la récupération de la balle.

df$Get_ball = (df$Recov + df$Blocks + df$Int)/3
df$Recov <- NULL
df$Blocks <- NULL
df$Int <- NULL

On regroupe les cartons rouges et jaunes en cartons.

df$Crd = (df$CrdY + df$CrdR)/2
df$CrdY <- NULL
df$CrdR <- NULL

On crée un dataframe avec seulement les variables quantitatives.

df_quanti <- df %>% select(-Pos, -Squad)
summary(df_quanti)
##     Player               Age              MP             Min      
##  Length:231         Min.   :18.00   Min.   : 6.00   Min.   : 324  
##  Class :character   1st Qu.:24.50   1st Qu.:14.00   1st Qu.: 898  
##  Mode  :character   Median :27.00   Median :17.00   Median :1181  
##                     Mean   :27.53   Mean   :16.16   Mean   :1180  
##                     3rd Qu.:30.00   3rd Qu.:19.50   3rd Qu.:1468  
##                     Max.   :38.00   Max.   :23.00   Max.   :2070  
##      Goals            Shots            SoT            ShoDist     
##  Min.   : 0.000   Min.   :0.000   Min.   :0.0000   Min.   : 0.00  
##  1st Qu.: 0.000   1st Qu.:0.445   1st Qu.:0.0750   1st Qu.:12.55  
##  Median : 1.000   Median :0.950   Median :0.2800   Median :16.20  
##  Mean   : 2.113   Mean   :1.268   Mean   :0.4532   Mean   :15.56  
##  3rd Qu.: 3.000   3rd Qu.:1.920   3rd Qu.:0.6750   3rd Qu.:19.55  
##  Max.   :25.000   Max.   :5.550   Max.   :2.2700   Max.   :34.10  
##    PasTotCmp.        PasAss            PPA             PasAtt      
##  Min.   :53.00   Min.   :0.0000   Min.   :0.0000   Min.   : 12.50  
##  1st Qu.:77.40   1st Qu.:0.3050   1st Qu.:0.2800   1st Qu.: 41.00  
##  Median :83.40   Median :0.8500   Median :0.7500   Median : 54.30  
##  Mean   :82.07   Mean   :0.9958   Mean   :0.8995   Mean   : 53.53  
##  3rd Qu.:87.10   3rd Qu.:1.5850   3rd Qu.:1.3500   3rd Qu.: 64.90  
##  Max.   :95.50   Max.   :3.6000   Max.   :4.6900   Max.   :104.20  
##        CK              SCA             GCA              Tkl       
##  Min.   :0.0000   Min.   :0.000   Min.   :0.0000   Min.   :0.000  
##  1st Qu.:0.0000   1st Qu.:1.090   1st Qu.:0.0700   1st Qu.:0.935  
##  Median :0.0000   Median :2.110   Median :0.2300   Median :1.460  
##  Mean   :0.4694   Mean   :2.318   Mean   :0.2831   Mean   :1.495  
##  3rd Qu.:0.2300   3rd Qu.:3.355   3rd Qu.:0.4700   3rd Qu.:2.050  
##  Max.   :6.2400   Max.   :6.520   Max.   :1.2600   Max.   :4.090  
##       Clr           Touches           ToAtt          Carries     
##  Min.   :0.000   Min.   : 20.70   Min.   :0.000   Min.   : 9.24  
##  1st Qu.:0.445   1st Qu.: 52.30   1st Qu.:0.475   1st Qu.:30.15  
##  Median :1.130   Median : 64.00   Median :1.060   Median :37.50  
##  Mean   :1.492   Mean   : 63.19   Mean   :1.555   Mean   :38.91  
##  3rd Qu.:2.310   3rd Qu.: 74.95   3rd Qu.:2.115   3rd Qu.:47.05  
##  Max.   :4.650   Max.   :114.10   Max.   :8.100   Max.   :96.40  
##       CPA              Rec             Crs           Get_ball     
##  Min.   :0.0000   Min.   :12.10   Min.   :0.000   Min.   :0.2433  
##  1st Qu.:0.0000   1st Qu.:35.10   1st Qu.:0.160   1st Qu.:1.7050  
##  Median :0.1700   Median :43.90   Median :0.870   Median :2.3367  
##  Mean   :0.4894   Mean   :44.09   Mean   :1.528   Mean   :2.2429  
##  3rd Qu.:0.7050   3rd Qu.:52.60   3rd Qu.:2.235   3rd Qu.:2.9017  
##  Max.   :3.6400   Max.   :91.50   Max.   :8.960   Max.   :4.1433  
##       Crd         
##  Min.   :0.00000  
##  1st Qu.:0.03500  
##  Median :0.08000  
##  Mean   :0.08911  
##  3rd Qu.:0.13000  
##  Max.   :0.59500
df_quanti2 <- select(df_quanti,-Player)

Analyse de la base de donnée

# Création du modèle de régression linéaire
modele <- lm(Min ~ MP, data = df)

# Affichage du graphique pour la régression linéaire avec ggplot
ggplot(df, aes(x = MP, y = Min)) +
  geom_point() +  # Points de données
  geom_smooth(method = "lm", se = FALSE, color = "red") +  # Régression linéaire
  labs(x = "Matches played (MP)", y = "Minutes played (Min)", 
       title = "Regression linéaire: minutes joué en fonction de matchs joué")
## `geom_smooth()` using formula = 'y ~ x'

cor(df$MP, df$Min)
## [1] 0.8713091
# Étiquettes des parts
etiquettes <- c("Défenseur", "Attaquant", "Gardien", "Milieu")
df$Pos <- factor(df$Pos, levels = c("DF", "FW", "GK", "MF"), labels = etiquettes)
# Comptage des valeurs
valeurs <- table(df$Pos)

# Conversion de la table en dataframe
df_valeurs <- as.data.frame(valeurs)

# Création du diagramme en camembert avec ggplot
ggplot(df_valeurs, aes(x = "", y = Freq, fill = Var1)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar(theta = "y") +
  labs(title = "Répartition des postes") +
  theme_void() +
  labs(fill = "Postes")

# Analyse de l'age 
# Création d'un vecteur pour les étiquettes d'âge
etiquettes_age <- c("Moins de 20", "20-24", "25-29", "30-34", "35 et plus")

# Définir les limites des intervalles d'âge
bornes <- c(0, 20, 25, 30, 35, max(df$Age))

# Création des intervalles d'âge avec des étiquettes
df$IntervalAge <- cut(df$Age, breaks = bornes, labels = etiquettes_age)

# Création de l'histogramme avec ggplot2
ggplot(df, aes(x = IntervalAge, fill = IntervalAge)) +
  geom_bar() +
  labs(x = "Âge", y = "Nombre de joueurs", title = "Répartition des joueurs par âge") +
  scale_fill_brewer(palette = "Set3") +  # Choix de la palette de couleurs
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotation des étiquettes sur l'axe x

Réalisation d’une ACP et interprétation

nvar=ncol(df_quanti)
df_quanti.acp = PCA(df_quanti, ncp = nvar, quali.sup = 1, graph=TRUE)

Le graphique d’Analyse en Composantes Principales (ACP) montre les relations entre différentes variables de performance des joueurs. Les axes Dim 1 et Dim 2 expliquent respectivement 32.32 % et 23,12 % de la variance totale. Chaque flèche représente une variable, et sa direction et longueur montrent son importance et sa contribution aux deux dimensions principales. Les flèches pointant dans la même direction sont positivement corrélées, tandis que celles pointant en sens opposé sont négativement corrélées. Par exemple, les variables comme PasTotCmp, Clr, repésentant les pass et le dégagement, sont corrélées et situées à gauche, tandis que les variables offensives comme Goals, Shots, et SoT se trouvent à droite. Les flèches représentées sous forme d’angle droit ne sont pas corrélées. Par exemple, la distance de tir ShoDist n’est pas corrélée avec le nombre de but Goals. L’âge est près du centre, ce qui indique une contribution modérée. Ce graphique permet d’identifier facilement les groupes de variables qui sont liés à des aspects spécifiques de la performance des joueurs.

explor(df_quanti.acp)
Shiny applications not supported in static R Markdown documents
df_quanti.acp$eig
##           eigenvalue percentage of variance cumulative percentage of variance
## comp 1  7.7569679227           32.320699678                          32.32070
## comp 2  5.5489437770           23.120599071                          55.44130
## comp 3  2.0634019011            8.597507921                          64.03881
## comp 4  1.6422134391            6.842555996                          70.88136
## comp 5  1.4950723740            6.229468225                          77.11083
## comp 6  1.1194712064            4.664463360                          81.77529
## comp 7  0.6990471620            2.912696508                          84.68799
## comp 8  0.6679186280            2.782994283                          87.47099
## comp 9  0.5494564508            2.289401878                          89.76039
## comp 10 0.4255541628            1.773142345                          91.53353
## comp 11 0.3769357638            1.570565682                          93.10409
## comp 12 0.3302881381            1.376200576                          94.48030
## comp 13 0.2772531002            1.155221251                          95.63552
## comp 14 0.2019894979            0.841622908                          96.47714
## comp 15 0.1834331260            0.764304692                          97.24144
## comp 16 0.1662040159            0.692516733                          97.93396
## comp 17 0.1329065372            0.553777238                          98.48774
## comp 18 0.1063941677            0.443309032                          98.93105
## comp 19 0.0889006215            0.370419256                          99.30147
## comp 20 0.0583124850            0.242968688                          99.54444
## comp 21 0.0524327187            0.218469661                          99.76290
## comp 22 0.0392803869            0.163668279                          99.92657
## comp 23 0.0166683452            0.069451438                          99.99602
## comp 24 0.0009540721            0.003975301                         100.00000
plot(df_quanti.acp$eig[,'eigenvalue'], main="Ebouli des valeurs propres", names.arg=1)
## Warning in plot.window(...): "names.arg" n'est pas un paramètre graphique
## Warning in plot.xy(xy, type, ...): "names.arg" n'est pas un paramètre graphique
## Warning in axis(side = side, at = at, labels = labels, ...): "names.arg" n'est
## pas un paramètre graphique

## Warning in axis(side = side, at = at, labels = labels, ...): "names.arg" n'est
## pas un paramètre graphique
## Warning in box(...): "names.arg" n'est pas un paramètre graphique
## Warning in title(...): "names.arg" n'est pas un paramètre graphique

D’après la règle de kaiser, il faut garder les axes dont la valeur des valeurs propres est supérieure à 1. D’après la règle empiriques, il faut garder les facteurs expliquant un pourcentage de variance cumulé à 80%. D’après l’éboulis des valeurs propres, il faut garder les axes correspondant aux valeurs propres situées avant le point d’inflexion. Dans les trois cas, on doit conserver 6 axes, mais nous allons en analyser que 4.

Axe 1

Les variables qui représentent le mieux l’axe 1 sont SCA, PasAss, Shots, SoT, GCA, ToAtt, PPA, CPA. Ces variables sont tous en lien avec un jeu offensif comme les attaquants. Donc on peut dire que les joueurs qui sont à droite du cercle sont les joueurs ayant un style de jeu offensif. Et les joueurs à gauche du cercle ont un style de jeu peu offensif. Le joueur offensif qui se démarque le plus est Lionnel Messi, ou encore Kylian Mbappe. De l’autre côté, on a le défenseur Victor Lindelof qui est peu offensif.

Axe 2

Les variables qui représentent le mieux l’axe 2 sont Rec, Touches, PasAtt, Carries. Ces variables sont fortement en lien avec un jeu qui contrôle beaucoup le ballon comme les milieux de terrain. Donc on peut dire que les joueurs qui sont en haut du cercle sont les joueurs qui contrôlent beaucoup le ballon. Et les joueurs en bas du cercle contrôlent peu le ballon. Par exemple, le joueur Marco Verrati contrôle beaucoup le ballon. Alors que Jan Oblak possède peu le ballon.

Axe 3

Les variables qui représentent le mieux l’axe 3 sont Min, MP. Ces variables renvoient aux joueurs qui ont le plus joué. Donc on peut dire que les joueurs qui sont en haut du cercle sont les joueurs qui ont le plus joué. Et les joueurs en bas du cercle ont le moins joué. Par exemple, le joueur David de Gea a beaucoup joué. Alors que Pablo Marin a peu joué.

Axe 4

Les variables qui représentent le mieux l’axe 4 sont Crs, CK. Ces variables renvoient aux joueurs qui font un grand nombre de centre. Donc on peut dire que les joueurs qui sont en bas du cercle sont les joueurs qui font le plus de centre. Et les joueurs en haut du cercle ont fait peu de centre. Par exemple, Ivan Perisi fait le plus de centre. Alors que Kylian Mbappe a fait le moins.

Classification et interprétation

# CAH et dendrogramme
x.std = scale(df_quanti2) #centré reduit

distance=dist(x.std, method="euclidean")

On utilise la méthode de ward.D2 pour faire le dendogramme. C’est la méthode la plus fiable.

dendro=hclust(distance, method="ward.D2")
plot(dendro, main = "Dendrogramme avec la methode de Ward", label=FALSE)
abline(h=18, col="red")

Visuellement, on aurait envie de couper avec le trait rouge (6 clusters).

Pour être sûr de nous, nous allons utiliser une fonction qui nous permet d’obtenir deux indicateurs efficaces dans notre situation : le R² et le pseudo-F.

Le R², ou coefficient de détermination, mesure la proportion de la variance des données expliquée par le modèle. Il varie de 0 à 1, avec 1 indiquant une parfaite explication des données par le modèle. Le pseudo-F est utilisé dans les analyses de clusters pour évaluer la qualité de la partition des données, en comparant la variance inter-clusters à la variance intra-cluster. Un pseudo-F élevé indique une bonne séparation des clusters.

R2.PseudoF = function(donnees,dendro, graph=T, cut=20){
  n=nrow(donnees)
  R2 = numeric(n)

  Iinter = 0
  g = apply(donnees, 2, mean)
  I = (n-1)/n*sum(diag(var(donnees)))

  for(i in 2:n){
      class = cutree(dendro,k=i)
      ncl = unique(class)
      d = numeric(length(ncl)) 
      nb = integer(length(ncl))
      for(j in ncl){
          nb[j] = sum(class==j)
          if(nb[j]>1){
              m = apply(donnees[class==j,], 2, mean)
          } else {
              m = donnees[class==j,]
          }
          d[j] = sum((m-g)^2)   
      }
      Iinter = (1/n)*sum(nb*d)
      R2[i] = Iinter/I
  }

  ncl = 2:(n-1)
  PseudoF = R2[ncl]/(1-R2[ncl])*(n-ncl)/(ncl-1)

  if(graph==T){
  par(mfrow=c(1,2))
  plot(1:20,R2[1:cut], type = 'b', xlab = "Nombre de classes", ylab = "Rsquare")
  title("Indice du R2")
  plot(ncl[1:20],PseudoF[1:cut], type = 'b', xlab = "Nombre de classes", ylab = "PseudoF")
  title("Indice du PseudoF")
  }
  resultat = list(R2,PseudoF)
  names(resultat)=c("Rsquare","PseudoF")
  resultat
}

R2.PseudoF(x.std,dendro)

## $Rsquare
##   [1] 0.0000000 0.2211536 0.3352553 0.4005804 0.4645403 0.5050802 0.5292071
##   [8] 0.5491461 0.5664977 0.5829313 0.5976616 0.6105539 0.6224683 0.6343405
##  [15] 0.6445583 0.6537525 0.6628738 0.6704383 0.6778343 0.6849116 0.6919354
##  [22] 0.6988325 0.7055823 0.7121498 0.7186794 0.7248474 0.7309393 0.7365232
##  [29] 0.7419584 0.7467311 0.7514624 0.7561010 0.7606867 0.7651505 0.7695623
##  [36] 0.7738143 0.7778720 0.7817690 0.7856571 0.7892475 0.7924927 0.7956414
##  [43] 0.7987414 0.8018120 0.8047890 0.8077430 0.8106191 0.8134205 0.8161043
##  [50] 0.8187008 0.8212901 0.8238047 0.8263080 0.8287746 0.8312209 0.8336362
##  [57] 0.8359207 0.8381975 0.8404659 0.8426537 0.8448100 0.8469472 0.8490564
##  [64] 0.8511359 0.8532126 0.8552860 0.8572788 0.8592515 0.8612215 0.8631428
##  [71] 0.8650263 0.8668375 0.8686468 0.8704402 0.8722332 0.8740152 0.8757888
##  [78] 0.8775611 0.8793011 0.8810143 0.8826953 0.8842512 0.8857979 0.8873400
##  [85] 0.8888588 0.8903595 0.8918468 0.8933270 0.8947922 0.8962539 0.8977080
##  [92] 0.8991400 0.9005664 0.9019784 0.9033885 0.9047724 0.9061445 0.9075117
##  [99] 0.9088773 0.9102270 0.9115723 0.9129073 0.9142374 0.9155575 0.9168656
## [106] 0.9181592 0.9194525 0.9207345 0.9219983 0.9232564 0.9244959 0.9257345
## [113] 0.9269719 0.9282051 0.9294215 0.9305204 0.9315916 0.9326440 0.9336854
## [120] 0.9347114 0.9357362 0.9367428 0.9377481 0.9387432 0.9397257 0.9407039
## [127] 0.9416747 0.9426418 0.9435836 0.9445074 0.9454280 0.9463453 0.9472561
## [134] 0.9481629 0.9490514 0.9499380 0.9508210 0.9517001 0.9525361 0.9533623
## [141] 0.9541829 0.9550034 0.9557981 0.9565889 0.9573775 0.9581542 0.9589291
## [148] 0.9596960 0.9604605 0.9612178 0.9619728 0.9627266 0.9634797 0.9642309
## [155] 0.9649686 0.9657020 0.9664294 0.9671413 0.9678484 0.9685506 0.9692518
## [162] 0.9699496 0.9706424 0.9713353 0.9720112 0.9726830 0.9733340 0.9739807
## [169] 0.9746231 0.9752646 0.9758996 0.9765335 0.9771533 0.9777584 0.9783617
## [176] 0.9789647 0.9795676 0.9801555 0.9807329 0.9812859 0.9818387 0.9823872
## [183] 0.9829310 0.9834728 0.9840075 0.9845396 0.9850688 0.9855951 0.9861197
## [190] 0.9866310 0.9871403 0.9876434 0.9881385 0.9886310 0.9891212 0.9896068
## [197] 0.9900861 0.9905604 0.9910284 0.9914858 0.9919397 0.9923892 0.9928345
## [204] 0.9932735 0.9936684 0.9940395 0.9944072 0.9947531 0.9950838 0.9954130
## [211] 0.9957327 0.9960513 0.9963593 0.9966617 0.9969537 0.9972374 0.9975174
## [218] 0.9977822 0.9980324 0.9982731 0.9985121 0.9987434 0.9989743 0.9992050
## [225] 0.9993690 0.9995316 0.9996772 0.9998117 0.9998974 0.9999569 1.0000000
## 
## $PseudoF
##   [1]  65.02461  57.49441  50.56655  49.01681  45.92382  41.96551  38.80243
##   [8]  36.26351  34.32097  32.68034  31.21246  29.95291  28.95756  27.97819
##  [15]  27.06287  26.29857  25.48900  24.78036  24.13965  23.58376  23.09361
##  [22]  22.65815  22.26626  21.92752  21.60164  21.31512  21.01727  20.74356
##  [29]  20.43527  20.15691  19.90037  19.66773  19.44955  19.25163  19.06067
##  [36]  18.87140  18.68606  18.52003  18.34042  18.14077  17.94743  17.76480
##  [43]  17.59415  17.42762  17.27231  17.12146  16.97479  16.82690  16.68060
##  [50]  16.54437  16.41016  16.28466  16.16463  16.05154  15.94384  15.82969
##  [57]  15.72289  15.62310  15.52161  15.42385  15.33105  15.24191  15.15600
##  [64]  15.07637  15.00276  14.92565  14.85215  14.78423  14.71607  14.64880
##  [71]  14.57788  14.51200  14.44925  14.39155  14.33743  14.28715  14.24160
##  [78]  14.19657  14.15266  14.10901  14.05271  13.99937  13.94953  13.90052
##  [85]  13.85299  13.80750  13.76488  13.72398  13.68638  13.65145  13.61701
##  [92]  13.58545  13.55539  13.52872  13.50164  13.47631  13.45381  13.43465
##  [99]  13.41652  13.40127  13.38792  13.37737  13.36876  13.36172  13.35577
## [106]  13.35344  13.35277  13.35248  13.35485  13.35743  13.36360  13.37335
## [113]  13.38622  13.39964  13.39272  13.38329  13.37310  13.36371  13.35414
## [120]  13.34746  13.33987  13.33514  13.33125  13.32763  13.32620  13.32622
## [127]  13.32861  13.32800  13.32606  13.32648  13.32926  13.33361  13.34020
## [134]  13.34518  13.35294  13.36313  13.37568  13.37909  13.38280  13.38809
## [141]  13.39664  13.40044  13.40625  13.41467  13.42252  13.43319  13.44454
## [148]  13.45860  13.47375  13.49171  13.51308  13.53816  13.56662  13.59405
## [155]  13.62398  13.65582  13.68555  13.71764  13.75217  13.79097  13.83319
## [162]  13.87821  13.92863  13.97615  14.02712  14.07264  14.12146  14.17360
## [169]  14.23139  14.29165  14.35802  14.42242  14.48421  14.55172  14.62656
## [176]  14.70942  14.78966  14.87022  14.93975  15.01728  15.09981  15.18747
## [183]  15.28307  15.38235  15.49011  15.60673  15.73317  15.87163  16.00946
## [190]  16.16049  16.32041  16.48776  16.67075  16.87209  17.09021  17.32410
## [197]  17.57832  17.85264  18.14052  18.45967  18.81269  19.20611  19.64017
## [204]  20.00191  20.33786  20.71460  21.06552  21.40886  21.80446  22.22270
## [211]  22.71417  23.23660  23.82826  24.46820  25.18480  26.04283  26.95203
## [218]  27.92129  29.03493  30.50465  32.36648  35.09717  39.45205  42.42370
## [225]  47.41627  54.81678  70.18522  85.45468 101.25642

D’après l’analyse du coefficient de détermination (R²), le point de rupture semble être à 6, ce qui maximise l’ajustement du modèle aux données. Cependant, le pseudo-F, qui évalue la qualité de cette partition, n’est pas stable à ce niveau, indiquant une possible fragilité de ce point de rupture et suggérant qu’une réévaluation pourrait être nécessaire.

################################### A PEAUFINER  ####################################################
res = cutree(dendro, 6)
df2 <- as.data.frame(x.std)
df$Cluster <- factor(res,
                     levels = 1:6,
                     labels = paste("GRP", 1:6))
clusProfile <- aggregate(df2[, 1:24],
                         by = list(df$Cluster),
                         mean)
colnames(clusProfile)[ 1] <- "CLUSTER"
clus_transpose <- melt(clusProfile, id.vars = "CLUSTER") #transposition du df

ggplot(clus_transpose) +
  geom_bar(aes(x = variable, y = value, fill = CLUSTER),
           stat = "identity") +
  scale_fill_grey() +
  facet_wrap(~ CLUSTER) +
  coord_flip() + theme_bw()

L’analyse des profils des clusters et des moyennes des variables pour chaque groupe est cruciale pour comprendre les différences et les similitudes entre les groupes. Cette analyse permet d’identifier les caractéristiques distinctives de chaque cluster,

Chaque barre représente une moyenne de variable spécifique pour le groupe 4, et les clusters sont distingués par des couleurs.

Cluster 1 :

Nous pouvons voir que les variables qui ont les moyennes les plus elévé sont CRD,get ball, rec , touches , Carries, CK et PasCompto. Ces variables sont fortement en lien avec un jeu qui contrôle beaucoup le ballon comme les milieux de terrain. ** On peut donc dire que le closter rassemble les joueurs qui contrôlent beaucoup le ballon.

Cluster 2 :

Bien sûr, voici une version plus concise :

En observant les moyennes les plus élevées pour les variables CRD, Get Ball, Rec, Touches, Carries, CK et PasCompto, il est clair que ce cluster regroupe les joueurs qui dominent le contrôle du ballon. Ces variables sont étroitement liées à un jeu de possession, typique des milieux de terrain.

D’autre part, les variables SCA, PasAss, Shots, SoT, GCA, ToAtt, PPA et CPA représentent le mieux l’axe 1. Elles sont toutes associées à un jeu offensif, souvent caractéristique des attaquants.

Cluster 3 :

En observant les moyennes ce cluster présente des moyennes plus élevées dans les variables liées à l’âge, au temps de jeu, aux tirs, aux passes réussies, aux passes décisives, aux duels aériens gagnés, aux interceptions et aux dégagements.

Ces joueurs semblent être des acteurs importants dans la création et la transition du jeu, avec une contribution notable dans les phases défensives et offensives.

Cluster 4 :

Les joueurs de ce cluster se démarquent par leurs performances dans les variables liées à l’âge, aux tirs, aux passes, aux dribbles, aux centres, aux récupérations et aux interceptions.

le cluster reprensente donc les joueurs clés dans la construction du jeu et la création d’opportunités offensives, avec une présence notable sur le terrain malgré leur âge relativement bas.

Cluster 5 :

Les variables Age,MP et Min sont les seuls avec un moyenne positif.

Ce cluster regroupe les joueurs les plus âgés de la compétition, ayant accumulé une expérience considérable sur le terrain. Leurs statistiques de matchs joués et de temps de jeu reflètent une longue carrière dans le football.( Pour résumer les joueurs les plus anciens de la compétition)

Cluster 6 :

Les variables avec les moyennes les plus élévés sont Goals , Shots , SoT.

Ce cluster se caractérise par des moyennes élevées dans les catégories des buts marqués, des tirs et des tirs cadrés. Il semble regrouper les joueurs ayant réalisé le plus de réalisations au cours de la compétition, mettant en lumière leur rôle prépondérant en tant qu’attaquants.

profils = function(donnees,classes){
  nvar=ncol(donnees)
  class=unique(classes)
  nclass=length(class)

  moyenne = matrix(nrow=nvar,ncol=nclass)
  ecart = matrix(nrow=nvar,ncol=nclass)

  rownames(moyenne)=colnames(donnees)
  colnames(moyenne)=class

  rownames(ecart)=colnames(donnees)
  colnames(ecart)=class

  for(i in 1:nclass){
   moyenne[,i] = apply(donnees[classes==class[i],],2,mean)
   ecart[,i] = sqrt(apply(donnees[classes==class[i],],2,var))
  }
  resultat = list(moyenne, colMeans(donnees, na.rm=T), ecart)
  names(resultat)=c("Cluster.Centers", "Average.point", "Cluster.std")
  resultat
}

stats = profils(df_quanti2, cutree(dendro,6))
(stats$Cluster.Centers-stats$Average.point)/stats$Cluster.std
##                     1           2           3           4           5
## Age         0.1529410 -0.43523214 -0.27919200  0.15646150   0.6252951
## MP         -0.1906594 -0.39128617  0.06414968  1.77726085   0.0458975
## Min        -0.0938412 -0.51897253 -0.06199317  1.06857425   0.6066571
## Goals      -1.7610120  0.57360448 -0.41959431  0.48962707        -Inf
## Shots      -1.8652715  1.41849226 -0.27154192  0.81917251 -31.4182650
## SoT        -2.1576776  1.31009069 -0.47627240  0.59127551 -23.7990409
## ShoDist    -0.1320647  0.59602631  0.92155687  1.06622398  -7.0973930
## PasTotCmp.  1.5226941 -0.98071110 -0.06178217 -0.85489446  -0.2845094
## PasAss     -1.7849701  1.50711016  0.41946359  2.45094457 -33.4373661
## PPA        -1.5599327  0.86513110  0.73393450  1.10465522 -76.0877507
## PasAtt      0.9086834 -1.07718561  0.29580446  0.25309763  -4.0460115
## CK         -4.6520946  0.56615250 -0.28743921  2.62035752        -Inf
## SCA        -1.7038483  1.93667563  0.69711822  2.01113332 -28.7108886
## GCA        -1.2624211  0.96915645  0.26240593  1.00027189 -14.3286989
## Tkl         0.3321414 -0.49400218  0.80977749  0.06281669 -35.5842202
## Clr         0.9998354 -3.54572427 -0.24153230 -1.59249879  -6.6597240
## Touches     0.9355639 -0.78375330  0.37563629  0.27008943  -5.5701489
## ToAtt      -1.5850203  2.15796265  0.25045560  0.24736027 -54.7487374
## Carries     0.6035681  0.02706120  0.09775671  0.08187295  -4.2619333
## CPA        -3.1142153  1.54577661 -0.11696467  0.32531115        -Inf
## Rec         0.6413114 -0.09959408  0.19527930  0.24565645  -5.8687239
## Crs        -1.9447467  0.63865239  0.38819666  2.45570744        -Inf
## Get_ball    0.9486269 -0.75503999  0.64983623  0.19236303 -14.9617874
## Crd         0.2575816  0.03498329  0.03974549 -0.24853372  -2.8891803
##                      6
## Age         0.18113583
## MP          0.21268990
## Min         0.02454072
## Goals       1.02173715
## Shots       1.94698054
## SoT         2.26384464
## ShoDist    -0.85027133
## PasTotCmp. -1.23151926
## PasAss      0.50903800
## PPA         0.14015274
## PasAtt     -2.99823686
## CK         -3.54921742
## SCA         0.40210148
## GCA         0.53696163
## Tkl        -2.31926099
## Clr        -1.39790127
## Touches    -2.80327729
## ToAtt       0.38650438
## Carries    -2.54761627
## CPA         0.70494188
## Rec        -1.90166280
## Crs        -2.21347927
## Get_ball   -3.03333409
## Crd        -0.42508805
plot(df_quanti.acp, choix="ind", habillage = "ind", col.hab=rainbow(6)[cutree(dendro,6)])

clusters <- cutree(dendro, 6)

# Créer le graphique ACP avec les clusters et sans les labels
df_pca <- data.frame(df_quanti.acp$ind$coord, cluster = as.factor(clusters))

# Créer le graphique PCA avec ggplot2 pour personnaliser les formes et les couleurs
ggplot(df_pca, aes(x = Dim.1, y = Dim.2, color = cluster)) +
  geom_point(size = 3)

Nous allons commencer par une analyse de la localisation des clusters :

Cluster 1 (Rouge) : Situé au centre et s’étendant horizontalement au milieu du graphique. Cluster 2 (Vert) : Situé en bas à gauche, formant un groupe compact. Cluster 3 (Jaune) : Situé dans la partie supérieure du milieu à droite du graphique, quelque peu dispersé. Cluster 4 (Cyan) : Réparti au milieu vers la droite du graphique. Cluster 5 (Rose) : Situé dans la partie moyenne-gauche du graphique. Cluster 6 (Bleu) : Situé principalement dans la partie inférieure du milieu du graphique.

Les clusters 1 (Rouge) et 5 (Rose) ont des points de données qui se chevauchent de manière significative dans la partie milieu-gauche du graphique. Cela indique que les données appartenant à ces clusters sont mélangées dans cette région, ce qui rend difficile la distinction claire entre les deux groupes. De même, il y a un chevauchement notable entre les clusters 1 (Rouge) et 4 (Cyan) vers le milieu-droit du graphique. Les points de ces deux clusters sont également mélangés, ce qui complique la séparation nette de ces groupes.

Les clusters 2 (Vert) et 6 (Bleu) sont plus distincts et moins entremêlés avec les autres clusters. Ils sont situés dans des régions du graphique où il y a peu ou pas de chevauchement avec les points de données des autres clusters. Cela signifie que les données de ces clusters sont plus facilement identifiables et séparables des autres groupes.

# Effectuer le k-means clustering avec k=6 classes
df.km <- kmeans(x.std, 6, nstart = 10)

# Extraire les coordonnées des individus de l'ACP
coord <- as.data.frame(df_quanti.acp$ind$coord)
coord$cluster <- as.factor(df.km$cluster)

# Créer le graphique PCA avec ggplot2
ggplot(coord, aes(x = Dim.1, y = Dim.2, color = cluster)) +
  geom_point(size = 3)

Ce graphique a été réalisé à partir de la méthode des k-means. L’objectif principal de la méthode des K-means est de partitionner un jeu de données en k clusters distincts. Chaque point de données est assigné au cluster dont le centroïde (le centre du cluster) est le plus proche. L’objectif est de minimiser la variance intra-cluster, c’est-à-dire de rendre les points de chaque cluster aussi similaires que possible tout en maximisant les différences entre les clusters. Les points centraux (centroïdes) sont initialement fixés aléatoirement, ce qui peut influencer les résultats finaux. Bien que la méthode des k-means et l’ACP aient des approches différentes pour le clustering, on remarque que nos 6 groupes d’individus sont, à quelques individus près, identiques.