# 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)
# 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
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)
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.
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.
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.
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é.
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.
# 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.