Biostatistiques

Imputation
MICE
Régression
ACP
Authors

C. ORHAN

Isabel PALACIO

Published

February 1, 2024

Introduction

Notre projet explore diverses stratégies pour gérer les valeurs manquantes, en s’appuyant sur un dataset provenant de la plateforme https://www.kaggle.com/datasets. Au cœur de notre approche se trouve une analyse descriptive, qui nous a permis de comprendre la distribution des données en examinant les tendances et la dispersion à travers des mesures comme la moyenne, la médiane et l’écart-type, et en utilisant des outils visuels tels que les histogrammes et les box-plots.

Concernant le remplacement des N/A, nous avons opté pour trois techniques adaptées aux caractéristiques de notre dataset : La régression linéaire, l’imputation multiple par MICE (Multiple Imputation by Chained Equations) et l’imputation multiple par Analyse en Composantes Principales (ACP).

Présentation du code

Je vous présente ci-dessous, le code utilisé pour mener à bien ce projet, avec les étapes et explications correspondantes.

Librairies

suppressPackageStartupMessages({
library(naniar)
library(tidyverse)
library(dplyr)
library(EnvStats)
library(corrplot)
library(RColorBrewer)
library(FactoMineR)
library(factoextra)
library(missMDA)
library(mice)
library(ggplot2)
library(car)
library(tinytex)
library(ranger)
library(here)
})
Warning in check_dep_version(): ABI version mismatch: 
lme4 was built with Matrix ABI version 1
Current Matrix ABI version is 0
Please re-install lme4 from source or restore original 'Matrix' package
vecteur_couleur <- c("F"="darkred", "M"="darkgreen", "I"="darkblue" )

Téléchargement de la base de données

crabe <- read.csv(here("data", "CrabAgePrediction.csv")) 

Présentation de la base de données

glimpse(crabe)
Rows: 3,893
Columns: 9
$ Sex            <chr> "F", "M", "I", "F", "I", "F", "F", "M", "I", "I", "M", …
$ Length         <dbl> 1.4375, 0.8875, 1.0375, 1.1750, 0.8875, 1.5500, 1.3000,…
$ Diameter       <dbl> 1.1750, 0.6500, 0.7750, 0.8875, 0.6625, 1.1625, 1.0000,…
$ Height         <dbl> 0.4125, 0.2125, 0.2500, 0.2500, 0.2125, 0.3500, 0.3250,…
$ Weight         <dbl> 24.635715, 5.400580, 7.952035, 13.480187, 6.903103, 28.…
$ Shucked.Weight <dbl> 12.332033, 2.296310, 3.231843, 4.748541, 3.458639, 13.5…
$ Viscera.Weight <dbl> 5.5848515, 1.3749507, 1.6017467, 2.2821347, 1.4883488, …
$ Shell.Weight   <dbl> 6.7471810, 1.5592225, 2.7640763, 5.2446575, 1.7009700, …
$ Age            <int> 9, 6, 6, 10, 6, 8, 15, 10, 13, 7, 6, 10, 9, 10, 11, 12,…

À titre informatif, notre base de données est une base sur des crabes destinés à la consommation dans des restaurants de la région de Boston.

Le type de crabe le plus commun à cet effet est le crabe bleu américain qui est natif des côtes atlantiques américaines.

Le crabe bleu américain est pêché et consommé en grande quantité, principalement aux Etats-Unis et au Mexique. Chaque année, 58 000 tonnes sont prélevées ; son importance économique et culinaire est considérable sur la côte est des Etats-Unis, en particulier dans les états de Louisiane, du Maryland, de Caroline du Nord, du New Jersey et du Massachusetts.

Transformation de la BD

Traduction des noms de nos variables en français

names(crabe) <- c("sexe", "longueur", "diametre", "hauteur", "poids","poids.chair", "poids.visceres", "poids.coquille", "age")

Notre base de données est donc composée de 3894 crabes bleus et de 9 variables qui sont :

Variables qualitatives :

  • Sexe du crabe - Mâle (Male), Femelle (Female) et Indéterminé (Indeterminate).

Variables quantitatives :

  • Longueur : longueur du crabe (en pieds ; 1 pied = 30,48 cm).

  • Diamètre : diamètre du crabe (en pieds ; 1 pied = 30,48 cm).

  • Hauteur : hauteur du crabe (en pieds ; 1 pied = 30,48 cm).

  • Poids : poids du crabe (en onces ; 1 livre = 16 onces).

  • Poids éviscéré : poids du crabe sans sa coquille (en onces ; 1 livre = 16 onces).

  • Poids des viscères : poids des viscères, qui sont les organes entourant la cavité abdominale (en onces ; 1 livre = 16 onces).

  • Poids de la coquille : poids de la coquille du crabe (en onces ; 1 livre = 16 onces).

  • Age : âge du crabe (en mois).

Conversion des variables à l’origine en pied en centimètre

crabe$longueur <- crabe$longueur * 30.48
crabe$diametre <- crabe$diametre * 30.48
crabe$hauteur <- crabe$hauteur * 30.48

Conversion des variables à l’origine en onces en kilogramme

crabe$poids <- crabe$poids * 0.0283495
crabe$poids.chair <- crabe$poids.chair * 0.0283495
crabe$poids.visceres <- crabe$poids.visceres * 0.0283495
crabe$poids.coquille <- crabe$poids.coquille * 0.0283495
str(crabe)
'data.frame':   3893 obs. of  9 variables:
 $ sexe          : chr  "F" "M" "I" "F" ...
 $ longueur      : num  43.8 27.1 31.6 35.8 27.1 ...
 $ diametre      : num  35.8 19.8 23.6 27.1 20.2 ...
 $ hauteur       : num  12.57 6.48 7.62 7.62 6.48 ...
 $ poids         : num  0.698 0.153 0.225 0.382 0.196 ...
 $ poids.chair   : num  0.3496 0.0651 0.0916 0.1346 0.0981 ...
 $ poids.visceres: num  0.1583 0.039 0.0454 0.0647 0.0422 ...
 $ poids.coquille: num  0.1913 0.0442 0.0784 0.1487 0.0482 ...
 $ age           : int  9 6 6 10 6 8 15 10 13 7 ...

Nos variables sont bien classées, nous n’avons pas à les modifier.

plot(crabe)

Après un aperçu rapide de nos données, nous pouvons observer que :

Les graphiques ont différentes tendances et degrés de corrélation. Certains indiquent une corrélation positive marquée, visible par les points qui forment une trajectoire nette ascendante de gauche à droite.

Des points paraissent s’écarter de la tendance générale dans plusieurs scatter plots, suggérant la présence de valeurs aberrantes.

Notre jeu de données ne présente pas de valeurs manquantes. Cependant, en ce qui concerne la variable qualitative “sexe”, nous observons une anomalie qui nécessite une analyse plus détaillée. En effet, nous recensons trois catégories : M pour masculin, F pour féminin et I pour indéfini, ce qui pourrait indiquer une erreur.

Afin de mieux comprendre nos données, nous allons réaliser une première analyse descriptive des variables qui présentent des valeurs atypiques.

Analyse descriptive exploratoire

L’analyse descriptive exploratoire a pour objectif de déterminer la présence de valeurs aberrantes ou extrêmes au sein de nos données, afin de procéder à leur correction si nécessaire.

Calcul des mesures de dispersion

summary(crabe)
     sexe              longueur         diametre         hauteur      
 Length:3893        Min.   : 5.715   Min.   : 4.191   Min.   : 0.000  
 Class :character   1st Qu.:34.290   1st Qu.:26.670   1st Qu.: 8.763  
 Mode  :character   Median :41.529   Median :32.385   Median :11.049  
                    Mean   :39.969   Mean   :31.117   Mean   :10.649  
                    3rd Qu.:46.863   3rd Qu.:36.576   3rd Qu.:12.573  
                    Max.   :62.103   Max.   :49.530   Max.   :86.106  
     poids           poids.chair        poids.visceres      poids.coquille    
 Min.   :0.001607   Min.   :0.0008037   Min.   :0.0004018   Min.   :0.001205  
 1st Qu.:0.359251   1st Qu.:0.1514963   1st Qu.:0.0755473   1st Qu.:0.105284  
 Median :0.646170   Median :0.2704431   Median :0.1378335   Median :0.188868  
 Mean   :0.668121   Mean   :0.2893730   Mean   :0.1456185   Mean   :0.192659  
 3rd Qu.:0.929472   3rd Qu.:0.4046600   3rd Qu.:0.2041383   3rd Qu.:0.265219  
 Max.   :2.270838   Max.   :1.1958969   Max.   :0.6108076   Max.   :0.807713  
      age        
 Min.   : 1.000  
 1st Qu.: 8.000  
 Median :10.000  
 Mean   : 9.955  
 3rd Qu.:11.000  
 Max.   :29.000  
  1. Longueur : La longueur des crabes varie de 5.715 à 62.103 avec une moyenne d’environ 39.969. La médiane est de 41.529, ce qui suggère une distribution légèrement asymétrique vers les valeurs inférieures puisque la moyenne est inférieure à la médiane. Les valeurs sont concentrées principalement entre 34.290 et 46.863, qui représentent les premiers et troisième quartile, indiquant que 50 % des observations sont dans cette plage.

  2. Diamètre : le diamètre varie de 4.191 à 49.530, avec une moyenne de 31.117. La médiane est de 32.385, suggérant une distribution similaire à celle de la longueur, avec une légère asymétrie. Le diamètre des crabes est généralement compris entre 26.670 et 36.576 (premier et troisième quartiles).

  3. Hauteur : la hauteur présente une gamme plus étendue allant de 0 à 86.106, avec une moyenne de 10.649. La médiane de 11.049 est supérieure à la moyenne, ce qui pourrait indiquer une distribution asymétrique avec une queue de distribution vers les valeurs inférieures.

  4. Poids : le poids total des crabes est compris entre 0.001607 et 2.270838, avec une moyenne de 0.668121. La médiane est de 0.646170, indiquant une distribution des poids assez symétrique autour de la valeur centrale.

  5. Poids de chair : le poids de la chair varie de 0.0008037 à 1.1958969, avec une moyenne de 0.2893730. La médiane, à 0.2704431, est légèrement inférieure à la moyenne, suggérant une distribution modérément asymétrique.

  6. Poids des viscères : le poids des viscères varie de 0.0004018 à 0.6108076, avec une moyenne de 0.1456185. La médiane est assez proche de la moyenne, ce qui indique une distribution assez équilibrée.

  7. Poids de la coquille : le poids de la coquille a une plage allant de 0.001205 à 0.807713, avec une moyenne de 0.192659. La médiane est également proche de la moyenne, ce qui suggère une distribution régulière.

  8. Age : l’âge varie de 1 à 29 mois, avec une moyenne proche de la médiane (9.955 contre 10), indiquant une distribution symétrique. La plupart des crabes ont entre 8 et 11 mois (premier et troisième quartiles), ce qui montre que les âges sont relativement concentrés.

Vérification de l’absence de doublons

Notre jeu de données est composé de 3 893 entrées. Nous allons vérifier s’il contient des doublons.

crabe |>
    distinct() |>
    nrow()

[1] 3893

Aucune ligne n’est répétée, nous pouvons donc conserver la totalité de nos données

Diagramme en camembert

Sexe

crabe |>
  count(sexe) |>
  mutate(pourcentage = n / sum(n) * 100) |>
  ggplot(aes(x = "", y = n, fill = sexe)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar(theta = "y") +
  scale_fill_manual(values = vecteur_couleur) +
  geom_text(aes(label = paste0(round(pourcentage, 1), "%")),
         position = position_stack(vjust = 0.5),
         color = "white") +  
  labs(
    title = "Distribution des sexes dans le jeu de données ",
    fill = "Sexe"
  ) +
  theme_void()  

Il illustre la distribution des sexes dans notre jeu de données. Les mâles représentent la plus grande proportion avec 36,9 %, tandis que les femelles et les indéfinis ont des proportions presque égales de 31,5 % et 31,7 % respectivement.

Représentation des valeurs aberrantes grâce à des boxplots

crabe  |>
    pivot_longer(
      cols = longueur:age,
      names_to = "mesure",
      values_to = "valeur"
      ) |>
    ggplot() +
    aes(y = valeur, x = sexe, color = sexe) +
    geom_boxplot() +
    geom_jitter(alpha = 0.3,  position = position_jitter(width = 0.2))  +
    facet_wrap(~ mesure, scales = "free_y") +
    scale_color_manual(values =vecteur_couleur)+
    labs(title = "Distribution des mesures par sexe")+
    theme_bw()

Nous pouvons donc observer la présence de valeurs aberrantes ou extrêmes dans nos variables. Pour les identifier, nous avons utilisé le test de Rosner.

rosnerTest(crabe$longueur, k=10, alpha=0.05)

Results of Outlier Test
-------------------------

Test Method:                     Rosner's Test for Outliers

Hypothesized Distribution:       Normal

Data:                            crabe$longueur

Sample Size:                     3893

Test Statistics:                 R.1  = 3.740649
                                 R.2  = 3.456138
                                 R.3  = 3.294960
                                 R.4  = 3.299993
                                 R.5  = 3.263207
                                 R.6  = 3.226213
                                 R.7  = 3.230957
                                 R.8  = 3.151732
                                 R.9  = 3.114132
                                 R.10 = 3.118429

Test Statistic Parameter:        k = 10

Alternative Hypothesis:          Up to 10 observations are not
                                 from the same Distribution.

Type I Error:                    5%

Number of Outliers Detected:     0

   i   Mean.i     SD.i  Value Obs.Num    R.i+1 lambda.i+1 Outlier
1  0 39.96859 9.157125  5.715    1331 3.740649   4.357703   FALSE
2  1 39.97739 9.141820  8.382     754 3.456138   4.357646   FALSE
3  2 39.98551 9.128947  9.906    1178 3.294960   4.357588   FALSE
4  3 39.99325 9.117367  9.906    3729 3.299993   4.357531   FALSE
5  4 40.00098 9.105761 10.287    1901 3.263207   4.357474   FALSE
6  5 40.00863 9.094449 10.668     308 3.226213   4.357416   FALSE
7  6 40.01617 9.083430 10.668     956 3.230957   4.357359   FALSE
8  7 40.02373 9.072385 11.430    1135 3.151732   4.357302   FALSE
9  8 40.03109 9.061943 11.811     694 3.114132   4.357244   FALSE
10 9 40.03835 9.051785 11.811    2766 3.118429   4.357187   FALSE
rosnerTest(crabe$diametre, k=10, alpha=0.05)

Results of Outlier Test
-------------------------

Test Method:                     Rosner's Test for Outliers

Hypothesized Distribution:       Normal

Data:                            crabe$diametre

Sample Size:                     3893

Test Statistics:                 R.1  = 3.558731
                                 R.2  = 3.211973
                                 R.3  = 3.166162
                                 R.4  = 3.120107
                                 R.5  = 3.124422
                                 R.6  = 3.078090
                                 R.7  = 3.082245
                                 R.8  = 3.086418
                                 R.9  = 3.090607
                                 R.10 = 3.043926

Test Statistic Parameter:        k = 10

Alternative Hypothesis:          Up to 10 observations are not
                                 from the same Distribution.

Type I Error:                    5%

Number of Outliers Detected:     0

   i   Mean.i     SD.i Value Obs.Num    R.i+1 lambda.i+1 Outlier
1  0 31.11683 7.566132 4.191    1331 3.558731   4.357703   FALSE
2  1 31.12375 7.554779 6.858     754 3.211973   4.357646   FALSE
3  2 31.12998 7.545724 7.239    1178 3.166162   4.357588   FALSE
4  3 31.13612 7.536961 7.620    1135 3.120107   4.357531   FALSE
5  4 31.14217 7.528488 7.620    3729 3.124422   4.357474   FALSE
6  5 31.14822 7.519995 8.001     308 3.078090   4.357416   FALSE
7  6 31.15417 7.511789 8.001     956 3.082245   4.357359   FALSE
8  7 31.16013 7.503564 8.001    2913 3.086418   4.357302   FALSE
9  8 31.16609 7.495321 8.001    3634 3.090607   4.357244   FALSE
10 9 31.17206 7.487061 8.382    1648 3.043926   4.357187   FALSE
rosnerTest(crabe$hauteur, k=10, alpha=0.05)

Results of Outlier Test
-------------------------

Test Method:                     Rosner's Test for Outliers

Hypothesized Distribution:       Normal

Data:                            crabe$hauteur

Sample Size:                     3893

Test Statistics:                 R.1  = 23.582729
                                 R.2  =  9.658305
                                 R.3  =  3.628763
                                 R.4  =  3.635390
                                 R.5  =  3.380918
                                 R.6  =  3.255592
                                 R.7  =  3.260460
                                 R.8  =  3.134283
                                 R.9  =  3.007441
                                 R.10 =  3.011338

Test Statistic Parameter:        k = 10

Alternative Hypothesis:          Up to 10 observations are not
                                 from the same Distribution.

Type I Error:                    5%

Number of Outliers Detected:     2

   i   Mean.i     SD.i  Value Obs.Num     R.i+1 lambda.i+1 Outlier
1  0 10.64892 3.199676 86.106    2257 23.582729   4.357703    TRUE
2  1 10.62953 2.962577 39.243     749  9.658305   4.357646    TRUE
3  2 10.62217 2.927216  0.000     270  3.628763   4.357588   FALSE
4  3 10.62490 2.922632  0.000    3868  3.635390   4.357531   FALSE
5  4 10.62764 2.918035  0.762    1331  3.380918   4.357474   FALSE
6  5 10.63017 2.914116  1.143    1124  3.255592   4.357416   FALSE
7  6 10.63262 2.910514  1.143    3543  3.260460   4.357359   FALSE
8  7 10.63506 2.906903  1.524     986  3.134283   4.357302   FALSE
9  8 10.63740 2.903599  1.905     694  3.007441   4.357244   FALSE
10 9 10.63965 2.900588  1.905    1135  3.011338   4.357187   FALSE
rosnerTest(crabe$poids, k=10, alpha=0.05)

Results of Outlier Test
-------------------------

Test Method:                     Rosner's Test for Outliers

Hypothesized Distribution:       Normal

Data:                            crabe$poids

Sample Size:                     3893

Test Statistics:                 R.1  = 4.069788
                                 R.2  = 3.984935
                                 R.3  = 3.742623
                                 R.4  = 3.540531
                                 R.5  = 3.536432
                                 R.6  = 3.538473
                                 R.7  = 3.499292
                                 R.8  = 3.483594
                                 R.9  = 3.475026
                                 R.10 = 3.473644

Test Statistic Parameter:        k = 10

Alternative Hypothesis:          Up to 10 observations are not
                                 from the same Distribution.

Type I Error:                    5%

Number of Outliers Detected:     0

   i    Mean.i      SD.i    Value Obs.Num    R.i+1 lambda.i+1 Outlier
1  0 0.6681205 0.3938086 2.270838    2897 4.069788   4.357703   FALSE
2  1 0.6677087 0.3930200 2.233868     773 3.984935   4.357646   FALSE
3  2 0.6673062 0.3922674 2.135415    2572 3.742623   4.357588   FALSE
4  3 0.6669288 0.3916107 2.053439     230 3.540531   4.357531   FALSE
5  4 0.6665722 0.3910292 2.049420    2717 3.536432   4.357474   FALSE
6  5 0.6662166 0.3904498 2.047813     539 3.538473   4.357416   FALSE
7  6 0.6658611 0.3898704 2.030131     502 3.499292   4.357359   FALSE
8  7 0.6655100 0.3893056 2.021693    1758 3.483594   4.357302   FALSE
9  8 0.6651610 0.3887470 2.016067    1327 3.475026   4.357244   FALSE
10 9 0.6648132 0.3881920 2.013254    3186 3.473644   4.357187   FALSE
rosnerTest(crabe$poids.chair, k=10, alpha=0.05)

Results of Outlier Test
-------------------------

Test Method:                     Rosner's Test for Outliers

Hypothesized Distribution:       Normal

Data:                            crabe$poids.chair

Sample Size:                     3893

Test Statistics:                 R.1  = 5.095668
                                 R.2  = 4.492498
                                 R.3  = 4.493418
                                 R.4  = 4.070734
                                 R.5  = 4.045732
                                 R.6  = 4.027361
                                 R.7  = 4.001947
                                 R.8  = 3.847766
                                 R.9  = 3.846418
                                 R.10 = 3.743692

Test Statistic Parameter:        k = 10

Alternative Hypothesis:          Up to 10 observations are not
                                 from the same Distribution.

Type I Error:                    5%

Number of Outliers Detected:     3

   i    Mean.i      SD.i     Value Obs.Num    R.i+1 lambda.i+1 Outlier
1  0 0.2893730 0.1779009 1.1958969    2572 5.095668   4.357703    TRUE
2  1 0.2891401 0.1773291 1.0857908    1950 4.492498   4.357646    TRUE
3  2 0.2889354 0.1768912 1.0837816     773 4.493418   4.357588    TRUE
4  3 0.2887310 0.1764541 1.0070288    2317 4.070734   4.357531   FALSE
5  4 0.2885463 0.1761003 1.0010011    1294 4.045732   4.357474   FALSE
6  5 0.2883631 0.1757518 0.9961789    3351 4.027361   4.357416   FALSE
7  6 0.2881810 0.1754072 0.9901512    1327 4.001947   4.357359   FALSE
8  7 0.2880004 0.1750678 0.9616201    3186 3.847766   4.357302   FALSE
9  8 0.2878270 0.1747563 0.9600127     539 3.846418   4.357244   FALSE
10 9 0.2876539 0.1744455 0.9407240     854 3.743692   4.357187   FALSE
rosnerTest(crabe$poids.visceres, k=10, alpha=0.05)

Results of Outlier Test
-------------------------

Test Method:                     Rosner's Test for Outliers

Hypothesized Distribution:       Normal

Data:                            crabe$poids.visceres

Sample Size:                     3893

Test Statistics:                 R.1  = 5.286202
                                 R.2  = 4.219961
                                 R.3  = 3.757195
                                 R.4  = 3.626516
                                 R.5  = 3.628525
                                 R.6  = 3.538250
                                 R.7  = 3.415023
                                 R.8  = 3.337302
                                 R.9  = 3.342527
                                 R.10 = 3.213223

Test Statistic Parameter:        k = 10

Alternative Hypothesis:          Up to 10 observations are not
                                 from the same Distribution.

Type I Error:                    5%

Number of Outliers Detected:     1

   i    Mean.i       SD.i     Value Obs.Num    R.i+1 lambda.i+1 Outlier
1  0 0.1456185 0.08800062 0.6108076     773 5.286202   4.357703    TRUE
2  1 0.1454990 0.08769532 0.5155698    1758 4.219961   4.357646   FALSE
3  2 0.1454039 0.08750561 0.4741795     502 3.757195   4.357588   FALSE
4  3 0.1453194 0.08735787 0.4621241    1205 3.626516   4.357531   FALSE
5  4 0.1452379 0.08722122 0.4617223     539 3.628525   4.357474   FALSE
6  5 0.1451565 0.08708457 0.4532835     692 3.538250   4.357416   FALSE
7  6 0.1450772 0.08695537 0.4420318    1936 3.415023   4.357359   FALSE
8  7 0.1450008 0.08683593 0.4347985    2317 3.337302   4.357302   FALSE
9  8 0.1449262 0.08672250 0.4347985    2531 3.342527   4.357244   FALSE
10 9 0.1448516 0.08660879 0.4231450    1828 3.213223   4.357187   FALSE
rosnerTest(crabe$poids.coquille, k=10, alpha=0.05)

Results of Outlier Test
-------------------------

Test Method:                     Rosner's Test for Outliers

Hypothesized Distribution:       Normal

Data:                            crabe$poids.coquille

Sample Size:                     3893

Test Statistics:                 R.1  = 5.501712
                                 R.2  = 4.744584
                                 R.3  = 4.672147
                                 R.4  = 4.685917
                                 R.5  = 4.190527
                                 R.6  = 4.072972
                                 R.7  = 3.954369
                                 R.8  = 3.816471
                                 R.9  = 3.574841
                                 R.10 = 3.573856

Test Statistic Parameter:        k = 10

Alternative Hypothesis:          Up to 10 observations are not
                                 from the same Distribution.

Type I Error:                    5%

Number of Outliers Detected:     4

   i    Mean.i      SD.i     Value Obs.Num    R.i+1 lambda.i+1 Outlier
1  0 0.1926588 0.1117932 0.8077126    3296 5.501712   4.357703    TRUE
2  1 0.1925008 0.1113718 0.7209137    2897 4.744584   4.357646    TRUE
3  2 0.1923649 0.1110634 0.7112693    2726 4.672147   4.357588    TRUE
4  3 0.1922316 0.1107655 0.7112693    3070 4.685917   4.357531    TRUE
5  4 0.1920981 0.1104664 0.6550107     199 4.190527   4.357474   FALSE
6  5 0.1919790 0.1102308 0.6409461    1486 4.072972   4.357416   FALSE
7  6 0.1918635 0.1100094 0.6268814    1924 3.954369   4.357359   FALSE
8  7 0.1917516 0.1098019 0.6108076    1826 3.816471   4.357302   FALSE
9  8 0.1916437 0.1096100 0.5834820    1556 3.574841   4.357244   FALSE
10 9 0.1915428 0.1094435 0.5826783    1847 3.573856   4.357187   FALSE
rosnerTest(crabe$age, k=10, alpha=0.05)

Results of Outlier Test
-------------------------

Test Method:                     Rosner's Test for Outliers

Hypothesized Distribution:       Normal

Data:                            crabe$age

Sample Size:                     3893

Test Statistics:                 R.1  = 5.912886
                                 R.2  = 5.316734
                                 R.3  = 5.336843
                                 R.4  = 5.043142
                                 R.5  = 4.745335
                                 R.6  = 4.443844
                                 R.7  = 4.455752
                                 R.8  = 4.150310
                                 R.9  = 4.160079
                                 R.10 = 4.169918

Test Statistic Parameter:        k = 10

Alternative Hypothesis:          Up to 10 observations are not
                                 from the same Distribution.

Type I Error:                    5%

Number of Outliers Detected:     7

   i   Mean.i     SD.i Value Obs.Num    R.i+1 lambda.i+1 Outlier
1  0 9.954791 3.220967    29    1730 5.912886   4.357703    TRUE
2  1 9.949897 3.206875    27    3070 5.316734   4.357646    TRUE
3  2 9.945515 3.195613    27    3523 5.336843   4.357588    TRUE
4  3 9.941131 3.184299    26      90 5.043142   4.357531    TRUE
5  4 9.937002 3.174275    25    2424 4.745335   4.357474    TRUE
6  5 9.933128 3.165474    24     374 4.443844   4.357416    TRUE
7  6 9.929509 3.157827    24    3308 4.455752   4.357359    TRUE
8  7 9.925888 3.150153    23     138 4.150310   4.357302   FALSE
9  8 9.922523 3.143564    23     502 4.160079   4.357244   FALSE
10 9 9.919156 3.136955    23    1215 4.169918   4.357187   FALSE

Nous utilisons le test de Rosner pour identifier les observations qui peuvent être considérées comme aberrantes ou extrêmes, afin de les analyser en détail.

  • Hauteur pour les observations numéros 2257 (86,106 cm) et 749 (39,24 cm)

  • Poids de la chair pour les observations 2257 (1,19 kg), 1950 (1,08 kg) et 773 (1,08 kg)

  • Poids des viscères pour l’observation 773 (0,61 kg)

  • Poids de la coquille pour les observations 3296 (0,8 kg), 2897 (0,72 kg), 2726 (0,71 kg) et 3070 (0,71 kg)

  • Age pour les observations 1730 (29 mois), 3070 (27 mois), 3535 (27 mois), 90 (26 mois), 2424 (25 mois), 374 (24 mois) et 3308 (24 mois).

Lors de nos recherches, nous avons cherché à comprendre la normalité de notre base de données.

On apprend ainsi que le crabe bleu à une longévité d’environ 3 ans donc nous décidons de conserver les valeurs extrêmes de la variable âge. Concernant les variables poids de la chair, poids des viscères et poids de la coquille, nous décidons également de les garder.

Pour la suite, nous allons donc traiter les deux valeurs de la variable “hauteur”.

Observation n°2257

crabe[2257,]
     sexe longueur diametre hauteur     poids poids.chair poids.visceres
2257    F   34.671   27.051  86.106 0.4773943   0.2668265     0.09322852
     poids.coquille age
2257      0.1072932   8
resultat <- crabe %>%
  filter(sexe == "F", age == 8) %>%
  summarise(mean_hauteur = mean(hauteur))
print(resultat)
  mean_hauteur
1     11.39628

Nous constatons que la moyenne des hauteurs pour les crabes âgés de 8 mois et de sexe féminin est de 11,39. Nous pouvons donc supposer que notre valeur de 86,106 est une valeur aberrante, probablement due à une erreur de saisie de virgule, que nous pouvons corriger.

crabe[2257,"hauteur"]<-8.6106

Première méthode de remplacement : Regression linéaire

Observation n°749

crabe[749,]
    sexe longueur diametre hauteur    poids poids.chair poids.visceres
749    M   53.721   43.053  39.243 1.776164   0.8900913      0.3909972
    poids.coquille age
749      0.4114914  10
resultat <- crabe %>%
  filter(sexe == "M", age == 10) %>%
  summarise(min_hauteur = min(hauteur))
print(resultat)
  min_hauteur
1       4.953

Par conséquent, cette valeur observée de 39,243 cm, n’est pas une valeur aberrante, mais semble être une valeur extrême compte tenu de la valeur minimum de 4,953 cm.

Nous avons choisi comme première méthode de remplacement pour cette valeur, une régression linéaire.

crabe[749,"hauteur"]<-NA

Pour commencer, nous avons remplacé la valeur extrême identifiée par une valeur manquante “NA” afin de procéder à son remplacement.

regression_linéaire <- lm (
  hauteur ~ sexe + diametre + longueur + poids + poids.chair + poids.visceres + poids.coquille + age,
  data=crabe
  )
summary(regression_linéaire)

Call:
lm(formula = hauteur ~ sexe + diametre + longueur + poids + poids.chair + 
    poids.visceres + poids.coquille + age, data = crabe)

Residuals:
     Min       1Q   Median       3Q      Max 
-11.4907  -0.6381  -0.0373   0.6150   6.1299 

Coefficients:
                Estimate Std. Error t value Pr(>|t|)    
(Intercept)     1.850761   0.154990  11.941  < 2e-16 ***
sexeI          -0.207460   0.054287  -3.822 0.000135 ***
sexeM          -0.035236   0.043663  -0.807 0.419718    
diametre        0.140987   0.015275   9.230  < 2e-16 ***
longueur        0.045855   0.012403   3.697 0.000221 ***
poids          -0.209082   0.477195  -0.438 0.661303    
poids.chair    -0.218862   0.566617  -0.386 0.699324    
poids.visceres  4.918407   0.844109   5.827 6.11e-09 ***
poids.coquille  6.907514   0.734184   9.408  < 2e-16 ***
age             0.079057   0.008096   9.765  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.114 on 3882 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.8556,    Adjusted R-squared:  0.8552 
F-statistic:  2555 on 9 and 3882 DF,  p-value: < 2.2e-16

À travers cette régression linéaire, nous avons identifié les variables qui montrent des corrélations significatives avec la variable « hauteur ». Il apparaît que la variable significative liée au sexe est « sexeI », représentant le sexe indéterminé, tandis que « sexeF », qui sert de modalité de référence par défaut, et « sexeM », qui n’est pas significative, ne seront pas pris en compte dans notre analyse. Par conséquent, nous allons filtrer notre ensemble de données en se concentrant uniquement sur le sexe indéterminé.

sexeI <- crabe |> filter(sexe=="I")
modele <- regression_linéaire2 <-lm(
  hauteur~diametre+poids.visceres+poids.coquille+age,
  data=sexeI
)
summary(regression_linéaire2)

Call:
lm(formula = hauteur ~ diametre + poids.visceres + poids.coquille + 
    age, data = sexeI)

Residuals:
    Min      1Q  Median      3Q     Max 
-8.3991 -0.5447 -0.0582  0.4965  4.8595 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)     0.96519    0.17413   5.543 3.63e-08 ***
diametre        0.21139    0.01024  20.649  < 2e-16 ***
poids.visceres  9.17354    1.57864   5.811 7.90e-09 ***
poids.coquille  2.65358    1.30044   2.041   0.0415 *  
age             0.13475    0.01558   8.646  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.9279 on 1228 degrees of freedom
Multiple R-squared:  0.8585,    Adjusted R-squared:  0.858 
F-statistic:  1863 on 4 and 1228 DF,  p-value: < 2.2e-16

Nous allons à présent utiliser les résultats de cette régression afin de générer des prédictions pour remplacer la valeur manquante.

crabe$hauteur[is.na(crabe$hauteur)] <- predict(modele, newdata = crabe[is.na(crabe$hauteur), ])

Cette prédiction nous a permis d’utiliser les relations linéaires identifiées dans le modèle pour estimer et remplacer de manière précise la valeur manquante de l’observation n°749.

crabe[749,"hauteur"]
[1] 16.09228
crabe_complet<-crabe

La nouvelle valeur est donc 16,09 cm.

Création de nos valeurs manquantes

Notre jeu de données est initialement complet, sans valeurs manquantes. Nous avons toutefois opté pour l’insertion aléatoire de données manquantes de façon contrôlée.

Pour garantir une reproductibilité fiable de ce processus aléatoire, nous employons la fonction set.seed, qui fixe la graine du générateur de nombres aléatoires. Cette étape est essentielle pour s’assurer que les résultats puissent être régénérés de manière identique lors de chaque exécution.

Afin d’intégrer les valeurs manquantes (N/A) dans notre jeu de données, nous procédons de la manière suivante :

set.seed(123)  
n <- nrow(crabe)  
p <- ncol(crabe)  
m <- 50

cols <- c("poids", "diametre", "age")

row_indices <- sample(1:n, m)  
col_indices <- sample(cols, m, replace = TRUE)

Explication détaillée du script :

n <- nrow(crabe) : cette commande calcule le nombre total d’observations dans le jeu de données crabe et stocke ce nombre dans la variable n.

p <- ncol(crabe) : cette commande détermine le nombre total de variables présentes dans le jeu de données crabe et l’assigne à la variable p.

m <- 50 : cette instruction spécifie le nombre total de valeurs manquantes à générer dans le jeu de données, fixé ici à 50.

cols <- c (“poids”, “diametre”, “age”) : cette ligne crée un vecteur cols contenant les noms des variables pour lesquelles les valeurs manquantes seront introduites.

row_indices <- sample(1:n, m) : cet appel à sample produit un vecteur row_indices composé de m indices de lignes choisies aléatoirement parmi toutes les lignes disponibles, allant de 1 à n.

col_indices <- sample(cols, m, replace = TRUE) : cette instruction crée un vecteur col_indices de m éléments, sélectionnant aléatoirement et avec remplacement parmi les noms de colonnes spécifiés dans cols.

Pour injecter les valeurs manquantes dans le jeu de données, nous parcourons les indices générés et assignons NA à la position correspondante à chaque itération de la boucle :

for (i in 1:m) {
  crabe[row_indices[i], col_indices[i]] <- NA
}
crabe_mice <- crabe
crabe_missMDA <- crabe

Visualisation des valeurs manquantes

gg_miss_upset(crabe)
`geom_line()`: Each group consists of only one observation.
ℹ Do you need to adjust the group aesthetic?

Description de la figure.

Le graphique ci-dessus, illustre la répartition des valeurs manquantes (N/A) que nous avons générées et insérées de manière aléatoire dans les colonnes sélectionnées de notre jeu de données. Au total, 50 valeurs manquantes ont été introduites : 19 dans la colonne du poids, 16 dans celle du diamètre et 15 dans celle de l’âge.

Afin de mieux comprendre la distribution des colonnes où nous avons inséré des valeurs manquantes, et pour déterminer les méthodes de remplacement les plus adaptées, nous procédons à l’examen de la normalité et à l’analyse de la corrélation entre nos variables.

Test de normalité

QQ plot Age

qqnorm(crabe$age, main = "Q-Q plot - Age")
qqline(crabe$age, col = 2)

QQ plot Poids

qqnorm(crabe$poids, main = "Q-Q Plot - Poids")

qqline(crabe$poids, col = 2)

QQ plot Diametre

qqnorm(crabe$diametre, main = "Q-Q Plot - Diamètre")

qqline(crabe$diametre, col = 2)

Un graphique Q-Q (quantile-quantile) est un outil visuel utilisé en statistique pour comparer deux distributions de probabilité en traçant leurs quantiles l’un contre l’autre. Il est souvent utilisé pour vérifier si deux ensembles de données suivent une même distribution. Si les points s’alignent approximativement sur une ligne droite, cela suggère que les deux distributions sont similaires.

Dans notre cas, les Q-Q plots ne suivent pas la droite de la loi normale, nous pouvons donc supposer qu’ils ne suivent pas une distribution normale.

Calculer la moyenne et l’écart-type de nos données

moyenne_age <- mean(crabe$age, na.rm = TRUE)
ecart_type_age <- sd(crabe$age, na.rm = TRUE)

moyenne_poids <- mean(crabe$poids, na.rm = TRUE)
ecart_type_poids <- sd(crabe$poids, na.rm = TRUE)

moyenne_diametre <- mean(crabe$diametre, na.rm = TRUE)
ecart_type_diametre <- sd(crabe$diametre, na.rm = TRUE)

Test KS pour comparer nos données à une distribution normale

age.ks<-ks.test(crabe$age, "pnorm", mean = moyenne_age, sd = ecart_type_age)
Warning in ks.test.default(crabe$age, "pnorm", mean = moyenne_age, sd =
ecart_type_age): ties should not be present for the Kolmogorov-Smirnov test
age.ks

    Asymptotic one-sample Kolmogorov-Smirnov test

data:  crabe$age
D = 0.14369, p-value < 2.2e-16
alternative hypothesis: two-sided
poids.ks<-ks.test(crabe$poids, "pnorm", mean = moyenne_poids, sd = ecart_type_poids)
Warning in ks.test.default(crabe$poids, "pnorm", mean = moyenne_poids, sd =
ecart_type_poids): ties should not be present for the Kolmogorov-Smirnov test
poids.ks

    Asymptotic one-sample Kolmogorov-Smirnov test

data:  crabe$poids
D = 0.046722, p-value = 9.026e-08
alternative hypothesis: two-sided
diametre.ks<-ks.test(crabe$diametre, "pnorm", mean = moyenne_diametre, sd = ecart_type_diametre)
Warning in ks.test.default(crabe$diametre, "pnorm", mean = moyenne_diametre, :
ties should not be present for the Kolmogorov-Smirnov test
diametre.ks

    Asymptotic one-sample Kolmogorov-Smirnov test

data:  crabe$diametre
D = 0.080708, p-value < 2.2e-16
alternative hypothesis: two-sided

Nous avons par la suite effectué les tests de Kolmogorov-Smirnov, notre échantillon étant composé de plus de 50 observations. Ces tests confirment ce qu’on a constaté avec les Q-Q plots, nos variables ne présentent pas une distribution normale. De ce fait, nous excluons l’option de remplacement par la moyenne.

Matrice de corrélation

crabe |>
  select(longueur:age) |>
  drop_na() |>
  cor() |>
  corrplot::corrplot.mixed()

Nous observons une corrélation existante entre les variables âge, diamètre et poids.

Risque de multicolinarité

Les variables longueur, diamètre, hauteur, poids, poids.chair, poids.visceres, et poids.coquille ont des coefficients supérieurs à 0.9. Dans le cadre de notre projet, l’objectif est d’utiliser la régression pour prédire et imputer des valeurs manquantes plutôt que pour l’inférence statistique, la multicolinéarité est un peu moins problématique. Cependant, elle peut affecter la stabilité des coefficients de régression utilisés dans l’imputation.

Ainsi, pour la suite, nous opterons pour des méthodes d’imputation plus robustes telles que l’imputation MICE (Multiple Imputation by Chained Equations) et la méthode basée sur l’Analyse en Composantes Principales (ACP), ainsi qu’un remplacement global des valeurs manquantes.

Deuxième méthode de remplacement : l’imputation MICE des valeurs manquantes pour l’age, le poids, diamètre

md.pattern(crabe_mice, rotate.names = TRUE)

     sexe longueur hauteur poids.chair poids.visceres poids.coquille age
3843    1        1       1           1              1              1   1
19      1        1       1           1              1              1   1
16      1        1       1           1              1              1   1
15      1        1       1           1              1              1   0
        0        0       0           0              0              0  15
     diametre poids   
3843        1     1  0
19          1     0  1
16          0     1  1
15          1     1  1
           16    19 50

Nous pouvons donc observer nos 50 valeurs manquantes réparties dans nos trois variables. Chaque valeur manquante n’est que dans une seule variable par observation.

Nous allons par la suite imputer les valeurs manquantes par plusieurs méthodes telles que Prédictive Mean Matching et Random Forest :

  • PMM() : pour une observation avec une valeur manquante, la méthode trouve un ensemble d’observations (par exemple, les plus proches voisins) dans les données complètes dont les valeurs prédites par le modèle sont proches de la valeur prédite pour l’observation manquante.

  • RF (Forêt aléatoire) : dans une forêt aléatoire, chaque arbre de décision est entraîné sur un sous-ensemble de données et un sous-ensemble de caractéristiques. La prédiction finale résulte de la moyenne des prédictions de tous les arbres individuels.

Aléatoire

crabe_mice_aleatoire <- mice(crabe_mice, m = 5)

 iter imp variable
  1   1  diametre  poids  age
  1   2  diametre  poids  age
  1   3  diametre  poids  age
  1   4  diametre  poids  age
  1   5  diametre  poids  age
  2   1  diametre  poids  age
  2   2  diametre  poids  age
  2   3  diametre  poids  age
  2   4  diametre  poids  age
  2   5  diametre  poids  age
  3   1  diametre  poids  age
  3   2  diametre  poids  age
  3   3  diametre  poids  age
  3   4  diametre  poids  age
  3   5  diametre  poids  age
  4   1  diametre  poids  age
  4   2  diametre  poids  age
  4   3  diametre  poids  age
  4   4  diametre  poids  age
  4   5  diametre  poids  age
  5   1  diametre  poids  age
  5   2  diametre  poids  age
  5   3  diametre  poids  age
  5   4  diametre  poids  age
  5   5  diametre  poids  age
Warning: Number of logged events: 1
crabe_mice_aleatoire$imp
$sexe
[1] 1 2 3 4 5
<0 rows> (or 0-length row.names)

$longueur
[1] 1 2 3 4 5
<0 rows> (or 0-length row.names)

$diametre
          1      2      3      4      5
195  39.624 41.148 39.624 38.862 38.481
211  34.290 33.147 33.909 33.528 32.385
348  34.671 36.195 34.671 36.195 36.576
1038 39.624 39.624 39.624 38.862 39.243
1614 14.478 14.097 14.097 14.097 14.097
1790 21.717 22.479 20.955 20.955 22.860
1842 39.624 41.148 41.529 40.005 39.243
1866 39.624 38.100 37.338 39.243 36.957
1895 30.480 29.337 30.480 30.099 30.480
2013 33.909 31.623 34.290 33.147 33.909
2074 27.051 27.051 27.432 26.670 26.670
2592 34.671 35.433 34.290 33.147 34.290
2888 20.574 21.717 23.622 24.003 20.574
3693 32.385 32.766 31.623 34.290 33.528
3721 29.718 29.337 29.337 31.242 28.575
3840 19.050 19.812 19.050 20.193 19.812

$hauteur
[1] 1 2 3 4 5
<0 rows> (or 0-length row.names)

$poids
             1         2         3         4         5
555  0.3725122 0.3596531 0.3307201 0.3596531 0.3913991
665  1.0315414 1.0335507 0.9993937 1.0214953 0.9993937
1115 0.8511121 0.8708026 0.9226409 0.9226409 0.9178187
1142 0.3785399 0.3873806 0.3938101 0.3913991 0.4191265
1167 0.7410060 0.6984102 0.6984102 0.7128767 0.7494448
1268 0.5236067 0.5300363 0.5191864 0.4753851 0.5280271
1627 0.3262998 0.3443829 0.3359442 0.3415700 0.3142444
1673 0.5171772 0.5027107 0.5171772 0.4826183 0.5091402
1799 1.7637068 1.7464274 1.7464274 1.7464274 1.7464274
2227 0.9138002 0.8824562 0.9431351 0.9700588 0.9700588
2463 1.4824139 1.4824139 1.4599104 1.5864923 1.4599104
2538 1.0652966 1.1062850 1.1175367 1.0773520 1.0869963
2641 0.3528217 0.3496070 0.3443829 0.3283091 0.3403645
2757 0.4673481 0.4737777 0.4902534 0.4633297 0.4673481
2971 0.8503084 0.8760266 0.8667841 0.8511121 0.8358419
2980 0.3958194 0.3873806 0.3938101 0.3913991 0.3966231
2986 0.4323875 0.4356022 0.4147062 0.4323875 0.4356022
3371 0.3186647 0.3041982 0.3106278 0.3041982 0.3262998
3446 0.4609186 0.4962811 0.4906553 0.4773943 0.4609186

$poids.chair
[1] 1 2 3 4 5
<0 rows> (or 0-length row.names)

$poids.visceres
[1] 1 2 3 4 5
<0 rows> (or 0-length row.names)

$poids.coquille
[1] 1 2 3 4 5
<0 rows> (or 0-length row.names)

$age
      1  2  3  4  5
373   6  6  5  5  6
526  11 13 10 13  9
905   9 11 14  9  9
953  14  9 12 10  9
1011  8 11  9  8  8
1017  9  9  9 10  9
1047  7  8  8 10  6
1253 17 10  9 14  9
1379 10  9  9  7 10
1450  8 11  5  8  9
2511 10 11 13  7 11
2567 12  9 10  9  9
2650 12 10 11 11 19
2892  8  8 10 11  9
2985 10  8 11 15 12
crabe_mice_aleatoire$method
          sexe       longueur       diametre        hauteur          poids 
            ""             ""          "pmm"             ""          "pmm" 
   poids.chair poids.visceres poids.coquille            age 
            ""             ""             ""          "pmm" 
plot(crabe_mice_aleatoire)

Lorsque nous effectuons la méthode de manière aléatoire, le logiciel propose d’effectuer l’imputation avec la méthode PMM.

Imputation par la PMM

meth_pmm <- c("", "", "pmm", "", "pmm", "", "", "", "pmm")
set.seed(123)
crabe_pmm <- mice(crabe_mice, method = meth_pmm, m = 6, maxit = 6)

 iter imp variable
  1   1  diametre  poids  age
  1   2  diametre  poids  age
  1   3  diametre  poids  age
  1   4  diametre  poids  age
  1   5  diametre  poids  age
  1   6  diametre  poids  age
  2   1  diametre  poids  age
  2   2  diametre  poids  age
  2   3  diametre  poids  age
  2   4  diametre  poids  age
  2   5  diametre  poids  age
  2   6  diametre  poids  age
  3   1  diametre  poids  age
  3   2  diametre  poids  age
  3   3  diametre  poids  age
  3   4  diametre  poids  age
  3   5  diametre  poids  age
  3   6  diametre  poids  age
  4   1  diametre  poids  age
  4   2  diametre  poids  age
  4   3  diametre  poids  age
  4   4  diametre  poids  age
  4   5  diametre  poids  age
  4   6  diametre  poids  age
  5   1  diametre  poids  age
  5   2  diametre  poids  age
  5   3  diametre  poids  age
  5   4  diametre  poids  age
  5   5  diametre  poids  age
  5   6  diametre  poids  age
  6   1  diametre  poids  age
  6   2  diametre  poids  age
  6   3  diametre  poids  age
  6   4  diametre  poids  age
  6   5  diametre  poids  age
  6   6  diametre  poids  age
Warning: Number of logged events: 1
crabe_pmm$imp
$sexe
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$longueur
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$diametre
          1      2      3      4      5      6
195  38.862 38.862 39.243 38.481 39.243 38.481
211  33.528 34.290 32.004 33.528 33.528 32.766
348  35.433 35.814 34.671 36.576 36.195 35.433
1038 39.243 38.481 39.624 39.624 39.624 41.910
1614 13.716 14.097 13.716 14.097 14.478 13.716
1790 20.955 21.717 21.717 23.622 22.479 21.717
1842 41.529 40.005 41.148 41.529 40.005 39.243
1866 38.100 36.957 38.100 37.338 38.862 38.481
1895 30.861 30.480 29.718 30.099 30.480 30.099
2013 34.671 31.242 33.528 33.909 33.909 33.528
2074 26.670 27.432 27.432 26.670 25.146 26.670
2592 33.909 34.290 35.814 34.290 33.147 32.766
2888 21.717 22.860 23.241 22.860 22.479 21.336
3693 33.528 33.909 35.052 33.528 32.004 35.052
3721 28.575 28.956 29.337 31.242 30.480 30.480
3840 19.431 19.431 19.812 19.050 18.669 19.812

$hauteur
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$poids
             1         2         3         4         5         6
555  0.3592513 0.3913991 0.3913991 0.3556347 0.3913991 0.3576439
665  0.9993937 1.0476153 1.0162713 0.9993937 1.0022066 1.0162713
1115 0.8511121 0.8708026 0.8908950 0.8217773 0.8812506 0.8908950
1142 0.4114914 0.3978286 0.3785399 0.4010434 0.3913991 0.3966231
1167 0.7385949 0.7518559 0.7229229 0.7213155 0.7385949 0.7518559
1268 0.5236067 0.5280271 0.5288308 0.5043181 0.5288308 0.5441009
1627 0.3142444 0.3415700 0.3781381 0.3142444 0.3359442 0.3415700
1673 0.4826183 0.4998978 0.4978885 0.5087384 0.5023088 0.5111495
1799 1.7464274 1.7637068 1.7464274 1.7689308 1.7761641 1.7689308
2227 0.9109873 0.9495646 0.9431351 1.0315414 1.0315414 0.9085762
2463 1.5109450 1.4920582 1.5213930 1.5141598 1.5213930 1.4920582
2538 1.0869963 1.0869963 1.0652966 1.0580633 1.0745391 1.0701188
2641 0.3275054 0.3283091 0.3387571 0.3283091 0.3283091 0.3351405
2757 0.4625260 0.4790017 0.4665445 0.4790017 0.4918608 0.4790017
2971 0.8531213 0.8531213 0.8531213 0.8358419 0.8358419 0.8032923
2980 0.4046600 0.4046600 0.3938101 0.3913991 0.4010434 0.3841658
2986 0.4022489 0.4243505 0.3946138 0.4243505 0.4159117 0.4022489
3371 0.3190666 0.3190666 0.3262998 0.3146463 0.3262998 0.3226832
3446 0.4713666 0.5019070 0.4922627 0.4794036 0.4922627 0.4524798

$poids.chair
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$poids.visceres
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$poids.coquille
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$age
      1  2  3  4  5  6
373   6  6  7  7  6 13
526  10 11 11 15  9 11
905  11  9 10 13 11 10
953  10 10  9 11  9  9
1011  9 10  8 13  9 10
1017 10 10 12  8 11 12
1047  9  9 11  9  8  9
1253  9  9 12  9 13  9
1379  8  8 13 10  9  9
1450  5  6  9  6  7 10
2511  9 10  8  8 10 11
2567 10 10  9 11  7 10
2650 13  9 23  8  9 10
2892  8 12  9 12 11  7
2985  9 10 11 11 10 15
plot(crabe_pmm, main="Plot selon la méthode pmm")

Imputation par la RF

set.seed(123)
meth_rf <- c("", "", "rf", "", "rf", "", "", "", "rf")
crabe_rf <- mice(crabe_mice, method = meth_rf, m = 6, maxit = 6, )

 iter imp variable
  1   1  diametre  poids  age
  1   2  diametre  poids  age
  1   3  diametre  poids  age
  1   4  diametre  poids  age
  1   5  diametre  poids  age
  1   6  diametre  poids  age
  2   1  diametre  poids  age
  2   2  diametre  poids  age
  2   3  diametre  poids  age
  2   4  diametre  poids  age
  2   5  diametre  poids  age
  2   6  diametre  poids  age
  3   1  diametre  poids  age
  3   2  diametre  poids  age
  3   3  diametre  poids  age
  3   4  diametre  poids  age
  3   5  diametre  poids  age
  3   6  diametre  poids  age
  4   1  diametre  poids  age
  4   2  diametre  poids  age
  4   3  diametre  poids  age
  4   4  diametre  poids  age
  4   5  diametre  poids  age
  4   6  diametre  poids  age
  5   1  diametre  poids  age
  5   2  diametre  poids  age
  5   3  diametre  poids  age
  5   4  diametre  poids  age
  5   5  diametre  poids  age
  5   6  diametre  poids  age
  6   1  diametre  poids  age
  6   2  diametre  poids  age
  6   3  diametre  poids  age
  6   4  diametre  poids  age
  6   5  diametre  poids  age
  6   6  diametre  poids  age
Warning: Number of logged events: 1
crabe_rf$imp
$sexe
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$longueur
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$diametre
          1      2      3      4      5      6
195  40.767 40.005 43.053 44.196 41.148 40.767
211  33.528 33.909 34.290 32.766 31.242 31.623
348  33.909 35.814 35.433 34.671 35.814 34.290
1038 40.005 39.243 40.005 38.481 41.148 38.100
1614 14.859 13.716 13.716 14.478 14.097 13.335
1790 23.622 22.098 22.860 22.479 22.479 22.860
1842 40.767 38.862 40.005 41.148 40.386 40.005
1866 36.576 38.100 35.433 39.243 38.862 38.481
1895 29.337 29.718 29.718 30.861 33.147 30.099
2013 32.766 34.290 33.528 32.766 34.290 34.290
2074 27.051 26.670 28.194 27.051 27.813 28.575
2592 34.671 34.671 35.433 34.290 34.671 33.528
2888 28.194 26.289 27.813 27.813 20.574 28.956
3693 33.147 32.385 33.147 35.433 32.004 33.528
3721 28.194 31.242 29.718 30.861 29.718 30.099
3840 19.050 19.812 19.812 20.193 15.621 19.431

$hauteur
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$poids
             1         2         3         4         5         6
555  0.3520180 0.3158518 0.3837640 0.3664845 0.3644753 0.3837640
665  1.0918185 1.0255137 0.9853290 0.9198280 1.0701188 0.9853290
1115 0.8495047 0.8495047 0.7803870 0.7988720 0.8282068 0.8008812
1142 0.4167154 0.4263597 0.3753252 0.5119532 0.4130988 0.4287708
1167 0.7430152 0.6546089 0.6449646 0.7036342 0.7076527 0.7277451
1268 0.4769925 0.4633297 0.5617822 0.5091402 0.5549508 0.4633297
1627 0.3013853 0.3106278 0.3230850 0.3013853 0.2684338 0.3371497
1673 0.5123550 0.5123550 0.5224012 0.5436991 0.5726321 0.5075329
1799 1.7464274 1.5306355 1.7761641 2.1354154 1.6110049 1.7966583
2227 0.7920406 0.8764285 0.7393986 0.7715464 0.9644330 1.0435969
2463 1.1561140 1.4120906 1.4599104 1.5519334 1.7464274 1.5326447
2538 1.0906130 1.0669040 1.0504283 1.0427932 0.9487609 1.1870563
2641 0.3226832 0.2985724 0.1056858 0.3271035 0.3391589 0.3226832
2757 0.4970848 0.4649371 0.4544890 0.4621241 0.4540872 0.4247524
2971 0.8844654 0.9278649 0.8559343 0.8491029 0.8852691 0.8683915
2980 0.4159117 0.3733159 0.3701012 0.3950157 0.3845677 0.3789418
2986 0.3475977 0.3596531 0.3479996 0.4396207 0.4472558 0.4392189
3371 0.3182629 0.3488033 0.3158518 0.3037964 0.3415700 0.3210758
3446 0.5441009 0.5091402 0.4998978 0.4942719 0.5111495 0.4544890

$poids.chair
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$poids.visceres
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$poids.coquille
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$age
      1  2  3  4  5  6
373   6  8  6  5  6  6
526  11 12 13  8 10  9
905  10  9 13  9 19 10
953   9 19  9 12  9  8
1011  8  8  9  8  9  8
1017  9  8 10 10  8 10
1047  7 13 10 10  8 16
1253 11 10  7 10  9 17
1379  9 11 11 12  9 10
1450  9  9  9  8  9  8
2511  8  9  9  9 11  8
2567  9  8 11  9  9  9
2650  9  9 10 12  8 11
2892 11 10 10 15 10  8
2985 19 12 10 15 11 10
plot(crabe_rf, main="Plot selon la méthode rf")

Imputation mix entre PMM et RF

meth_mix <- c("", "", "pmm", "", "pmm", "", "", "", "rf")
set.seed(123)
crabe_mix <- mice(crabe_mice, method = meth_mix,m = 6, maxit = 6)

 iter imp variable
  1   1  diametre  poids  age
  1   2  diametre  poids  age
  1   3  diametre  poids  age
  1   4  diametre  poids  age
  1   5  diametre  poids  age
  1   6  diametre  poids  age
  2   1  diametre  poids  age
  2   2  diametre  poids  age
  2   3  diametre  poids  age
  2   4  diametre  poids  age
  2   5  diametre  poids  age
  2   6  diametre  poids  age
  3   1  diametre  poids  age
  3   2  diametre  poids  age
  3   3  diametre  poids  age
  3   4  diametre  poids  age
  3   5  diametre  poids  age
  3   6  diametre  poids  age
  4   1  diametre  poids  age
  4   2  diametre  poids  age
  4   3  diametre  poids  age
  4   4  diametre  poids  age
  4   5  diametre  poids  age
  4   6  diametre  poids  age
  5   1  diametre  poids  age
  5   2  diametre  poids  age
  5   3  diametre  poids  age
  5   4  diametre  poids  age
  5   5  diametre  poids  age
  5   6  diametre  poids  age
  6   1  diametre  poids  age
  6   2  diametre  poids  age
  6   3  diametre  poids  age
  6   4  diametre  poids  age
  6   5  diametre  poids  age
  6   6  diametre  poids  age
Warning: Number of logged events: 1
crabe_mix$imp
$sexe
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$longueur
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$diametre
          1      2      3      4      5      6
195  38.862 37.719 39.243 38.481 38.862 38.862
211  30.480 29.718 32.385 34.290 32.004 33.909
348  35.433 35.814 36.576 35.814 36.195 36.195
1038 39.624 38.481 39.243 38.481 39.624 39.624
1614 14.859 14.097 14.859 14.478 14.478 14.478
1790 20.574 20.574 21.717 20.955 21.336 23.622
1842 39.243 41.148 40.005 40.767 38.481 39.243
1866 38.100 38.100 39.624 38.481 37.719 38.481
1895 30.099 30.099 29.337 29.337 30.480 30.099
2013 32.385 33.528 32.766 33.528 33.528 32.385
2074 27.432 27.051 26.289 27.432 26.289 26.670
2592 33.909 34.290 36.195 34.290 34.290 33.909
2888 21.336 20.574 22.860 22.860 22.860 23.622
3693 34.290 33.147 35.052 33.528 33.909 35.052
3721 31.242 30.480 30.099 28.575 30.480 28.575
3840 19.431 19.431 20.193 19.431 19.050 19.812

$hauteur
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$poids
             1         2         3         4         5         6
555  0.3753252 0.3604568 0.3905954 0.3644753 0.3692975 0.3592513
665  1.0222990 1.0158694 0.9977863 0.9977863 1.0142620 0.9977863
1115 1.0407839 0.8732137 0.9178187 0.8752229 0.8217773 0.9226409
1142 0.3873806 0.3978286 0.4130988 0.4191265 0.3785399 0.3978286
1167 0.7128767 0.7044379 0.8044978 0.7518559 0.7329691 0.7385949
1268 0.5441009 0.5280271 0.5215975 0.5441009 0.5304381 0.5441009
1627 0.3262998 0.3311220 0.3781381 0.3387571 0.3142444 0.3142444
1673 0.5027107 0.4826183 0.5171772 0.5091402 0.4978885 0.5027107
1799 1.7464274 1.7637068 1.9135958 1.9135958 1.7689308 1.7464274
2227 0.8776340 0.9652367 0.9495646 0.8824562 0.9226409 0.9495646
2463 1.5109450 1.5897070 1.5864923 1.5141598 1.4824139 1.5141598
2538 1.0745391 1.0652966 1.0994536 1.0693151 1.0532412 1.0604744
2641 0.3391589 0.3347386 0.3283091 0.3528217 0.3387571 0.3283091
2757 0.4625260 0.4625260 0.4665445 0.4673481 0.4665445 0.4681518
2971 0.8772322 0.8667841 0.8503084 0.9065670 0.8478973 0.8603546
2980 0.3479996 0.3990341 0.3958194 0.3958194 0.3938101 0.4046600
2986 0.4468539 0.4231450 0.4356022 0.4319856 0.4243505 0.4468539
3371 0.3371497 0.3319257 0.3262998 0.3070112 0.3041982 0.3166555
3446 0.4886460 0.4609186 0.4962811 0.4725722 0.4886460 0.4886460

$poids.chair
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$poids.visceres
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$poids.coquille
[1] 1 2 3 4 5 6
<0 rows> (or 0-length row.names)

$age
      1  2  3  4  5  6
373   6  9  6  6  5  5
526  10 11 11  9 10 10
905  10  9 15 11 14  9
953  13 10 12 12 12 17
1011  8  8  8  8  8  9
1017 11  9 11 12 11  8
1047 10 12 12  7  9 12
1253 10 10 11  8 15 12
1379 12  9  8 12  9 12
1450  8  9  9  7  9  9
2511 10  8 10  9  9 10
2567  8 10  8  9  9 11
2650 11 14  9 10 10 11
2892 11  9 18 10  9 11
2985  9  8 18 12  8 10
names(crabe)
[1] "sexe"           "longueur"       "diametre"       "hauteur"       
[5] "poids"          "poids.chair"    "poids.visceres" "poids.coquille"
[9] "age"           
plot(crabe_mix, main="Plot avec la méthode mix")

Nous observons donc que la méthode de remplacement par la PMM n’est pas optimale, choisissons donc l’imputation par la méthode de random forest.

Après avoir analysé les graphiques, nous pouvons dire que la meilleure itération est la 2ème, c’est pourquoi nous procédons à l’imputation avec celle-ci.

Imputation des valeurs manquantes

crabe_complet_mice_rf2 <- mice::complete(crabe_rf, 2)

Vérification

md.pattern(crabe_complet_mice_rf2, rotate.names = TRUE)
 /\     /\
{  `---'  }
{  O   O  }
==>  V <==  No need for mice. This data set is completely observed.
 \  \|/  /
  `-----'

     sexe longueur diametre hauteur poids poids.chair poids.visceres
3893    1        1        1       1     1           1              1
        0        0        0       0     0           0              0
     poids.coquille age  
3893              1   1 0
                  0   0 0

Toutes les valeurs manquantes ont bien été imputées.

Troisième méthode: ACP (Analyse en composante principale)

La PCA est utilisée pour réduire la dimensionnalité des données tout en préservant autant que possible la variance des données. Elle s’effectue sur des variables exclusivement quantitatives.

Le principe est d’itérer entre l’estimation des composantes principales et l’imputation des valeurs manquantes jusqu’à contingence.

La PCA elle-même ne fait pas d’hypothèses sur la distribution des données. Elle cherche à capturer la structure linéaire (corrélation) entre les variables.

Dans le contexte de l’imputation, l’objectif est de remplacer les valeurs manquantes de manières à préserver la structure globale des données.

crabe_acp <- crabe_missMDA |>
  drop_na()

Cette première étape à permis de trier notre jeux de données en ne gardant que les valeurs non-manquantes afin d’effectuer l’ACP.

crabe_acp |>
    group_by(sexe) |>
    summarize(
      across(where(is.numeric),
             median) ) |>
                 ungroup()
# A tibble: 3 × 9
  sexe  longueur diametre hauteur poids poids.chair poids.visceres
  <chr>    <dbl>    <dbl>   <dbl> <dbl>       <dbl>          <dbl>
1 F         45.0     35.4   12.2  0.836       0.354         0.181 
2 I         33.1     25.5    8.38 0.308       0.136         0.0651
3 M         44.2     34.7   11.8  0.785       0.340         0.170 
# ℹ 2 more variables: poids.coquille <dbl>, age <dbl>
acp_simple <- crabe_acp |>
    select(- sexe) |>
    PCA()

Concernant le cercle de corrélation :

  • Nous observons dans un premier temps que l’axe 1 à une inertie de 85,3 %, ce qui signifie qu’il explique à lui seul 85,3 % de la variance totale des données. De plus, il représente de manière significative toutes nos variables, à l’exception de la variable age.

  • Les angles de nos variables sont fermés ce qui nous permet d’affirmer que nos variables sont très corrélées entre elles.

Concernant le graphique des individus :

  • On observe des clusters d’individus contribuant soit positivement soit négativement aux composantes principales.
acp_simple$eig
        eigenvalue percentage of variance cumulative percentage of variance
comp 1 6.826744442            85.33430552                          85.33431
comp 2 0.698233146             8.72791432                          94.06222
comp 3 0.187355572             2.34194465                          96.40416
comp 4 0.122746877             1.53433596                          97.93850
comp 5 0.082778256             1.03472820                          98.97323
comp 6 0.062872043             0.78590054                          99.75913
comp 7 0.012671889             0.15839862                          99.91753
comp 8 0.006597775             0.08247218                         100.00000
fviz_screeplot(acp_simple, addlabels = TRUE)

On peut donc confirmer que la dimension 1 explique à elle seule 85,3% de la variance.

crabe_sans_sexe <- crabe_acp |> select(-sexe)

res.pca<-PCA(crabe_sans_sexe)

contribution<-round(res.pca$var$contrib,2)

corrplot(contribution, is.corr=FALSE, method="circle", tl.srt=45, tl.col="#002200",
        col=brewer.pal(n=9, name="OrRd"), addCoef.col="black", main="Tableau des contributions")

Ce tableau des contributions permet de voir que toutes nos variables sont significatives pour la dimension 1 à l’exception de la variable âge qui est plus contributive pour la dimension 2.

acp <- PCA(
  X = crabe_acp,
  quali.sup = c("sexe"))

plot.PCA(acp, choix = "ind", label = "quali")

plot.PCA(acp, choix = "ind", habillage = "sexe", label = "none")

Nous avons ensuite cherché à visualiser les individus dans l’ACP, en leur attribuant des couleurs ou des étiquettes en fonction de certaines variables qualitatives (comme le genre dans le deuxième cas), ce qui facilite la compréhension de la distribution des individus dans l’espace des composantes principales.

acp$eig
        eigenvalue percentage of variance cumulative percentage of variance
comp 1 6.826744442            85.33430552                          85.33431
comp 2 0.698233146             8.72791432                          94.06222
comp 3 0.187355572             2.34194465                          96.40416
comp 4 0.122746877             1.53433596                          97.93850
comp 5 0.082778256             1.03472820                          98.97323
comp 6 0.062872043             0.78590054                          99.75913
comp 7 0.012671889             0.15839862                          99.91753
comp 8 0.006597775             0.08247218                         100.00000

Nous travaillerons avec les dimensions 1 et 2 qui explique à elles seules 92,5 % de la variance.

crabe_complet_acp <-  MIPCA(crabe_missMDA |> select(-sexe), scale=TRUE, ncp=2)

Nous procédons donc maintenant à l’analyse en composante principales multiple imputation en excluant la variable “sexe”, étant une variable qualitative, elle ne peut pas être utilisée dans l’acp qui est exclusivement quantitative. De plus, nous spécifions que nous travaillerons avec deux composantes principales avec le paramètre : ncp=2.

plot.MIPCA(crabe_complet_acp, choice = "dim")

$PlotDim

Le premier graphique après imputation est la projection de nos variables selon les deux premières dimensions de l’ACP.

Comme toutes les flèches sont proches soit de l’axes 1 soit de l’axe 2, cela signifie que les axes sont stables. Cette stabilité nous permet d’interpréter les résultats de notre ACP.

plot.MIPCA(crabe_complet_acp, choice = "var")

$PlotVar

Ce graphique spécifie que l’on souhaite visualiser les variables originales dans l’espace des deux premières dimensions de l’ACP. On observe dans notre cas que le graphique ne montre pas d’auréoles, les données ont donc bien été traitées et elles sont représentées de manière cohérente dans nos deux dimensions.

crabe_complet_acp <-
    bind_cols(
      crabe_missMDA |> select(sexe),
      crabe_complet_acp[["res.imputePCA"]])

Ensuite, nous ajoutons notre variables “sexe” à notre base de données imputées des valeurs manquantes.

md.pattern(crabe_complet_acp, rotate.names = TRUE)
 /\     /\
{  `---'  }
{  O   O  }
==>  V <==  No need for mice. This data set is completely observed.
 \  \|/  /
  `-----'

     sexe longueur diametre hauteur poids poids.chair poids.visceres
3893    1        1        1       1     1           1              1
        0        0        0       0     0           0              0
     poids.coquille age  
3893              1   1 0
                  0   0 0

Pour terminer, nous pouvons confirmer que toute nos variables ont bien été imputées.

Comparaison des deux analyses

rbind(tableau1, tableau2, tableau3)
           Mice          ACP Approche_retenue
1  0.0033393270 0.0022554586              Acp
2  0.0012722836 0.0023577737             Mice
3 -0.0001155065 0.0001045964             Mice

En observant les résultats, nous pouvons conclure que la meilleure approche pour notre base de données est l’imputation MICE puisqu’elle domine sur deux de nos variables.

Analyse descriptive sans N/A

 summary(crabe_complet_mice_rf2)
     sexe              longueur         diametre         hauteur      
 Length:3893        Min.   : 5.715   Min.   : 4.191   Min.   : 0.000  
 Class :character   1st Qu.:34.290   1st Qu.:26.670   1st Qu.: 8.763  
 Mode  :character   Median :41.529   Median :32.385   Median :11.049  
                    Mean   :39.969   Mean   :31.116   Mean   :10.623  
                    3rd Qu.:46.863   3rd Qu.:36.576   3rd Qu.:12.573  
                    Max.   :62.103   Max.   :49.530   Max.   :19.050  
     poids           poids.chair        poids.visceres      poids.coquille    
 Min.   :0.001607   Min.   :0.0008037   Min.   :0.0004018   Min.   :0.001205  
 1st Qu.:0.359251   1st Qu.:0.1514963   1st Qu.:0.0755473   1st Qu.:0.105284  
 Median :0.646170   Median :0.2704431   Median :0.1378335   Median :0.188868  
 Mean   :0.668005   Mean   :0.2893730   Mean   :0.1456185   Mean   :0.192659  
 3rd Qu.:0.929472   3rd Qu.:0.4046600   3rd Qu.:0.2041383   3rd Qu.:0.265219  
 Max.   :2.270838   Max.   :1.1958969   Max.   :0.6108076   Max.   :0.807713  
      age        
 Min.   : 1.000  
 1st Qu.: 8.000  
 Median :10.000  
 Mean   : 9.958  
 3rd Qu.:11.000  
 Max.   :29.000  

En réexaminant les statistiques de notre jeu de données corrigé et en les comparant à l’analyse exploratoire initiale, nous observons que :

  • La moyenne de la variable « hauteur » a été légèrement ajustée, passant de 10,649 à 10,623, tandis que la médiane est restée inchangée à 11,049.
  • Concernant l’âge, la moyenne a été légèrement modifiée, évoluant de 9,955 à 9,958, sans pour autant altérer significativement l’interprétation de la distribution.
  • Les autres statistiques relatives à la longueur, au diamètre, au poids, au poids de la chair, au poids des viscères et au poids de la coquille sont identiques à celles énoncées dans la description initiale.

Analyse descriptive univariée

Les variables quantitatives sont longueur, diamètre, hauteur, poids, poids de la chair, poids des viscères, poids de la coquille et âge.

Et nous avons une seule variable qualitative: le sexe.

Variable Qualitative

Tableau de contingence

count(crabe_complet_mice_rf2, sexe)
  sexe    n
1    F 1225
2    I 1233
3    M 1435

Nous avons trois catégories de sexe : femelle (F), indéterminé (I) et mâle (M), avec respectivement 1225, 1233 et 1435 individus dans chaque catégorie.

Variables quantitatives

Boite à moustache

crabe_complet_mice_rf2 |>
    pivot_longer(
    cols = where(is.numeric)
    ) |>
    ggplot() +
    aes(y = value) +
    facet_wrap(~ name, scales = "free_y") +
    geom_boxplot() +
    theme_light()

Après avoir vérifié et corrigé les deux valeurs aberrantes pour la variable « hauteur », nous avons décidé de conserver les valeurs extrêmes présentes pour les autres variables de type poids et taille. De même, concernant l’âge, étant donné que la longévité d’un crabe peut atteindre 3 à 4 ans et que nos données incluent des valeurs jusqu’à 30 mois, soit 2,5 ans, ces observations sont jugées cohérentes avec le comportement naturel des crabes.

Histogrammes

Pour enrichir l’analyse, nous visualisons la forme de la distribution à l’aide d’histogrammes et superposons une courbe de densité. Cela nous permet d’évaluer visuellement la normalité de la distribution et de souligner les modes ainsi que les asymétries.

#| warning: false
ggplot(crabe_complet_mice_rf2, aes(x = longueur)) +
  geom_histogram(aes(y = ..density..), binwidth = 1, fill = "blue", color = "black", alpha = 0.4) +
  geom_density(color = "red", size = 1) +  
  labs(title = "Distribution de la longueur ", x = "Longueur", y = "Densité") +  
  theme_minimal()
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
ℹ Please use `after_stat(density)` instead.

La distribution présente une légère asymétrie à droite. Cela signifie qu’il y a une proportion de crabes qui ont des longueurs plus grandes que la moyenne.

ggplot(crabe, aes(x = diametre)) +
  geom_histogram(aes(y = ..density..), binwidth = 1, fill = "blue", color = "black", alpha = 0.4) +  
  geom_density(color = "red", size = 1) +  
  labs(title = "Distribution du diamètre  avec courbe de densité",
    x = "Diamètre",
    y = "Densité") +
  theme_minimal()

La distribution du diamètre n’est pas symétrique ; elle présente une forme qui semble multimodale et qui n’est pas normale en raison de ses multiples pics.

ggplot(crabe_complet_mice_rf2, aes(x = hauteur)) +
  geom_histogram(aes(y = ..density..), binwidth = 0.5, fill = "blue",color = "black", alpha = 0.6) +
  geom_density(color = "red", size = 1) +
  labs(title = "Distribution de la hauteur ", x = "Hauteur", y = "Densité") +
  theme_minimal()

Le graphique nous montre une distribution de la hauteur des crabes qui semble être multimodale, car il y a plusieurs pics.

ggplot(crabe_complet_mice_rf2, aes(x = poids)) +
  geom_histogram(aes(y = ..density..), binwidth = 0.1, fill = "orange", color = "black", alpha = 0.6) +
  geom_density(color = "red", size = 1) +
  labs(title = "Distribution du poids ", x = "Poids", y = "Densité") +
  theme_minimal()

ggplot(crabe_complet_mice_rf2, aes(x = poids.chair)) +
  geom_histogram(aes(y = ..density..), binwidth = 0.01, fill = "orange",  alpha = 0.6) +
  geom_density(color = "red", size = 1) +
  labs(title = "Distribution du poids de chair ", x = "Poids de chair", y = "Densité") +
  theme_minimal()

ggplot(crabe_complet_mice_rf2, aes(x = poids.visceres)) +
  geom_histogram(aes(y = ..density..), binwidth = 0.01, fill = "orange",  alpha = 0.6) +
  geom_density(color = "red", size = 1) +
  labs(title = "Distribution du poids des viscères ", x = "Poids des viscères", y = "Densité") +
  theme_minimal()

ggplot(crabe_complet_mice_rf2, aes(x = poids.coquille)) +
  geom_histogram(aes(y = ..density..), binwidth = 0.01, fill = "orange",  alpha = 0.6) +
  geom_density(color = "red", size = 1) +
  labs(title = "Distribution du poids de la coquille ", x = "Poids de la coquille", y = "Densité") +
  theme_minimal()

Les poids de viscères, de la coquille et de la chair, pressentent des distribution asymétriques à droite, avec une concentration plus élevée de valeurs faibles et une queue qui s’étend vers des valeurs plus élevées.

ggplot(crabe_complet_mice_rf2, aes(x = age)) +
  geom_histogram(aes(y = ..density..), binwidth = 1, fill = "blue", alpha = 0.6) +
  geom_density(color = "red", size = 1) +
  labs(title = "Distribution de l'âge ", x = " ge", y = "Densité") +
  theme_minimal()

La queue de la distribution s’étend jusqu’à environ 30 mois, avec une diminution progressive de la densité au fur et à mesure que l’âge augmente, indiquant moins de crabes plus âgés.

Analyse Bivariée

Quantitative - Quantitative

 ggplot(crabe, aes(x = age, y = diametre, color = sexe)) +
  geom_point() +
  scale_color_manual(values = vecteur_couleur) +  
  theme_minimal() +  
  labs(title = "Relation entre l'âge et le diamètre ",
    x = " ge",
    y = "Diamètre")  

Nous pouvons observer une tendance positive entre l’âge et le diamètre, ce qui signifie que, en général, le diamètre des crabes augmente avec l’âge. Et on peut aussi observer que les crabes de sexe indéfini sont très présents jusqu’à l’âge de 10 mois.

Corrélation (variables type poids)

cor(crabe_complet_mice_rf2[c("poids", "poids.chair", "poids.visceres", "poids.coquille")])
                   poids poids.chair poids.visceres poids.coquille
poids          1.0000000   0.9689417      0.9655096      0.9552759
poids.chair    0.9689417   1.0000000      0.9312796      0.8824063
poids.visceres 0.9655096   0.9312796      1.0000000      0.9061047
poids.coquille 0.9552759   0.8824063      0.9061047      1.0000000

En ce qui concerne la relation entre le “poids”, “poids.chair”, “poids.visceres”, “poids.coquille” les fortes corrélations indiquent que les différentes mesures de poids sont interdépendantes, ce qui n’est pas surprenant compte tenu de leur nature biologique.

Les lignes de régression sont bien ajustées à la distribution des points, bien que quelques points éloignés (valeurs extrêmes) en particulier dans la plage supérieure des valeurs.

variables_quantitatives <- c("longueur", "diametre", "hauteur", "poids")

# Création de toutes les paires possibles sans répétition ni inversion
paires <- combn(variables_quantitatives, 2, simplify = FALSE)


graphiques <- map(paires, ~ ggplot(crabe_complet_mice_rf2, aes_string(x = .[1], y = .[2], color = "sexe")) +
    geom_point() +
    geom_smooth(method = "lm", se = FALSE) +
    scale_color_manual(values = vecteur_couleur) +
    labs(title = paste("Relation entre", .[1], "et", .[2])) +
    theme_classic()
)


graphiques
[[1]]


[[2]]


[[3]]


[[4]]


[[5]]


[[6]]

Toutes les relations que nous observons sont positives, par exemple la relation entre le diamètre et le poids signifie qu’à mesure que le diamètre augmente, le poids augmente aussi. La ligne de régression pour les femelles est légèrement supérieure à celle des mâles et des jeunes (I), indiquant que pour un même diamètre, les femelles ont tendance à être plus lourdes.

La relation linéaire entre longueur et diamètre, mais aussi le diamètre et la hauteur et elle est presque uniforme entre les sexes et les points autour des lignes de régression suggère une variance faible des résidus.

En examinant de plus près la répartition des points selon les catégories de sexe, nous constatons que les données des mâles et des femelles se superposent sur une large gamme de valeurs pour toutes les paires de variables étudiées, ce qui indique des caractéristiques similaires entre ces deux groupes. En revanche, les points représentant la catégorie indéterminée (I) se concentrent davantage sur les échelons inférieurs des variables mesurées, suggérant que les individus classés comme indéterminés tendent à avoir des longueurs, des diamètres et des poids inférieurs par rapport aux mâles et aux femelles.

Qualitative - quantitative

Afin d’examiner les relations entre nos variables quantitatives et notre variable qualitative, nous procédons à une visualisations deux à deux :

ggplot(crabe_complet_mice_rf2, aes(x = sexe, y = longueur)) +
  geom_boxplot() +
  labs(title = "Comparaison de la taille entre les sexes ", x = "Sexe", y = "Longueur")

Nous pouvons observer que la médiane semble être légèrement plus élevée pour les femelles que pour les mâles et aussi elles semblent avoir une étendue interquartile (entre le premier et le troisième quartile) plus étroite que celle des mâles. Cela indique que les longueurs des femelles sont moins dispersées autour de la médiane.

ggplot(crabe_complet_mice_rf2, aes(x = sexe, y = poids)) +
  geom_boxplot() +
  labs(title = "Comparaison du poids entre les sexes ", x = "Sexe", y = "Poids")

Les médianes semblent similaires entre les sexes.

ggplot(crabe_complet_mice_rf2) +
    aes(x = poids, fill = sexe) +
    geom_histogram(bins = 50) +
    scale_fill_manual(values = vecteur_couleur) +
    theme_bw()

Les crabes féminins et masculins ont des distributions similaires, avec une gamme de poids étendue, tandis que les indéterminées ont une distribution plus concentrée vers les poids inférieurs.

Fréquences en fonction du sexe

crabe_complet_mice_rf2 |>
  group_by(sexe, diametre) |>
  count()
# A tibble: 266 × 3
# Groups:   sexe, diametre [266]
   sexe  diametre     n
   <chr>    <dbl> <int>
 1 F         14.9     1
 2 F         16.0     1
 3 F         16.8     1
 4 F         17.1     2
 5 F         17.5     1
 6 F         19.0     1
 7 F         19.4     2
 8 F         19.8     3
 9 F         20.2     3
10 F         20.6     2
# ℹ 256 more rows
crabe_complet_mice_rf2 |>
  group_by(sexe, poids) |>
  count()
# A tibble: 3,093 × 3
# Groups:   sexe, poids [3,093]
   sexe   poids     n
   <chr>  <dbl> <int>
 1 F     0.0643     1
 2 F     0.113      1
 3 F     0.119      1
 4 F     0.125      1
 5 F     0.137      1
 6 F     0.149      1
 7 F     0.151      1
 8 F     0.154      1
 9 F     0.158      1
10 F     0.161      1
# ℹ 3,083 more rows
crabe_complet_mice_rf2 |>
  group_by(sexe, age) |>
  count()
# A tibble: 68 × 3
# Groups:   sexe, age [68]
   sexe    age     n
   <chr> <int> <int>
 1 F         5     4
 2 F         6    15
 3 F         7    39
 4 F         8   114
 5 F         9   220
 6 F        10   237
 7 F        11   185
 8 F        12   120
 9 F        13    85
10 F        14    54
# ℹ 58 more rows

Conclusion

Ainsi, notre base de données, visant à comprendre les caractéristiques des crabes de Boston, est complète. Les valeurs aberrantes, extrêmes et les valeurs manquantes ont été remplacées avec différentes méthodes telles que la régression linéaire et des méthodes d’imputation multiple comme la méthode MICE ou missMDA. Aussi, l’approche MICE est celle que nous avons retenue pour notre analyse descriptive finale, étant celle avec le moins de différence par rapport à la base de données d’origine.

De plus, à la suite de notre analyse descriptive, nous avons voulu montrer au travers d’une régression logistique (Annexe) une analyse permettant d’identifier les caractéristiques des crabes femelles et mâles afin de remplacer le sexe indéterminé, mais cela ne s’est pas révélé significatif.

Annexe: Régression Logistique

Base avec crabe jeune

crabe_jeune<-crabe |> filter (age<=9)

Boite à moustache avec crabe jeune

crabe_jeune |>
  pivot_longer(
    cols = where(is.numeric)
    ) |>
  ggplot() +
  aes(y = value) +
  facet_wrap(~ name, scales = "free_y") +
  geom_boxplot() +
  theme_light()
Warning: Removed 22 rows containing non-finite outside the scale range
(`stat_boxplot()`).

crabe_jeune|>
  pivot_longer(
    cols = longueur:age,
    names_to = "mesure",
    values_to = "valeur"
    ) |>
  ggplot() +
  aes(y = valeur, x = sexe, color = sexe) +
  geom_boxplot() +
  geom_jitter(alpha = 0.3) +
  scale_fill_manual(values = vecteur_couleur)+
  facet_wrap(~ mesure, scales = "free_y") +
  theme_bw()

Regresion

crabes_reg <- crabe_jeune |>
  mutate(sexe = case_when(
    sexe == "M" ~ 0,
    sexe == "F" ~ 1
    ))

count(crabes_reg, sexe)
  sexe    n
1    0  533
2    1  390
3   NA 1000
crabes_reg |>
  pivot_longer(
    cols = longueur:age,
    names_to = "mesure",
    values_to = "valeur"
    ) |>
  ggplot() +
  aes(y = valeur) +
  geom_boxplot() +
  facet_wrap(~ mesure, scales = "free_y") +
  theme_bw()
Warning: Removed 22 rows containing non-finite outside the scale range
(`stat_boxplot()`).

str(crabes_reg)
'data.frame':   1923 obs. of  9 variables:
 $ sexe          : num  1 0 NA NA 1 NA 0 0 NA NA ...
 $ longueur      : num  43.8 27.1 31.6 27.1 47.2 ...
 $ diametre      : num  35.8 19.8 23.6 20.2 35.4 ...
 $ hauteur       : num  12.57 6.48 7.62 6.48 10.67 ...
 $ poids         : num  0.698 0.153 0.225 0.196 0.813 ...
 $ poids.chair   : num  0.3496 0.0651 0.0916 0.0981 0.385 ...
 $ poids.visceres: num  0.1583 0.039 0.0454 0.0422 0.1917 ...
 $ poids.coquille: num  0.1913 0.0442 0.0784 0.0482 0.2049 ...
 $ age           : int  9 6 6 6 8 7 6 9 7 6 ...

Séparation des données en ensembles d’entraînement et de test

crabes_entrainement <- crabes_reg |>
  filter(!is.na(sexe)) |>
  slice_sample(prop = 0.8)

Vérification

crabes_verification <- anti_join(
  crabes_reg,
  crabes_entrainement

) |>
  filter(!is.na(sexe))
Joining with `by = join_by(sexe, longueur, diametre, hauteur, poids,
poids.chair, poids.visceres, poids.coquille, age)`

Régression logistique

regression_logistique <- glm(
  sexe ~ longueur + diametre + hauteur + poids + poids.chair + poids.visceres + poids.coquille + age,
  data = crabes_entrainement,
  family = binomial
)

car::Anova(regression_logistique)
Analysis of Deviance Table (Type II tests)

Response: sexe
               LR Chisq Df Pr(>Chisq)  
longueur         2.5231  1    0.11219  
diametre         0.0935  1    0.75978  
hauteur          0.0963  1    0.75633  
poids            0.3523  1    0.55283  
poids.chair      3.4108  1    0.06477 .
poids.visceres   0.0200  1    0.88750  
poids.coquille   0.4589  1    0.49813  
age              0.0015  1    0.96905  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Selon les résultats, aucun des prédicteurs n’est significatif au seuil traditionnel de 0.05, bien que poids.chair soit proche avec une valeur de p de 0.06477. Cela suggère qu’il pourrait y avoir une association entre le poids de la chair et le sexe des crabes.

regression_logistique2 <- glm(
  sexe ~ poids.chair,
  data = crabes_entrainement,
  family = binomial
)

car::Anova(regression_logistique2)
Analysis of Deviance Table (Type II tests)

Response: sexe
            LR Chisq Df Pr(>Chisq)    
poids.chair   11.391  1   0.000738 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
plot(regression_logistique2)