diff --git a/module3/exo3/exercice_fr.Rmd b/module3/exo3/exercice_fr.Rmd index 7eece5e296bb586e88166aa8a263ca75b44c2b9e..a81485d4629d0d4c05996d904db33b7cd1e27b8c 100644 --- a/module3/exo3/exercice_fr.Rmd +++ b/module3/exo3/exercice_fr.Rmd @@ -1,33 +1,294 @@ --- -title: "Votre titre" -author: "Votre nom" -date: "La date du jour" -output: html_document +title: "Mesures de performance réseau" +author: "Arnaud Legrand" +date: "03/02/2015" +output: + html_document: + toc: true + theme: cosmo + highlight: tango --- +![C'est en forgeant qu'on devient forgeron!](http://www.luc-damas.fr/humeurs/images/forgeant-forgeron.jpg) -```{r setup, include=FALSE} -knitr::opts_chunk$set(echo = TRUE) +# Une première approche pour comprendre à quoi ressemble ce système +Dans le cadre de ces TPs, voici le genre de commandes shell qui peuvent être +utilisées pour collecter des mesures à moindre coût: + + ping -D liglab.imag.fr > liglab.log 2>&1 + ping -D liglab.imag.fr -s 20480 -i .2 + +On peut alors leur mettre un coup de grep et de sed pour les +reformater. Là, j'avais choisi de faire quelque chose d'un poil +robuste (en perl) et qui me rapporte les lignes non conformes à ce qui +est attendu. + + $#ARGV==1 or die "Usage: convert.pl -->'$#ARGV'"; + $input = $ARGV[0]; + $output = $ARGV[1]; + open(INPUT,$input) or die; + open(OUTPUT,"> $output") or die; + $l=; + print OUTPUT qw(time,size,name,ip,seq,ttl,delay)."\n"; + + while(defined($l=)) { + chomp($l); + if($l eq "") { last; } + if($l =~ /^\[(.*)\] (.*) bytes from (.*) \((.*)\): icmp_seq=(.*) ttl=(.*) time=(.*) ms$/) { + my($time,$size,$name,$ip,$seq,$ttl,$delay)=($1,$2,$3,$4,$5,$6,$7); + print OUTPUT (join(',',($time,$size,$name,$ip,$seq,$ttl,$delay))."\n"); + } else { print "---> $l\n"; } + } + +Quoi qu'il en soit, voici le genre de données que j'ai pu +récupérer. Si vous n'avez pas pu faire de mesures par vous même (ce +qui est dommage...), vous pouvez les utiliser... + +- [RICM4_EP_ping/stackoverflow.csv.gz](http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/stackoverflow.csv.gz) +- [RICM4_EP_ping/stackoverflow.log.gz](http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/stackoverflow.log.gz) +- [RICM4_EP_ping/google.csv.gz](http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/google.csv.gz) +- [RICM4_EP_ping/liglab.log.gz](http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/liglab.log.gz) +- [RICM4_EP_ping/google.log.gz](http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/google.log.gz) +- [RICM4_EP_ping/liglab.csv.gz](http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/liglab.csv.gz) +- [RICM4_EP_ping/liglab2.log.gz](http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/liglab2.log.gz) +- [RICM4_EP_ping/liglab2.csv.gz](http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/liglab2.csv.gz) + +## Analyses + +```{r} +library(ggplot2) +library(plyr) +``` + +Je prend liglab, une première série de mesures vers le serveur web du labo. + +```{r} +liglab<-read.csv("liglab.csv.gz",header=T); +df = liglab +``` + +Allons-y pour une première visualisation: + +```{r} +plot(df[names(df)%in% c("time","size","seq","delay")]); +``` + +Que voit-on ? + +* une seule taille utilisée +* le delay est vraiment très variable + +Regardons ça de plus près +```{r} +p = ggplot(data=df,aes(x=time-min(df$time),y=delay, color=size)) + geom_point(alpha=.3) +p +``` + +C'est à peu près stable dans le temps mais il y a l'air d'y avoir des aligements de points verticaux. + +Regardons, d'encore plus près... +```{r} +p + xlim(0,1000) +``` + +Il arrive qu'on ait des valeurs 2 à 3 fois plus grandes que les autres et ça arrive souvent en rafale. On a des séries de mesures qui peuvent être différentes du reste. Il faudra en tenir compte si on fait des expériences où certain paramètres (comme la taille) varient. + +Regardons ce que donne le jeu de données vers google +```{r} +google<-read.csv("google.csv.gz",header=T); +df = google +``` + +```{r} +plot(df[names(df)%in% c("time","size","seq","delay")]); +``` + +Encore une fois, une seule taille a été utilisée mais rien de surprenant de ce coté là. +Wow, par contre, niveau delay, c'est très différent cette fois ci. Ça n'est plus du tout stable dans le temps. Le comportement évolue franchemet au cours du temps et, ce de façon relativement lisse apparemment. Regardons de plus près. +```{r} +p = ggplot(data=df,aes(x=time-min(df$time),y=delay, color=size)) + geom_point(alpha=.3) +p +``` + +Ah, c'est lisse mais pas tant que ça. Il y a encore une autre échelle de temps qui fait apparaître des "dents" de scie. Regardons, d'encore plus près ? +```{r} +p + xlim(0,1000) +``` + +Et encore une fois, il arrive qu'on ait des valeurs 2 à 3 fois plus grandes que les autres et ça arrive souvent en rafale. On a des séries de mesures qui peuvent être différentes du reste et il faudra en tenir compte si on fait des expériences où certain paramètres (comme la taille) varient. + +# Allons plus loin et étudions l'influence de la taille des données +## Expériences + +Le plus naturel est certainement de faire quelque chose comme ça: + + while true ; do for i in 16 60 600 1600 ; do ping -c 2 -D liglab.imag.fr -s $i -i .2 | grep from; done ; done + +Seulement, vu qu'on peut avoir des rafales de mesures assez différentes des autres, on risque de ne pas arriver à savoir si les différences qu'on observe sont dûes à la taille ou à un bruit externe. Il vaut donc mieux randomiser les tailles de la façon suivante. L'approche suivante permet donc de se prémunir d'un certain nombre de biais et de collecter relativement rapidement des mesures (mettre le delay en dessous de .2 a souvent des conséquences facheuses et empèche de faire les mesures) + + while true ; do \ + export j=$(($RANDOM%2000)) ; \ + ping -c 1 -D liglab.imag.fr -s $j | grep from ; \ + sleep .2 ; \ + done > /tmp/liglab2.log + +J'ai mis 2000 comme taille max car pour des valeurs vraiment plus grosses, je me faisais dropper quasiment à chaque fois. Et comme google ne voulait plus de mes paquets de taille non standard, j'ai cherché d'autres serveurs. J'ai gardé liglab et j'ai remplacé google par stackoverflow. + +## Analyse de liglab +```{r} + liglab2<-read.csv("liglab2.csv.gz",header=T); + df = liglab2 +``` + +Regardons tout ça: +```{r} +plot(df[names(df)%in% c("time","size","seq","delay")]); ``` -## Quelques explications +Que voit-on ? -Ceci est un document R markdown que vous pouvez aisément exporter au format HTML, PDF, et MS Word. Pour plus de détails sur R Markdown consultez . +* size en fonction de time (graphe de coordonnées (2,1)): la size est bien indépendante de time. Pour bien faire, il faut vérifier que size est bien uniforme (on ne sait jamais) + ```{r} + hist(df$size) + ``` + +* delay en fonction de time (graphe de coordonnées (4,1)): le delay est vraiment très variable mais semble stable dans le temps. Il y a des points qui sortent vraiment du lôt (au delà de 100ms) mais ils sont peu nombreux. -Lorsque vous cliquerez sur le bouton **Knit** ce document sera compilé afin de ré-exécuter le code R et d'inclure les résultats dans un document final. Comme nous vous l'avons montré dans la vidéo, on inclue du code R de la façon suivante: +* delay en fonction de size (graphe de coordonnées (4,2)): il y a une rupture. Au delà d'environ 1400, le comportement est très différent. Ceci mis à part, il y a une variabilité telle qu'il est difficile de dire si la size est significative... -```{r cars} -summary(cars) +Regardons ça de plus près +```{r} +p = ggplot(data=df,aes(x=time-min(df$time),y=delay, color=size)) + geom_point(alpha=.3) +p ``` -Et on peut aussi aisément inclure des figures. Par exemple: +C'est à peu près stable dans le temps mais il y a encore une fois des paquets d'alignements verticaux. Ça va être conton à étudier. Je remarque aussi que les points clairs (ceux avec une size impotante) sont plutôt un peu plus vers le haut que les autres. Mais encore une fois avec une telle variabilité, ça va être difficile à mettre en évidence. +```{r} +p + xlim(0,1000) +``` + +Ah oui, là, on voit bien les rafales et il n'y a pas de raison qu'elles correspondent à une taille particulière puisque la taille est randomisée. Elles correspondent donc bien à des perturbations du réseau locales dans le temps. + +Bon, essayons déjà de séparer les "gros" des "petits" paquets. +```{r} +df$type=0; +df[df$size>1480,]$type=1; +ggplot(data=df,aes(x=size,y=delay, color=factor(type))) + geom_point(alpha=.3) +``` + +Ainsi, on peut les traiter à part lors de l'analyse. + +Je me souviens quand je faisais des mesures pour des petites tailles (64) et pour des tailles plus grosses (1000), je trouvais qu'on voyait la différence. Est-ce que c'est détectable. + +```{r} +summary(lm(data=df[df$type==0,],delay~size)) +``` + +Argh, si l'intercept et le coefficient pour size sont significativement différents de 0, on a un $R^2$ proche de 0. Il y a une variabilité énorme qu'on n'arrive pas à expliquer juste avec size. En même temps on le savait. Mettons la prédiction de la régression en regard des mesures. +```{r} +ggplot(data=df,aes(x=size,y=delay, color=factor(type))) + geom_point(alpha=.1) + geom_smooth(method="lm") +``` -```{r pressure, echo=FALSE} -plot(pressure) +Forcément avec autant de variabilité et une variabilité aussi asymétrique, notre régression est "trop haute". Moralement, on comprend bien qu'il y a un temps de propagation sur les liens et un temps d'attente dans les buffers et c'est cette dernière composante qui cause toute la variabilité et nous empèche de mesurer le temps de propagation sur les liens. Mais de temps, en temps, on arrive à ne pas faire la queue, nos paquets atteignent leur cible sans trop attendre. Du coup, une idée pourrait être de s'intéresser au bas de la courbe, aux plus petites valeurs... + +Allons-y: +```{r} +d = data.frame(size=c(),mindelay=c(),num=c()) +for(s in unique(df$size)) { + d = rbind(d,data.frame(size=s,mindelay=min(df[df$size==s,]$delay), + num=length(df[df$size==s,]$delay), + type=unique(df[df$size==s,]$type))) +} +``` + +Mais c'est lent... :) Si vous voulez faire sans boucle, la bonne façon de faire est d'utiliser plyr: +```{r} +library(plyr) +d = ddply(df,c("size"), summarize, mindelay=min(delay),num=length(delay),type=unique(type)) +``` + +Bref, une fois que c'est fait, voilà ce qu'on obtient: +```{r} +ggplot(data=d,aes(x=size,y=mindelay, color=factor(type))) + geom_point(alpha=.3) ``` -Vous remarquerez le paramètre `echo = FALSE` qui indique que le code ne doit pas apparaître dans la version finale du document. Nous vous recommandons dans le cadre de ce MOOC de ne pas utiliser ce paramètre car l'objectif est que vos analyses de données soient parfaitement transparentes pour être reproductibles. +Et ça, ça parait déjà, plus facile à étudier! :) Rajoutons la régression linéaire à ces points: +```{r} +ggplot(data=d,aes(x=size,y=mindelay, color=factor(type))) + geom_point(alpha=.3) + + geom_smooth(method="lm") +``` + +Nickel! Regardons quand même ce que disent les indicateurs des régressions linéaires: +```{r} +summary(lm(data=d[d$type==0,],mindelay~size)) +``` + +Joie et félicité. Deux paramètres bien significatifs avec une très faible variance, et un $R^2$ de 0.94! +Et maintenant, encore plus fort: +```{r} +l = lm(data=d,mindelay~size*factor(type)) +summary(l) +``` -Comme les résultats ne sont pas stockés dans les fichiers Rmd, pour faciliter la relecture de vos analyses par d'autres personnes, vous aurez donc intérêt à générer un HTML ou un PDF et à le commiter. +Je prend soin de préciser que type doit être considéré comme un facteur et pas comme un nombre. Et là, c'est très intéressant (attention, c'est un peu fin). Non seulement le $R^2$ est très faible (nos valeurs sont plus grandes quand on considère les gros paquets mais la variabilité n'a pas changé...) mais on voit que non seulement intercept, size et factor(type) sont significatifs et très précis mais en plus que size:factor(type) n'est absolument pas significatif. En gros, ça veut dire que la pente pour les petits et pour les gros paquets est la même... + +Si j'en crois ma régression, j'arrive donc à transmettre à une vitesse (en o/ms, c'est à dire en Ko/s) de: +```{r} +1/l[1]$coefficients[2] +``` + +## Analyse de stackoverflow +Bon, tentons de faire pareil avec stackoverflow. +```{r} + stack<-read.csv("stackoverflow.csv.gz",header=T); + df = stack +``` +Regardons tout ça: +```{r} +plot(df[names(df)%in% c("time","size","seq","delay")]); +``` +Que voit-on ? +* size ~ time : Indépendance de time et de size, c'est normal. +* delay ~ time : Aouch, une fois encore il y a une variabilité importante et des moments où ça se passe bien plus mal qu'à d'autres. +* delay ~ size : encore une fois, on retrouve ce phénomène des petits et des gros paquets. + +Bon, essayons déjà de séparer les "gros" des "petits" paquets. +```{r} +df$type=0; +df[df$size>1480,]$type=1; +ggplot(data=df,aes(x=size,y=delay, color=factor(type))) + geom_point(alpha=.3) +``` + +On arrive bien à séparer mais par contre, la variabilité est bizarre. La majorité des points sont à 110, 111, 112 ms. C'est beaucoup plus gros que ce que l'on avait tout à l'heure.... Si je prend les min comme j'avais fait avant, je risque de ne pas m'en sortir et il faudrait probablement utiliser une autre technique (régression de quantiles ?). :( + +Mais bon, allons quand même jusqu'au bout pour voir ce que ça donne. + +```{r} +d = ddply(df,c("size"), summarize, mindelay=min(delay),num=length(delay),type=unique(type)) +``` + +Bref, une fois que c'est fait, voilà ce qu'on obtient: +```{r} +ggplot(data=d,aes(x=size,y=mindelay, color=factor(type))) + geom_point(alpha=.2) + + geom_smooth(method="lm") +``` + +Mouif, en fait, c'est rigolo, là, on ne voit plus la distinction entre les gros et les petits (mis à part la couleur). + +Regardons quand même ce que disent les régressions linéaires: +```{r} +summary(lm(data=d[d$type==0,],mindelay~size)) +``` + +Bon, avec un $R^2$ de 0.004 on n'explique rien. On pourrait même ne plus considérer le type: +```{r} +ggplot(data=d,aes(x=size,y=mindelay)) + geom_point(alpha=.2) + + geom_smooth(method="lm") +``` +```{r} +l=lm(data=d,mindelay~size) +summary(l) +1/l[1]$coefficients[2] +``` -Maintenant, à vous de jouer! Vous pouvez effacer toutes ces informations et les remplacer par votre document computationnel. +De là à accorder du crédit à cette valeur... Franchement, je ne sais pas. On n'a vraiment fait qu'effleurer le problème. Pas facile de réduire la variance et d'avoir un modèle raisonnable pour tout ceci.