TP 2
L3 EURIA - UBO Pierre Ailliot
1 Préparation des données
1.1 Importation des données
data=read.csv("http://instruction.bus.wisc.edu/jfrees/jfreesbooks/Regression%20Modeling/BookWebDec2010/CSVData/UNLifeExpectancy.csv")
#head(data)
1.2 Nettoyage des données
Il est important de donner des noms aux individus pour pouvoir interpréter les graphiques (par exemple quand on regarde la position des individus dans le premier plan principal).
row.names(data)=data[,2] #pays = nom des lignes z=data[,-2]
str(data)
## 'data.frame': 185 obs. of 15 variables:
## $ REGION : int 4 7 1 6 3 3 7 8 8 7 ...
## $ COUNTRY : Factor w/ 185 levels "Afghanistan",..: 1 2 3 4 5 6 7 8 9 10 ...
## $ LIFEEXP : num 42.9 76.2 71.7 41.7 73.9 74.8 71.7 80.9 79.4 67.1 ...
## $ ILLITERATE : num 72 1.3 30.1 32.6 14.2 2.8 1 1 1 1.2 ...
## $ POP : num 25.1 3.2 32.9 16.1 0.1 38.7 3 20.3 8.3 8.4 ...
## $ FERTILITY : num 7.5 2.2 2.5 6.8 NA 2.4 1.3 1.8 1.4 1.7 ...
## $ PRIVATEHEALTH : num 3.7 3.7 1 0.4 1.4 5.3 4 3.1 2.5 2.7 ...
## $ PUBLICEDUCATION: num NA 2.9 NA 2.6 3.8 3.8 3.2 4.7 5.5 2.5 ...
## $ HEALTHEXPEND : int 19 339 167 38 516 1274 226 3123 3418 138 ...
## $ BIRTHATTEND : int 14 98 96 45 100 99 98 100 100 88 ...
## $ PHYSICIAN : int 19 131 113 8 17 301 359 247 338 355 ...
## $ SMOKING : int NA 60 32 NA NA 32 62 19 NA NA ...
## $ RESEARCHERS : int NA NA NA NA NA 720 NA 3759 2968 NA ...
## $ GDP : num 7.3 8.4 102.3 32.8 0.9 ...
## $ FEMALEBOSS : int NA NA NA NA 45 33 NA 37 27 NA ...
2 Analyse descriptive
2.1 Valeurs manquantes
perc=apply(is.na(z),2,sum)*100/nrow(z)
barplot(perc,las=2) #pourcentage de na par variable
perc=apply(is.na(z),1,sum)*100/ncol(z) #pourcentage de na par pays hist(perc)
2.2 Lois univariées
Le boxplot fait ressortir que les variables ont des échelles très différentes. Nous verrons que cela a un impact sur l’ACP si les variabes ne sont pas normalisées.
boxplot(z)
On peut faire des boxplots avec des échelles différentes pour chaque variable.
par(mfrow=c(2,ncol(z)/2)) for (i in 1:ncol(z)){
boxplot(z[,i],main=names(z)[i]) }
La variable région étant qualitative, on peut faire un cammenbert.
pie(table(z$REGION))
2.3 Matrice de corrélation
Il faut enlever les valeurs manquantes. On peut utiliser la fonction na.omit (regarder l’aide de la fonction pour comprendre ce que fait cette fonction). La variable qualitative ‘REGION’ est aussi enlevée.
Cette matrice permet d’analyser les relations (linéaires) entre les couples de variables.
Par exemple, l’espérance de vie est corrélée positivement avec les variables qui augmentent avec le niveau de vie des pays (“PUBLICEDUCATION” “HEALTHEXPEND” “BIRTHATTEND” “PHYSI- CIAN” “RESEARCHERS” “GDP”) et négativement avec les variables “ILLETERATE” FERTILITY"
et “SMOKING”.
library(corrplot)
## Warning: package 'corrplot' was built under R version 3.4.4
## corrplot 0.84 loaded
corrplot(cor(na.omit(z[,-1])))
2.4 Histogramme de l’espérance de vie
On observe une forte disparité entre l’espérance de vie des pays.
hist(z$LIFEEXP)
2.5 Analyse bivariée
R=cor(na.omit(z[,-1])) which.max(R[1,-1])
## HEALTHEXPEND
## 6
“HEALTHEXPEND” est la variable la plus corrélée avec “LIFEEXP”.
plot(z$HEALTHEXPEND,z$LIFEEXP)
La rela- tion n’est pas linéaire (et donc le coefficient de corrélation n’est pas adapté pour décrire la dépendance entre les deux variables).
3 ACP
3.1 Première ACP
3.1.1 Calculer les pourcentages d’inerties expliqués par le premier axe principal puis par le premier plan principal. Discuter.
La fonction PCA peut être utilisée avec des valeurs manquantes. Il est aussi possible d’enlever les valeurs manquantes avant de faire l’ACP.
Ici j’ai choisi d’enlever les pays avec des valeurs manquantes avec na.omit pour simplifier les inter- prétations (on a moins d’individus et donc les représentations graphiques sont moins chargées). Les résultats sont différents si on garde tous les pays, cf question 3.4.
La variable qualitative “REGION” est enlevée avant de faire l’ACP.
Seulement 55% d’interie est expliquée par le premier plan principal. Les individus ne sont pas très bien représentés dans le premier plan principal.
X=na.omit(z[,-1]) #retire la première colonne et NA library(FactoMineR)
fit=PCA(X,graph=FALSE)
par(mfrow=c(1,2))
barplot(fit$eig[,1]/sum(fit$eig[,1]),las=2) #pourcentage d'inertie totale expliquée par les composantes principales
barplot(100*cumsum(fit$eig[,1])/sum(fit$eig[,1]),las=2) #pourcentage d'inertie totale expliquée par les sous-espaces principaux
fit$eig[1:2,]
## eigenvalue percentage of variance cumulative percentage of variance
## comp 1 5.101070 39.23900 39.2390
## comp 2 2.108952 16.22271 55.4617
3.1.2 Visualiser les coordonnées des individus dans le premier plan principal ainsi que le cercle des corrélations. Proposer une interprétation.
La première composante principale, qui explique 39% de l’inertie totale, est corrélée positivement avec les variables “LIFEEXP”, “HEALTHEXPEND” , “BIRTHATTEND”, “RESEARCHERS”,
“PUBLICEDUCATION”. . . et négativement avec les variables “ILLETARATE”,“FERTILITY” et
“SMOKING”. A droite on retrouve donc les pays avec un système de santé publique développé et une espérance de vie importante (Japon, Canada, Europe occidentale,. . . ) aux pays avec des forts taux de natalité et d’illétrisme et une faible espérance de vie (Népal, Bangladesh,. . . ).
La deuxième composante principale, qui explique 16% de l’inertie totale, est corrélée positivement avec les variables “GDP” et “PRIVATEHEALTH”. On retrouve donc en haut du premier plan principal les pays avec un PIB important et un système de santé privé important (Etats-Unis).
Certaines variables sont mal représentées dans le premier plan principal (celles qui sont loin du cercle
unité comme POP par exemple qui est lié au quatrième axe principal, cf question 3.8).
par(mfrow=c(1,2)) fit=PCA(X)
###Calculer les contributions des individus aux différentes composantes. Existe-t-il des in- dividus qui apportent une contribution importante à l’un des deux premiers axes principaux ? Discuter.
Le Bangladesh et le Népal ont une forte contribution sur le premier axe principal.
Les Etats-Unis a une forte contribution sur le deuxième axe (presque 50%). Cette contribution semble excessive : on pourrait refaire l’ACP après avoir enlevé cet individu.
par(mfrow=c(2,1))
barplot(fit$ind$contrib[,1],las=2) barplot(fit$ind$contrib[,2],las=2)
3.1.3 Calculer les quantités COS2 et discuter de la qualité de la représentation des individus sur le premier axe principal puis sur le premier plan principal. Discuter.
Certains individus sont mal représentés sur le premier plan principal. L’individu le moins bien représenté est l’Uruguay. Il faut faire attention quand on interpréte la position de ces individus mal représentés.
par(mfrow=c(2,1))
QTL1=fit$ind$cos2[,1] #calcul de la qualité de la représentation sur le premier axe principal barplot(QTL1,las=2)
QTL2=apply(fit$ind$cos2[,1:2],1,sum) #calcul de la qualité de la représentation sur le premier plan principal barplot(QTL2,las=2)
3.2 Influence du choix de la métrique : effectuer une ACP sans nor- maliser les variables. Interpréter les résultats obtenus et comparer avec l’ACP normée.
Si on ne normalise pas les variables, celles qui ont la plus forte variance (cf question 2.2) ressortent de l’analyse.
par(mfrow=c(1,2))
PCA(X,scale.unit=FALSE)
## Warning in arrows(0, 0, coord.var[v, 1], coord.var[v, 2], length = 0.1, :
## zero-length arrow is of indeterminate angle and so skipped
## Warning in arrows(0, 0, coord.var[v, 1], coord.var[v, 2], length = 0.1, :
## zero-length arrow is of indeterminate angle and so skipped
## Warning in arrows(0, 0, coord.var[v, 1], coord.var[v, 2], length = 0.1, :
## zero-length arrow is of indeterminate angle and so skipped
3.3 Remplacer le produit intérieur brut (variable GDP) par le PIB par habitant puis effectuer à nouveau l’ACP. Comparer, discuter.
Le PIB par habitant refléte le niveau de vie des habitants et pas la richesse totale du pays. La Norvège est le pays avec le PIB/habitant le plus élevé alors que les Etats-Unis est le pays avec le PIB le plus élevé. La chine qui a PIB global élevé a un PIB/habitant plutôt faible.
X2=XX2$GDP=X$GDP/X$POP which.max(X2$GDP)
## [1] 32
La fonction fviz_pca_biplot du package factoextra permet de tracer le nuage de point et le cercle des corrélations sur le même graphique. Selon le nombre d’individus et de variables, cela peut être plus simple à interpréter.
fit=PCA(X2,graph = FALSE) library("factoextra")
## Warning: package 'factoextra' was built under R version 3.4.4
## Loading required package: ggplot2
## Welcome! Related Books: `Practical Guide To Cluster Analysis in R` at https://goo.gl/13EFCZ
fviz_pca_biplot(fit) #biplot
Le pour- centage d’inertie expliquée par le premier plan principal est légérement supérieur à celui de l’ACP sans normaliser le PIB. Le cercle des corrélation et la position des individus change lorsqu’on normalise le PIB.
On peut identifier quatre “groupes” de variables. Un premier groupe (“PUBLICEDUCATION”,
“HEALTHEXPEND”,“GDP”,. . . ) qui est lié à la richesse des pays et qui s’oppose à “SMOKING”. Le troisième groupe de variables semble lié à la place des femmes dans la société (“FEMALEBOSS”,
“BIRTHATTEND”) et s’oppose à (“FERTILITY” et “ILLETERATE”). La position des différents pays dans ce plan semble aussi interprétable.
3.4 Refaire l’ACP après avoir enlevé les individus avec des valeurs man- quantes (on pourra utiliser la fonction na.omit). Comparer, dis- cuter.
Ici, contrairement à ce qui est demandé, l’ACP est faite SANS enlever les valeurs manquantes (car j’avais choisi de les enlever dans les questions précédentes). Le message “Missing values are imputed by the mean of the variable” s’affiche. Cela signifie que, par défaut, les valeurs manquantes sont remplacées par la valeur moyenne de la colonne (c’est à dire des 0 sur le tableau centré). Cette méthode peut conduire à des ‘biais’ importants pour les individus/variables avec beaucoup de valeurs manquantes et doit donc être utilisée avec précaution.
A noter aussi que les graphiques sont plus difficiles à interpréter car il y a plus d’individus.
fit=PCA(z[,-1],graph = FALSE)
## Warning in PCA(z[, -1], graph = FALSE): Missing values are imputed by the
## mean of the variable: you should use the imputePCA function of the missMDA
## package
fviz_pca_biplot(fit)
3.5 Refaire l’ACP en incluant la variable LIFEEXP comme variable sup- plémentaire. Comparer, discuter.
Je considère à nouveau le jeu de données sans valeur manquante et avec le PIB normalisé. Les axes sont peu modifiés lorsque LIFEEXP est mise en variable supplémentaire.
fit=PCA(X2,graph = FALSE,quanti.sup=1) fviz_pca_biplot(fit)
3.6 Refaire l’ACP en incluant la variable REGION comme variable sup- plémentaire (avec “quali.sup=. . . ” dans la fonction PCA). Com- parer, discuter.
X3=na.omit(z)
X3$GDP=X3$GDP/X3$POP
X3$REGION=as.factor(X3$REGION) par(mfrow=c(1,2))
PCA(X3,quali.sup=1)
Ci-dessous une représentation alternative avec fviz_pca_biplot : chaque groupe est représenté par une couleur différente.
Ce graphique peut permette d’interpréter les différents groupes de pays.
library("factoextra")
fviz_pca_biplot(fit,habillage=1) #biplot
3.7 Refaire l’ACP en rajoutant des poids proportionnels à la population aux différents pays. Comparer, discuter.
L’ajout de poids renforce l’influence des pays avec une population importante (Chine, USA,. . . ) dans l’analyse.
fit=PCA(X2,graph = FALSE,row.w=X2$POP) library("factoextra")
fviz_pca_biplot(fit) #biplot
3.8 Visualiser les coordonnées des individus dans le plan engendré par les axes principaux 3 et 4 ainsi que le cercle des corrélations. Pro- poser une interprétation.
Les axes 3 et 4 expliquent environ 10% de l’inertie totale chacun. L’axe 3 est corrélé positivement avec les variables “PRIVATEHEALTH” et “FEMALEBOSS”. L’axe 4 est lié à la variable “POP”.
Les 4 premiers axes principaux expliquent 79% de l’inertie totale, ce qui est généralement considéré comme une valeur acceptable à partir de laquelle on peut supposer que les individus sont bien représentés.
Les axes 3 et 4 apportent une information complémentaire à celle apportée par les axes 1 et 2.
fit=PCA(X2,axes=c(3,4))
fviz_pca_biplot(fit,axes=c(3,4)) #biplot
4 Classification
4.1 Réaliser une CAH avec le saut de Ward. Discuter le choix du nombre de classes et représenter les classes obtenues dans le premier plan principal.
J’ai choisi de travailler sur le jeux de données sans valeurs manquantes et avec la variable “PIB par habitant”
d=dist(X2)
cah=hclust(d,method='ward.D') #utilisation du saut de ward plot(cah)
Pour aider le choix du nombre de classes, on peut tracer la mesure de dissimilarité (saut de Ward ici) en fonction du nombre de classes. Cela correspond à la ‘hauteur des branches’ du dendrogramme.
barplot(sort(cah$height,decreasing=TRUE))
On voit que le saut est important entre la troisième valeur et la quatrième valeur sur ce graphique, c’est à dire quand on passe de 4 à 3 classes. Un choix possible est donc de considérer une classification en 4 classes (un saut important correspond au regroupement de deux classes éloignées). On vérifie sur le dendrogramme que cela correspond bien à un saut important dans la hauteur des branches.
Par contre, un regroupement en 3 classes ne semble pas approprié ici. Evidemment, si vous avez choisi un autre jeux de données (PIB total du pays et/ou données avec des valeurs manquantes), le choix du nombre de classe sera différent.
memb <- cutree(cah, k = 4) #coupe de dendograme à 4 classes fit=PCA(X2,graph=FALSE) #ACP
plot(fit$ind$coord[,1],fit$ind$coord[,2])
#individu dans le premier plan principal
text(fit$ind$coord[,1],fit$ind$coord[,2],row.names(X),col=memb)
Les classes correspondent à des groupes de pays proches dans le premier plan principal. On peut utiliser ce graphique pour interpéter les différents groupes de pays identifiés (groupe des pays riches, . . . ). On peut remarquer cependant que certaines classes sont “mélangées” dans le premier plan principal. Une explication possible est le premier plan principal représente “seulement” 60% de l’inertie totale et donc que la projection sur ce plan déforme le nuage de point initial (deux points proches dans le premier plan principal peuvent être éloignés dans l’espace de départ avec toutes les variables).
On peut utiliser fviz_pca_biplot pour obtenir une représentation graphique plus complète (variables, individus et classes sur le même graphique). Vous devez être capable d’interpréter le graphique ci-dessous.
fviz_pca_biplot(fit,habillage=as.factor(memb))
4.2 Discuter le choix du saut : quelle est l’influence sur les classes obtenues?
Il suffit de changer l’argument method de la fonction hclust. On voit sur cet exemple qu’on obtient des classes très différentes en changeant la mesure de dissimilarité.
Par définition, la méthode “min” permet de bien reconstituer les classes filiformes, mais elles peuvent contenir des éléments très éloignés les uns des autres.
cah=hclust(d,method='single') #saut minimum
memb <- cutree(cah, k = 4) #coupe de dendograme à 4 classes plot(fit$ind$coord[,1],fit$ind$coord[,2])
#individu dans le premier plan principal
text(fit$ind$coord[,1],fit$ind$coord[,2],row.names(X),col=memb)
La méthode “max” au contraire, en évitant de constituer des classes contenant des éléments éloignés, donne des classes plus “compactes”.
cah=hclust(d,method='complete') #saut minimum
memb <- cutree(cah, k = 4) #coupe de dendograme à 4 classes plot(fit$ind$coord[,1],fit$ind$coord[,2])
#individu dans le premier plan principal
text(fit$ind$coord[,1],fit$ind$coord[,2],row.names(X),col=memb)
4.3 Tester la fonction HCPC. Combien de classes cette fonction propose de conserver?
L’option nb.clust=-1 enlève le choix inteactif du nombre de classes avec la souris et permet d’éxécuter la commande dans Rmarkdown. HCPC propose de garder 3 classes.
Avez vous regardé l’aide de la fonction HCPC? Quel algorithme est utilisé? Pourquoi obtient-on des résultats différents par rapport à la question 4.1? Remarque : la méthode implémentée par défaut dans la fonction HCPC correspond à l’option method = “ward.D2” de hclust.
res=PCA(X2)
HCPC(res,nb.clust=-1)
4.4 Réaliser une classification avec la méthode des moyennes mobiles (initialisation aléatoire). Est-ce que les résultats changent lorsqu’on exécute plusieurs fois l’algorithme avec une initialisation aléatoire?
Si on répète plusieurs fois le code ci-dessous, on peut voir que la composition des classes change légérement.
NB. Le numéro des classes est arbitraire et il est donc attendu, par exemple, que la classe 1 obtenue lorsqu’on lance l’algorithme une première fois devienne la classe 2 lorsqu’on relance l’algorithme.
k=4 #nombre de classes
cl=kmeans(X2,k) #initialisation aléatoire plot(fit$ind$coord[,1],fit$ind$coord[,2])
text(fit$ind$coord[,1],fit$ind$coord[,2],row.names(X),col=cl$cluster)
4.5 Exécuter l’algorithme de consolidation.
cah=hclust(dist(X2),method="ward.D") #CAH memb <- cutree(cah, k =4)
centers=matrix(0,nrow=k,ncol=ncol(X))
for (l in 1:k){ #centre de graivté des classes centers[l,]=apply(X2[memb==l,],2,mean)
}
cl=kmeans(X2,centers) #initialisation kmeans avec CAH
#comparaison CAH et CAH+k-means par(mfrow=c(1,2))
plot(fit$ind$coord[,1],fit$ind$coord[,2],main='CAH')
text(fit$ind$coord[,1],fit$ind$coord[,2],row.names(X2),col=memb) plot(fit$ind$coord[,1],fit$ind$coord[,2],main='kmeans')
text(fit$ind$coord[,1],fit$ind$coord[,2],row.names(X2),col=cl$cluster)