Exploration de données

Nous allons examiner dans cette section quelques unes des commandes de R, numériques ou graphiques, destinées à aider l'utilisateur à examiner ses données. Ces commandes sont très utiles pour mettre en évidence de manière descriptive certaines particularités des données. Ils permettent d'avoir une première impression d'ensemble sur les données. Les résultats numériques et graphiques obtenus aident beaucoup au choix de modèles et aux hypothèses que l'on sera amené à formuler pour poursuivre une étude statistique. Nous avons déjà remarqué que R est capable de distinguer des données de type différent, en particulier des données de type numérique et de type catégoriel. Les méthodes numériques et graphiques pour décrire un ensemble de données dépendent de leur type.

Résumés numériques

R contient une multitude de fonctions pour calculer des fonctions statistiques de base sur des échantillons de données, qu'elles soient numériques ou catégorielles. Pour des données numériques, le tableau suivant résume les plus importantes :

Résumés numériques
mean() moyenne aréthmétique
median() médiane
max plus grande valeur
min plus petite valeur
quantile() quantiles de l'échantillon
var() variance
sd() écart-type
Ces fonctions utilisent un ou plusieurs vecteurs numériques pour argument; de plus, en général, elles peuvent s'appliquer sur toutes les composantes d'un data.frame lorsque ce dernier est numérique et donné comme argument. À titre d'exemple d'utilisation de ces fonctions, considérons l'ensemble des données enregistré comme data.frame dans R sous le nom mtcars. Un appel d'aide mtcars permet d'obtenir un description détaillée des données. En résumé, cette base de données contient les mesures de 11 variables liées à l'aspect et aux performances d'un ensemble de 32 voitures (modèles 1973-1974) :

data(mtcars)
attach(mtcars) 
mtcars # affiche le contenu suivant
Mazda RX4
Mazda RX4 Wag Datsun 710 Hornet 4 Drive Hornet Sportabout ...
 # load in dataset
 # add mtcars to search path
 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
. . .
Ce dataframe contient des variables numériques continues (e.g. mpg, disp, wt)) et discrètes, (e.g. geai, carb, cil)). Pour les numériques, on peut calculer par exemple

mean(hp)
var(mgp)
quantile(qsec, probe=c(.2,.8)) # quantiles d'ordre 0.2 et 0.8 de qsec
cor(wt,mpg) # correlation entre poids et consommation
Bien évidement, calculer une moyenne ou un écart-type sur un échantillon de valeurs d'une variable catégorielle n'a pas de sens (et même si elle est discrète, sa moyenne peut ne pas être sensée). De telles données sont en général décrites par des tables ou encore par des tracés graphiques que nous examinerons plus tard. Par exemple :
 > table(cyl)
 cyl
 4  6  8 
 11 7 14
permet de voir que 11 des 32 véhicules ont 4 cylindres, 7 en ont 6 et 14 en ont 8. On peut transformer ces comptages en fréquences en divisant les entrées du tableau par le nombre total des observations :
> table(cyl)/length(cyl)
cyl
      4       6       8 
0.34375 0.21875 0.43750
Résumés graphiques Pour représenter une variable discrète ou catégorielle ne prenant qu'un nombre fini de valeurs distinctes on utilise un diagramme en bâtons. Lorsque la variable est catégorielle il est plus adéquat de tracer le diagramme en bâtons pour la table qui lui est associée. On pourra demander l'aide en ligne ?barplot pour voir comment on peut changer la couleur ou ajouter des titres. Essayez par exemple :
layout(c(1,2),2,1)
{barplot(table(cyl), col="red",
         main="Diagramme en batons des comptages")}
{barplot(table(cyl)/length(cyl), col="red", 
         main="Diagramme en batons des fréquences")}
Pour des données numériques continues on utilise l'histogramme. Les données sont réparties en classes disjointes et le nombre d'éléments (ou la fréquence relative) de chaque classe est graphiquement représentée, comme pour les diagrammes en bâtons pour les variables catégorielles, sauf que les bâtons se touchent. La hauteur de chaque rectangle est égale au nombre d'éléments présent dans la classe alors que lorsque l'on trace l'histogramme des fréquences, la hauteur est proportionnelle à la fréquence relative de sorte que la surface totale de la fonction constante par morceau ainsi tracée soit égale à 1, une propriété qui deviendra familière lorsque l'on étudiera les lois de probabilité usuelles plus tard. Généralement on choisit un nombre $ x_0$ (usuellement appelé origine de l'histogramme) et une longueur positive $ b$ appelée pas puis on partitionne l'axe réel en intervalles disjoints :

$\displaystyle \cdots \cup [x_0-2b,x_0-b[ \cup [x_0-b,x_0[ \cup [x_0,x_0 +b) \cup
[x_0 +b,x_0 +2b) \cup \cdots$

Pour l'histogramme des probabilités, sur chaque intervalle $ I_j =
[x_0 + jb, x_0 + (j + 1)b[$ on trace un rectangle de hauteur $ h =
\alpha n_j/n$$ n$ est le nombre total de données dans l'échantillon, $ n_j$ le nombre de données dans l'intervalle $ I_j$, le coefficient de proportionnalité $ \alpha>0$ étant choisi de telle sorte que la surface totale de la somme des rectangles soit 1. Il est à noter que le mot origine peut prêter à confusion car il ne signifie pas que l'histogramme démarre à ce point. Il donne plutôt un point de référence à partir duquel les intervalles de la subdivision seront calculés. La fonction permettant de tracer un histogramme dans R est hist(). Lisez l'aide par help(hist). L'argument breaks spécifie le nombre de classes de l'histogramme. Une valeur trop petite ou trop grande donne une représentation peu informative de la distribution. Par défaut R prend comme origine $ x_0$ le minimum des données et utilise la règle de Sturges avec pour nombre de classes la partie entière de $ \log_2(n)+1$, $ n$ étant la longueur de l'échantillon. Il existe d'autres méthodes pour trouver le pas optimal que nous ne détaillerons pas ici. Afin de voir (figure 6) la sensibilité des histogrammes en fonction de leurs paramètres, regardons de près les données de la base de données faithful qui est un jeu de données bimodales célèbre contenant deux variables : les temps d'éruptions (en minutes) et les temps d'attente entre deux éruptions successives du Geyser «Old Faithful».

data(faithful)
attach(faithful) # on charge les données
par(mfrow=c(1,2))
hist(eruptions,breaks=28,freq=F,col=0,xlab="",main="")
mtext("Eruption(min)",side=1,line=2)
mtext("(a) 18 classes",side=3,line=2,cex=.75)
hist(eruptions,breaks=12,freq=F,col=0,xlab="",main="")
mtext("Eruption(min)",side=1,line=2)
mtext("(b) 12 classes",side=3,line=2,cex=.75)

Figure 6: Sensibilité de l'histogramme au nombre de classes
\includegraphics[width=10cm]{densite1}

Pour se rendre compte de la sensibilité de l'histogramme au choix de l'origine, nous allons simuler un jeu de données bimodales et tracer les histogrammes pour des choix divers de l'origine $ x_0$ (voir figure 7).

number<-rbinom(1,50,.5)
mixture<-rnorm(50) 
mixture[1:number]<-mixture[1:number]+3 # on genère les donnees
par(mfrow=c(3,2))
hist(mixture,xlab=" ",breaks=-2.13:4.87,col=0,freq=F)
hist(mixture,xlab=" ",breaks=-2.33:5.67,col=0,freq=F)
hist(mixture,xlab=" ",breaks=-2.42:5.58,col=0,freq=F)
hist(mixture,xlab=" ",breaks=-2.53:5.47,col=0,freq=F)
hist(mixture,xlab=" ",breaks=-2.6:5.4,col=0,freq=F)
hist(mixture,xlab=" ",breaks=-3.1:4.9,col=0,freq=F)

Figure 7: Variabilité de l'histogramme en fonction de l'origine
\includegraphics[width=10cm]{densite2}

L'estimation lisse de la densité permet de corriger les défauts de l'histogramme. L'une des raisons du manque d'efficacité de l'histogramme à représenter une densité continue est la rigidité de ses classes. La hauteur d'un rectangle est seulement fonction du nombre de données contenues dans sa base sans tenir compte de leur répartition sur cet intervalle. Ce problème disparaît si on laisse les intervalles varier avec les données. L'idée de départ de l'estimation par noyau est de placer un rectangle de taille fixe $ 1/n$ autour de chaque point pour être sûr que si plusieurs rectangles se chevauchent on les empile de manière à ce que l'aire totale soit toujours égale à 1. On aborde là le domaine de la statistique non paramétrique sur lequel nous ne nous attarderons pas dans ce document. Toutefois on utilisera souvent une estimation graphique de la densité avec la commande density(). Le choix de la taille de la fenêtre dans l'estimation par noyau est très difficile et certaine règle sont définies dans R (on pourra les consulter avec une aide en ligne sur la fonction density()) . Ainsi par exemple pour les données d'éruption dont nous avons tracé l'histogramme on obtient (voir figure 8) en utilisant le règle de Sether et Jones sj et un noyau gaussien :

 
d <- density(faithful$eruptions, bw = "sj")
plot(d, main="Estimation par noyau de la densité")

Figure 8: Estimation par méthode du noyau
\includegraphics[width=10cm]{densite3}

L'impression donnée par le tracé de la figure 8 est analogue à celle que nous avions obtenue avec le tracé de l'histogramme. La densité inconnue est probablement bimodale et assez lisse.

Le diagramme en boîte ou «à moustaches» (box plot en anglais) permet de résumer graphiquement les données de manière plus succinte. On peut de manière très rapide apprécier la symétrie de la distribution des données et la présence de données suspectes. Dans son utilisation la plus simple un diagramme à moustaches est une boîte rectangulaire délimitée par un côté (le quartile d'ordre 0.25), une barre découpant le rectangle en la médiane des données, l'autre côté étant situé sur le quartile d'ordre 0.75. Les moustaches s'étendent du min au max des données, avec la convention de les rétrécir à une longueur égale à 1,5 fois celle du rectangle. Tout point au-delà est indiqué par un tracé ponctuel. Par exemple, les commandes suivantes produisent le diagramme de la figure 9 :

boxplot(eruptions,main="éruptions",horizontal=TRUE)

Figure 9: Diagramme à moustaches
\includegraphics[width=10cm]{boxplot1}
Ce tracé montre que la distribution de la variable éruptions n'est pas symétrique. Elle est chargée à gauche.
Il peut être intéressant de comparer deux distributions en traçant conjointement les box-plot de chacune d'elle. Par exemple on pourra tracer les box-plot des variables éruptions et wt du dataframe faithful avec la commande :

boxplot(faithful,main="Données faithful",horizontal=TRUE)

Figure 10: Deux diagrammes en boîte
\includegraphics[width=10cm]{boxplot2}

Une autre manière d'examiner la distribution des valeurs d'une variable est de tracer sa fonction de répartition empirique. Cette dernière est calculée à l'aide de la commande ecdf(). Par exemple :

 
f<-ecdf(eruptions)
plot(f, main="Répartition empirique",cex=0.5)
produit la figure 11.
Figure 11: Fonction de répartition empirique
\includegraphics[width=7cm]{ecdf1}


Nous n'avons illustré que quelques unes des fonctions graphiques de base et surtout uniquement pour des cas unidimensionnels. Pour les cas multi-dimensionnels on pourra aussi utiliser les fonctions suivantes.


Autres fonctions graphiques
pairs() trace tous les couples des variables
persp() tracé 3D en perspective et en couleur
pie() diagramme circulaire (cmembert)
qqplot() quantile-quantile pour comparer deux distributions
ts.plot() tracé de séries chronologiques

data(mtcars)
pairs(mtcars[,-c(2,7,8,9,10,11)])
produit la matrice de tracés de la figure 12.

Figure 12: Matrice de tracés
\includegraphics[width=7cm]{paires}


         © UJF Grenoble, 2011                              Mentions légales