Prétraitement des données qualitatives avec Tidymodels : Les “step_?” indispensables

Les variables catégorielles sont couramment présentes dans les jeux de données. Bien que certains modèles, tels que les modèles basés sur les arbres de décision, puissent fonctionner sans prétraitement, d’autres modèles nécessitent une transformation des variables catégorielles. Dans cet article, je vais vous présenter brièvement les méthodes couramment utilisées pour l’encodage des variables catégorielles, ainsi que la mise en pratique de ces méthodes en utilisant le package recipe de Tidymodels.

Qu’est-ce que vous découvrirez dans cet article ?

    • Encodage en variables indicatrices (One-Hot Encoding)
    • Encodage ordinal ( Ordinal Encoding)
    • Regroupement des valeurs peu fréquentes +  One-Hot Encoding

 

Données pour illuster les exemples 

Les données que nous allons utiliser sont disponibles ici. Il s’agit d’un jeu de données décrivant des réclamations d’assurance automobile. Nous allons nous concentrer sur l’utilisation de seulement quatres variables de ce jeu de données.

  • MaritalStatus : état matrimonial de la personne qui a déposé la réclamation
  • Make : marque du véhicule impliqué dans l’accident
  • VehiclePrice : prix du véhicule impliqué dans l’accident
  • FraudFound_P : détermine si une fraude a été détectée dans la réclamation
library(tidymodels)
library(dplyr)
library(skimr)

#chargement des données et sélection des variables
data =  read_csv("data/fraud_oracle.csv")
data_subset = data  %>% select(FraudFound_P,MaritalStatus,Make,VehiclePrice)

# convertion des variables en facteur
data_subset <- data_subset %>% 
     mutate_at(vars(MaritalStatus,Make,VehiclePrice), as.factor

#afichage des 10 premières observations
data_subset %>% slice_head(n=10)
# A tibble: 10 × 4
   FraudFound_P MaritalStatus Make   VehiclePrice   
          <dbl> <fct>         <fct>  <fct>          
 1            0 Single        Honda  more than 69000
 2            0 Single        Honda  more than 69000
 3            0 Married       Honda  more than 69000
 4            0 Married       Toyota 20000 to 29000 
 5            0 Single        Honda  more than 69000
 6            0 Single        Honda  more than 69000
 7            0 Married       Honda  more than 69000
 8            0 Single        Honda  more than 69000
 9            0 Single        Honda  more than 69000
10            0 Married       Ford   more than 69000

 

Encodage en variables indicatrices (One-Hot Encoding)

C’est une méthode de transformation des variables catégorielles dans laquelle chaque modalité de la variable est représentée par une variable binaire (0 ou 1). Cette méthode permet de représenter les variables catégorielles sous forme de variables numériques tout en conservant l’information sur les catégories. Toutefois, l’un des inconvénients de cette méthode est qu’elle crée une variable indicatrice pour chaque modalité de la variable catégorielle, ce qui peut entraîner une augmentation significative du nombre de variables dans le jeu de données. 

Pour illustrer cela, nous allons encoder la variable MaritalStatus définit précedement. cette variable à 4 modalités.

levels(data_subset$MaritalStatus)
[1] "Divorced" "Married" "Single" "Widow"

Avec le package tidymodels, la méthode d’encodage en variables indicatrices (ou One-Hot Encoding) est implémentée avec la fonction step_dummy() de recipe.

recipe_1 = recipe(FraudFound_P ~ MaritalStatus,data=data_subset) %>% 
  step_dummy(MaritalStatus)

recipe_1 %>% prep() %>% juice()
# A tibble: 15,420 × 4
   FraudFound_P MaritalStatus_Married MaritalStatus_Single MaritalStatus_Widow
          <dbl>                 <dbl>                <dbl>               <dbl>
 1            0                     0                    1                   0
 2            0                     0                    1                   0
 3            0                     1                    0                   0
 4            0                     1                    0                   0
 5            0                     0                    1                   0
 6            0                     0                    1                   0
 7            0                     1                    0                   0
 8            0                     0                    1                   0
 9            0                     0                    1                   0
10            0                     1                    0                   0
# ℹ 15,410 more rows
# ℹ Use `print(n = ...)` to see more rows

Il existe deux paramètres  qui sont généralement ajustés :

  • Le paramètre “one_hot” est un booléen (TRUE ou FALSE) qui est TRUE par défaut. Si “one_hot” est FALSE, une seule variable binaire est créée pour chaque modalité de la variable catégorielle. Dans ce cas, les variables binaires ne sont pas indépendantes, ce qui peut avoir des conséquences sur certains modèles.
  • Le paramètre “naming” permet de définir le préfixe ou le suffixe à utiliser pour nommer les variables binaires créées.

 

Encodage ordinal (Ordinal Encoding)

L’encodage ordinal est une méthode utilisé pour les variables catégorielles ordinales c’est à dire des variables pour lesquels les différentes modalités ont un ordre Elle consite à L’encodage ordinal consiste à assigner une valeur numérique à chaque catégorie en fonction de son ordre. 

Utilisons la variable VehiclePrice pour illuster cela. Elle comprend 6 modalités qui ne sont pas ordonnées. 

> levels(data_subset$VehiclePrice)
[1] "20000 to 29000"  "30000 to 39000"  "40000 to 59000"  "60000 to 69000"  "less than 20000" "more than 69000"

Avant de procéder à l’encodage, il est nécessaire de les réordonner en leur attribuant un ordre logique.

order_VehiclePrice = c("less than 20000","20000 to 29000","30000 to 39000","40000 to 59000","60000 to 69000","more than 69000")
data_subset$VehiclePrice = factor(data_subset$VehiclePrice,order=TRUE,levels = order_VehiclePrice)
levels(data_subset$VehiclePrice)
Levels: less than 20000 < 20000 to 29000 < 30000 to 39000 < 40000 to 59000 < 60000 to 69000 < more than 69000

Nous pouvons à présent effectuer l’encodage grâce à la fonction step_ordinalscore() de recipe.

recipe_1 = recipe(FraudFound_P ~ VehiclePrice,data=data_subset) %>% 
             step_ordinalscore(VehiclePrice)

recipe_1 %>% prep() %>% juice()
# A tibble: 15,420 × 2
   VehiclePrice FraudFound_P
          <int>        <dbl>
 1            6            0
 2            6            0
 3            6            0
 4            2            0
 5            6            0
 6            6            0
 7            6            0
 8            6            0
 9            6            0
10            6            0
# ℹ 15,410 more rows
# ℹ Use `print(n = ...)` to see more rows

 

Regroupement des valeurs peu fréquentes  + One-Hot encoding

Lorsqu’on a des variables avec beaucoup de modalités différentes, faire un One-hot-encoding c’est à dire créer une variable pour chaque modalité peut augmenter le nombre de variables de manière significative. Cela peut rendre les modèles plus complexes, nécessiter plus de ressources et augmenter le risque de surapprentissage. Pour éviter ces problèmes, on peut regrouper les modalitéss en groupes plus larges en fonction de leur similarité ou de leur fréquence et ensuite faire un one-hot encoding ou un ordianl encoding. Cela réduit la complexité du modèle tout en conservant les informations importantes.

Jetons un coup d’oeil à la distribution des modalités de la variable Make.

# fonction pour tracer un diagramme en bar
plot_quali = function(data,var){ 
  data %>% count(.data[[var]]) %>% 
    mutate(Pct = round(n / nrow(data),5)) %>% ggplot(aes_string(x="Pct", y=var,fill=var)) + 
    geom_bar(stat="identity")+ 
    geom_label_repel(aes(label = paste("%",Pct*100)), color = 'white',size=6)+ 
    theme_minimal()+ labs(y = "Frequence", title = paste("Diagramme en barre et Fréquence"), subtitle = paste0("Variable : ",var))+ 
    theme( legend.position="none", plot.title = element_text(color = "black", size = 18, face = "bold"), plot.subtitle = element_text(color = "red",size=15)) } 

plot_quali(data_subset,"Make")

 

 

La fonction step_other() de recipe permet de regrouper facilement les modalités peu fréquentes en une catégorie “autre”. On peut ajuster le comportement de la fonction en utilisant deux paramètres :

  • “threshold” qui indique la fréquence minimale qu’une catégorie doit avoir pour ne pas être considérée comme “autre”.
  • “other” qui permet de renommer la catégorie “autre”.

Nous regroupons les modalités qui ont une fréquence de moins de 3% en une modalité nommée “other”.

recipe_1 = recipe(FraudFound_P ~ Make,data=data_subset) %>% 
  step_other(Make,threshold = 0.03,other ="other")

new_data = recipe_1 %>% prep() %>% juice() 
plot_quali(new_data,"Make")

 

Nous pouvons à présent, effectuer un one-hot encoding sur la nouvelle variable. voici le code complet qui effectue toutes les transformations.

recipe_1 = recipe(FraudFound_P ~ Make,data=data_subset) %>% 
  step_other(Make,threshold = 0.03) %>% 
  step_dummy(Make)

recipe_1 %>% prep() %>% juice()
# A tibble: 15,420 × 7
   FraudFound_P Make_Chevrolet Make_Honda Make_Mazda Make_Pontiac Make_Toyota Make_other
          <dbl>          <dbl>      <dbl>      <dbl>        <dbl>       <dbl>      <dbl>
 1            0              0          1          0            0           0          0
 2            0              0          1          0            0           0          0
 3            0              0          1          0            0           0          0
 4            0              0          0          0            0           1          0
 5            0              0          1          0            0           0          0
 6            0              0          1          0            0           0          0
 7            0              0          1          0            0           0          0
 8            0              0          1          0            0           0          0
 9            0              0          1          0            0           0          0
10            0              0          0          0            0           0          1
# ℹ 15,410 more rows
# ℹ Use `print(n = ...)` to see more rows

Tidymodels propose de nombreuses fonctions pour le prétraitement des données, notamment à travers le package recipe qui permet de recoder facilement les variables qualitatives. J’espère que cet article vous aura été utile, à bientôt !