Objectif de l’étude

Un modèle simple et fréquemment utilisé pour décrire la performance d’une connexion de réseau consiste à supposer que le temps d’envoi T pour un message dépend principalement de sa taille S (nombre d’octets) et de deux grandeurs propres à la connexion : la latence L (en secondes) et la capacité C (en octets/seconde). La relation entre ces quatre quantités est T(S) = L + S/C. Ce modèle néglige un grand nombre de détails. D’une part, L et C dépendent bien sûr du protocole de communication choisi mais aussi dans une certaine mesure de S. D’autre part, la mesure de T(S) comporte en général une forte composante aléatoire. Nous nous intéressons ici au temps moyen qu’il faut pour envoyer un message d’une taille donnée.

Notre objectif est d’estimer L et C à partir d’une série d’observations de T pour des valeurs différentes de S.

Préparation des données

Nous disposons de deux bases de données que voici:

  1. Le premier jeu de données examine une connexion courte à l’intérieur d’un campus : http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/liglab2.log.gz

  2. Le deuxième jeu de données mesure la performance d’une connexion vers un site Web éloigné assez populaire et donc chargé : http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/stackoverflow.log.gz

Les url ci-dessus conduisent à deux fichiers sous format compressé qui contiennent la sortie brute de l’outil ping qui a été exécuté dans une boucle en variant de façon aléatoire la taille du message. Chaque ligne a la forme suivante:

[1421761682.052172] 665 bytes from lig-publig.imag.fr (129.88.11.7): icmp_seq=1 ttl=60 time=22.5 ms

Au début, entre crochet, se trouve la date à laquelle la mesure a été prise, exprimée en secondes depuis le 1er janvier 1970. La taille du message en octets est donnée juste après, suivie par le nom de la machine cible et son adresse IP, qui sont normalement identiques pour toutes les lignes à l’intérieur d’un jeu de données. À la fin de la ligne, nous trouvons le temps d’envoi (aller-retour) en millisecondes. Les autres indications, icmp_seq et ttl, n’ont pas d’importance pour notre analyse.

Téléchargement des données

Les fichiers sous format compressé ne peuvent pas être directement lu par le logiciel R. Pour ce fait, nous allons télécharger le format csv qui est facilement lu par R en remplaçant au niveau des url l’expression “log.gz” par “csv”

liglab2DataUrl <- "http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/liglab2.csv"
stackoverflowDataUrl <- "http://mescal.imag.fr/membres/arnaud.legrand/teaching/2014/RICM4_EP_ping/stackoverflow.csv"

liglab2Data <- read.csv(liglab2DataUrl)
stackoverflowData <- read.csv(stackoverflowDataUrl)

Sauvegarde des données dans le fichier local et chargement éventuel

Pour nous protéger contre une éventuelle disparition ou modification des données sur le site web de téléchargement, nous faisons une copie locale de ces jeux de données que nous préservons avec notre analyse. Il est inutile et même risquée de télécharger les données à chaque exécution, car dans le cas d’une panne nous pourrions remplacer nos données par un fichier défectueux. Pour cette raison, nous téléchargeons les données seulement si la copie locale n’existe pas.

Sauvegarde des données dans le fichier local

write.csv(liglab2Data,"liglab2.csv")
write.csv(stackoverflowData,"stackoverflow.csv")

Chargement éventuel des données

     1. Premier jeu de données
liglab2 = "liglab2.csv"
if (!file.exists(liglab2)) {
    download.file(liglab2DataUrl, liglab2, method="auto")
}
liglab2Data <- read.csv("liglab2.csv")
     2. Deuxième jeu de données
stackoverflow = "stackoverflow.csv"
if (!file.exists(stackoverflow)) {
    download.file(stackoverflowDataUrl, stackoverflow, method="auto")
}
stackoverflowData <- read.csv("stackoverflow.csv")

Visualisation des données

Regardons ce que nous avons obtenu:

     1. Premier jeu de données
     Visualisation des premières lignes
head(liglab2Data)
##   X       time size               name          ip seq ttl delay
## 1 1 1421761682 1373 lig-publig.imag.fr 129.88.11.7   1  60 21.20
## 2 2 1421761683  262 lig-publig.imag.fr 129.88.11.7   1  60 21.20
## 3 3 1421761683 1107 lig-publig.imag.fr 129.88.11.7   1  60 23.30
## 4 4 1421761683 1128 lig-publig.imag.fr 129.88.11.7   1  60  1.41
## 5 5 1421761683  489 lig-publig.imag.fr 129.88.11.7   1  60 21.90
## 6 6 1421761683 1759 lig-publig.imag.fr 129.88.11.7   1  60 78.70
     Visualisation des dernières lignes
tail(liglab2Data)
##           X       time size               name          ip seq ttl delay
## 44030 44030 1421771186  572 lig-publig.imag.fr 129.88.11.7   1  60  1.29
## 44031 44031 1421771186 1338 lig-publig.imag.fr 129.88.11.7   1  60  1.47
## 44032 44032 1421771186 1515 lig-publig.imag.fr 129.88.11.7   1  60  7.02
## 44033 44033 1421771186 1875 lig-publig.imag.fr 129.88.11.7   1  60  2.33
## 44034 44034 1421771187 1006 lig-publig.imag.fr 129.88.11.7   1  60  1.61
## 44035 44035 1421771187 1273 lig-publig.imag.fr 129.88.11.7   1  60  1.35
     2. Deuxième jeu de données
     Visualisation des premières lignes
head(stackoverflowData)
##   X       time size              name              ip seq ttl delay
## 1 1 1421771203  454 stackoverflow.com 198.252.206.140   1  50   120
## 2 2 1421771204  775 stackoverflow.com 198.252.206.140   1  50   126
## 3 3 1421771204 1334 stackoverflow.com 198.252.206.140   1  50   112
## 4 4 1421771204   83 stackoverflow.com 198.252.206.140   1  50   111
## 5 5 1421771205  694 stackoverflow.com 198.252.206.140   1  50   111
## 6 6 1421771205 1577 stackoverflow.com 198.252.206.140   1  50   112
     Visualisation des dernières lignes
tail(stackoverflowData)
##         X       time size              name              ip seq ttl delay
## 6818 6818 1421773459  357 stackoverflow.com 198.252.206.140   1  50   111
## 6819 6819 1421773459 1696 stackoverflow.com 198.252.206.140   1  50   111
## 6820 6820 1421773460  561 stackoverflow.com 198.252.206.140   1  50   111
## 6821 6821 1421773460  773 stackoverflow.com 198.252.206.140   1  50   111
## 6822 6822 1421773460 1009 stackoverflow.com 198.252.206.140   1  50   111
## 6823 6823 1421773461 1948 stackoverflow.com 198.252.206.140   1  50   112
Nom de colonne Libellé de colonne
time Date de prise des mesures exprimée en secondes depuis le 1er janvier 1970
size Taille (S) du message en octets
name Nom de la machine cible
ip Adresse IP la machine cible
seq
ttl
delay Temps(T) d’envoi (aller-retour) en millisecondes

Recherche des eventuelles lignes incomplètes des données

Il peut arriver qu’une ligne soit incomplète et il faut donc vérifier chaque ligne avant d’en extraire des informations !

     1. Premier jeu de données
na_records1 = apply(liglab2Data, 1, function (x) any(is.na(x)))
liglab2Data[na_records1,]
## [1] X     time  size  name  ip    seq   ttl   delay
## <0 rows> (or 0-length row.names)
     2. Deuxième jeu de données
na_records2 = apply(stackoverflowData, 1, function (x) any(is.na(x)))
stackoverflowData[na_records2,]
## [1] X     time  size  name  ip    seq   ttl   delay
## <0 rows> (or 0-length row.names)

Toutes les lignes de nos deux jeux de données sont complètes.

Conversion du temps (T)de transmisson de millisecondes en secondes

Afin de se facilité la tâche pour la suite, convertissons le temps de transmissions en secondes. Pour ce fait, nous allons créer une colonne delay_s qui contiendra T en secondes. Pour créer la collonne delay_s, nous allons utiliser des fonctions du packages tidyverse

library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.2     v purrr   0.3.4
## v tibble  3.0.4     v dplyr   1.0.2
## v tidyr   1.1.2     v stringr 1.4.0
## v readr   1.4.0     v forcats 0.5.0
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
     1. Premier jeu de données
liglab2Data <- liglab2Data  %>%
mutate(delay_s=0.001*delay)
     2. Deuxième jeu de données
stackoverflowData <- stackoverflowData  %>%
mutate(delay_s=0.001*delay)

Commençons par travailler avec le premier jeu de données (liglab2).

Pour la visualisation graphiques des données, nous allons utiliser le package ggplot2

library(ggplot2)

Représention graphique de l’évolution du temps de transmission au cours du temps (éventuellement à différents instants et différentes échelles de temps) pour évaluer la stabilité temporelle du phénomène.

ggplot(liglab2Data) +
    geom_line(aes(time,delay_s))+
    theme_bw(base_size = 14)+
    ylab("Temps (T) d'envoi en secondes")+xlab("Date de prise des mesures en secondes")

ggplot(liglab2Data) +
    geom_line(aes(time/360,delay_s))+
    theme_bw(base_size = 14)+
    ylab("Temps (T) d'envoi en secondes")+xlab("Date de prise des mesures en heures")

Les graphes ci-dessus montrent qu’il n’y pas une variation évidente du temps (T) d’envoi en fonction de la date de prise des mésures. Ainsi, compte tenu des variables de notre base de données, nous pouvons dire que les variations du temps (T) d’envoi peuvent être expliquées seulement par la taille des messages.

2. Représentons le temps de transmission en fonction de la taille des messages.

ggplot(liglab2Data) +
    geom_line(aes(size,delay_s))+
    theme_bw(base_size = 14)+
    geom_vline(aes(xintercept=mean(1480)),
               color="red", linetype="dashed", size=1.2)+
    ylab("Temps (T) d'envoi en secondes")+xlab("Taille (S) du message en octets")

A peu près à partir de la taille de 1480 octets, on observe une rupture et la nature de la variabilité du temps (T) de transmission change.

3. Effectuons une régression linéaire pour chacune des deux classes et évaluons les valeurs de L et de C correspondantes.

Séparation des données des deux classes

     1. Première classe
liglab2Class1 <- liglab2Data  %>%
    filter(size<=1480)
head(liglab2Class1)
##   X       time size               name          ip seq ttl delay delay_s
## 1 1 1421761682 1373 lig-publig.imag.fr 129.88.11.7   1  60 21.20 0.02120
## 2 2 1421761683  262 lig-publig.imag.fr 129.88.11.7   1  60 21.20 0.02120
## 3 3 1421761683 1107 lig-publig.imag.fr 129.88.11.7   1  60 23.30 0.02330
## 4 4 1421761683 1128 lig-publig.imag.fr 129.88.11.7   1  60  1.41 0.00141
## 5 5 1421761683  489 lig-publig.imag.fr 129.88.11.7   1  60 21.90 0.02190
## 6 7 1421761684 1146 lig-publig.imag.fr 129.88.11.7   1  60 25.10 0.02510
     2. Deuxième classe
liglab2Class2 <- liglab2Data  %>%
    filter(size>1480)
head(liglab2Class2)
##    X       time size               name          ip seq ttl delay delay_s
## 1  6 1421761683 1759 lig-publig.imag.fr 129.88.11.7   1  60 78.70 0.07870
## 2 15 1421761686 1843 lig-publig.imag.fr 129.88.11.7   1  60  2.31 0.00231
## 3 18 1421761686 1511 lig-publig.imag.fr 129.88.11.7   1  60  2.18 0.00218
## 4 24 1421761687 1510 lig-publig.imag.fr 129.88.11.7   1  60  2.17 0.00217
## 5 26 1421761688 1966 lig-publig.imag.fr 129.88.11.7   1  60  2.20 0.00220
## 6 30 1421761689 1518 lig-publig.imag.fr 129.88.11.7   1  60  2.19 0.00219

Régression linéaire

     1. Première classe
modliglab2Class1 <- lm(delay_s~size,liglab2Class1)
summary(modliglab2Class1)
## 
## Call:
## lm(formula = delay_s ~ size, data = liglab2Class1)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.002475 -0.002246 -0.002189 -0.002087  0.272490 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 3.275e-03  7.230e-05  45.295  < 2e-16 ***
## size        3.266e-07  8.496e-08   3.844 0.000121 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.006431 on 32664 degrees of freedom
## Multiple R-squared:  0.0004522,  Adjusted R-squared:  0.0004216 
## F-statistic: 14.78 on 1 and 32664 DF,  p-value: 0.0001213

La p-value du modèle 0.0001213 est inférieure à 0.05. On peut donc écrire pour cette classe de donnée que: \(T = 3.275\times10^{-3} +3.266\times10^{-7}*S\). De ce fait, \(L=3.275\times10^{-3}\) secondes et \(C=1/3.266\times10^{-7} = 3062153\) octets par seconde.

     2. Deuxième classe
modliglab2Class2 <- lm(delay_s~size,liglab2Class2)
summary(modliglab2Class2)
## 
## Call:
## lm(formula = delay_s ~ size, data = liglab2Class2)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.008276 -0.007729 -0.007354 -0.006999  0.177215 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)  
## (Intercept) 5.290e-03  2.244e-03   2.357   0.0184 *
## size        2.579e-06  1.281e-06   2.012   0.0442 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.02074 on 11367 degrees of freedom
## Multiple R-squared:  0.0003562,  Adjusted R-squared:  0.0002682 
## F-statistic:  4.05 on 1 and 11367 DF,  p-value: 0.0442

La p-value du modèle 0.0442 est inférieure à 0.05. On peut donc écrire pour cette classe de donnée que: \(T = 5.290\times10^{-3} +2.579\times10^{-6}*S\). De ce fait, \(L=5.290\times10^{-3}\) secondes et \(C=2.579\times10^{-6} = 387760.4\) octets par seconde.

Superposition du résultat de la régression linéaire au graphe précédent.

     1. Première classe
ggplot(liglab2Class1, aes(x=size,y=delay_s)) +
    geom_line()+
    geom_smooth(method=lm)+
    ylab("Temps (T) d'envoi en secondes")+xlab("Taille (S) du message en octets")
## `geom_smooth()` using formula 'y ~ x'

     2. Deuxième classe
ggplot(liglab2Class2, aes(x=size,y=delay_s)) +
    geom_line()+
    geom_smooth(method = lm)+
    ylab("Temps (T) d'envoi en secondes")+xlab("Taille (S) du message en octets")
## `geom_smooth()` using formula 'y ~ x'

4. (Optionnel) La variabilité est tellement forte et asymétrique que la régression du temps moyen peut être considérée comme peu pertinente. On peut vouloir s’intéresser à caractériser plutôt le plus petit temps de transmission. Une approche possible consiste donc à filtrer le plus petit temps de transmission pour chaque taille de message et à effectuer la régression sur ce sous-ensemble de données. Cela peut également être l’occasion pour ceux qui le souhaitent de se familiariser avec la régression de quantiles (implémentée en R dans la bibliothèque quantreg et en Python dans la bibliothèque statsmodels).

5. Travaillons maintenant avec le second jeu de données (stackoverflow)

Représention graphique de l’évolution du temps de transmission au cours du temps (éventuellement à différents instants et différentes échelles de temps) pour évaluer la stabilité temporelle du phénomène.

ggplot(stackoverflowData) +
    geom_line(aes(time,delay_s))+
    theme_bw(base_size = 14)+
    ylab("Temps (T) d'envoi en secondes")+xlab("Date de prise des mesures en secondes")

ggplot(stackoverflowData) +
    geom_line(aes(time/360,delay_s))+
    theme_bw(base_size = 14)+
    ylab("Temps (T) d'envoi en secondes")+xlab("Date de prise des mesures en heures")

Les graphes ci-dessus montrent qu’il n’y pas une variation évidente du temps (T) d’envoi en fonction de la date de prise des mésures. Ainsi, compte tenu des variables de notre base de données, nous pouvons dire que les variations du temps (T) d’envoi peuvent être expliquées seulement par la taille des messages.

Représentons le temps de transmission en fonction de la taille des messages.

ggplot(stackoverflowData) +
    geom_line(aes(size,delay_s))+
    theme_bw(base_size = 14)+
    geom_vline(aes(xintercept=1480),
               color="red", linetype="dashed", size=1.2)+
    ylab("Temps (T) d'envoi en secondes")+xlab("Taille (S) du message en octets")

A peu près à partir de la taille de 1480 octets, on observe une rupture et la nature de la variabilité du temps (T) de transmission change.

Effectuons une régression linéaire pour chacune des deux classes et évaluons les valeurs de L et de C correspondantes.

Séparation des données des deux classes

     1. Première classe
stackoverflowClass1 <- stackoverflowData  %>%
    filter(size<=1480)
head(stackoverflowClass1)
##   X       time size              name              ip seq ttl delay delay_s
## 1 1 1421771203  454 stackoverflow.com 198.252.206.140   1  50   120   0.120
## 2 2 1421771204  775 stackoverflow.com 198.252.206.140   1  50   126   0.126
## 3 3 1421771204 1334 stackoverflow.com 198.252.206.140   1  50   112   0.112
## 4 4 1421771204   83 stackoverflow.com 198.252.206.140   1  50   111   0.111
## 5 5 1421771205  694 stackoverflow.com 198.252.206.140   1  50   111   0.111
## 6 7 1421771205  632 stackoverflow.com 198.252.206.140   1  50   111   0.111
     2. Deuxième classe
stackoverflowClass2 <- stackoverflowData  %>%
    filter(size>1480)
head(stackoverflowClass2)
##    X       time size              name              ip seq ttl delay delay_s
## 1  6 1421771205 1577 stackoverflow.com 198.252.206.140   1  50   112   0.112
## 2 12 1421771207 1714 stackoverflow.com 198.252.206.140   1  50   112   0.112
## 3 15 1421771208 1598 stackoverflow.com 198.252.206.140   1  50   112   0.112
## 4 29 1421771212 1619 stackoverflow.com 198.252.206.140   1  50   112   0.112
## 5 40 1421771216 1655 stackoverflow.com 198.252.206.140   1  50   112   0.112
## 6 41 1421771216 1556 stackoverflow.com 198.252.206.140   1  50   112   0.112

Régression linéaire

     1. Première classe
modstackoverflowClass1 <- lm(delay_s~size,stackoverflowClass1)
summary(modstackoverflowClass1)
## 
## Call:
## lm(formula = delay_s ~ size, data = stackoverflowClass1)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.003262 -0.002273 -0.002254 -0.002233  0.036765 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 1.132e-01  1.655e-04 684.264   <2e-16 ***
## size        4.136e-08  1.938e-07   0.213    0.831    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.005818 on 5012 degrees of freedom
## Multiple R-squared:  9.087e-06,  Adjusted R-squared:  -0.0001904 
## F-statistic: 0.04554 on 1 and 5012 DF,  p-value: 0.831

La p-value du modèle 0.831 est supérieure à 0.05. Toutefois, \(L=1.132\times10^{-1}\) secondes et différent de 0 (p-value <2e-16 ). \(C=1/4.136\times10^{-8} = 24175534\) octets par seconde mais n’est par différent de 0 statistiquement (p-value=0.831).

     2. Deuxième classe
modstackoverflowClass2 <- lm(delay_s~size,stackoverflowClass2)
summary(modstackoverflowClass2)
## 
## Call:
## lm(formula = delay_s ~ size, data = stackoverflowClass2)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.006382 -0.005113 -0.004789 -0.004468  0.045721 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  1.201e-01  3.189e-03  37.648   <2e-16 ***
## size        -1.803e-06  1.827e-06  -0.987    0.324    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.01188 on 1807 degrees of freedom
## Multiple R-squared:  0.0005387,  Adjusted R-squared:  -1.444e-05 
## F-statistic: 0.9739 on 1 and 1807 DF,  p-value: 0.3238

La p-value du modèle 0.3238 est supérieure à 0.05. Toutefois, \(L=1.201\times10^{-1}\) secondes et différent de 0 (p-value <2e-16 ). \(C=1/-1.803\times10^{-6} = -554663.1\) (ce qui est absurde) octets par seconde mais n’est par différent de 0 statistiquement (p-value=0.324).

Superposition du résultat de la régression linéaire au graphe précédent.

     1. Première classe
ggplot(stackoverflowClass1, aes(x=size,y=delay_s)) +
    geom_line()+
    geom_smooth(method=lm)+
    ylab("Temps (T) d'envoi en secondes")+xlab("Taille (S) du message en octets")
## `geom_smooth()` using formula 'y ~ x'

     2. Deuxième classe
ggplot(stackoverflowClass2, aes(x=size,y=delay_s)) +
    geom_line()+
    geom_smooth(method = lm)+
    ylab("Temps (T) d'envoi en secondes")+xlab("Taille (S) du message en octets")
## `geom_smooth()` using formula 'y ~ x'