Encodage à chaud (One Hot Encoding)

Un encodage à chaud, consiste à coder chaque variable catégorielle avec différentes variables booléennes (aussi appelées variables factices) qui prennent les valeurs 0 ou 1, indiquant si une catégorie est présente dans une observation.

Par exemple, pour la variable catégorielle “Sexe”, avec les étiquettes “femme” et “mâle”, nous pouvons générer la variable booléenne “femme”, qui prend la valeur 1 si la personne est “femme” ou 0 sinon, ou nous pouvons générer la variable “mâle”, qui prend la valeur 1 si la personne est “mâle” et 0 sinon.

Pour la variable catégorielle “couleur” avec les valeurs “rouge”, “bleu” et “vert”, nous pouvons créer 3 nouvelles variables appelées “rouge”, “bleu” et “vert”. Ces variables prendront la valeur 1, si l’observation est de ladite couleur ou 0 sinon.

Encodage en k-1 variables factices

Notez cependant que pour la variable “color”, en créant 2 variables binaires, disons “rouge” et “bleu”, nous encodons déjà Toutes les informations :

  • si l’observation est rouge, elle sera saisie par la variable “rouge” (rouge = 1, bleu = 0)
  • si l’observation est bleue, elle sera saisie par la variable “bleu” (rouge = 0, bleu = 1)
  • si l’observation est verte, elle sera saisie par la combinaison de “rouge” et “bleu” (rouge = 0, bleu = 0)

Nous n’avons pas besoin d’ajouter une troisième variable “verte” pour indiquer que l’observation est verte.

Plus généralement, une variable catégorielle doit être encodée en créant k-1 variables binaires, où k est le nombre de catégories distinctes. Dans le cas du sexe, k=2 (homme / femme), nous devons donc créer seulement 1 (k – 1 = 1) variable binaire. Dans le cas de la couleur, qui a 3 catégories différentes (k=3), nous devons créer 2 (k – 1 = 2) variables binaires pour saisir toutes les informations.

Un codage à chaud en k-1 variables binaires tient compte du fait que nous pouvons utiliser 1 dimension de moins et représenter quand même toute l’information : si l’observation est 0 dans toutes les variables binaires, alors elle doit être 1 dans la variable binaire finale (non présente).

Lors d’un encodage à chaud des variables catégorielles, nous créons k – 1 variables binaires

La plupart des algorithmes d’apprentissage automatique prennent en compte l’ensemble des données tout en étant adaptés. Il est donc préférable de coder les variables catégorielles en k – 1 variables binaires, car cela évite d’introduire des informations redondantes.

Exception : Un codage à chaud en k variables fictives

Il est parfois préférable de coder les variables en k variables factices :

  • lors de la construction d’algorithmes basés sur des arbres
  • lors de la sélection de caractéristiques par des algorithmes récursifs
  • lorsqu’il s’agit de déterminer l’importance de chaque catégorie

Les algorithmes basés sur l’arbre, contrairement à la majorité des algorithmes d’apprentissage machine, n’évaluent pas l’ensemble des données pendant la formation. Ils extraient aléatoirement un sous-ensemble de caractéristiques de l’ensemble de données à chaque nœud de chaque arbre. Par conséquent, si nous voulons qu’un algorithme basé sur l’arbre prenne en compte toute les catégories, nous devons coder les variables catégorielles en k variables binaires.

Si nous prévoyons de sélectionner des caractéristiques par élimination (ou addition) récursive, ou si nous voulons évaluer l’importance de chaque catégorie de la variable catégorielle, alors nous aurons également besoin de l’ensemble des variables binaires (k) pour permettre au modèle d’apprentissage machine de sélectionner celles qui ont le plus de pouvoir prédictif.

Avantages d’un encodage à chaud

  • Simple à mettre en œuvre
  • Ne fait aucune hypothèse sur la distribution ou les catégories de la variable catégorielle
  • Conserve toutes les informations de la variable catégorielle
  • Convient aux modèles linéaires

Limitations

  • Élargir l’espace de présentation
  • N’ajoute pas d’informations supplémentaires lors de l’encodage
  • De nombreuses variables factices peuvent être identiques, ce qui introduit des informations redondantes

Notes

Si nos jeux de données contiennent quelques variables hautement cardinales, nous nous retrouverons très bientôt avec des jeux de données comportant des milliers de colonnes, ce qui pourrait rendre l’apprentissage de nos algorithmes lent et l’interprétation des modèles difficile.

En outre, nombre de ces variables fictives peuvent être similaires les unes aux autres, car il n’est pas rare que deux ou plusieurs variables partagent les mêmes combinaisons de 1 et de 0. Par conséquent, un encodage à chaud peut introduire des informations redondantes ou dupliquées même si nous codons en k-1.

Dans cette démo :

Nous allons voir comment effectuer un encodage à chaud avec :

  • pandas
  • Scikit-learn
  • Feature-Engine

Et les avantages et les limites de chaque mise en œuvre.

import pandas as pd

# to split the datasets
from sklearn.model_selection import train_test_split

# for one hot encoding with sklearn
from sklearn.preprocessing import OneHotEncoder

# for one hot encoding with feature-engine
from feature_engine.categorical_encoders import OneHotCategoricalEncoder

import matplotlib.pyplot as plt

data = pd.read_csv('../exportfeature.csv',usecols=['place', 'M1', 'M2', 'Hippodrome'],sep=";",encoding='ANSI')


data.head()
	place	M1	M2	Hippodrome
0	1	3a	3m	Vincennes
1	1	3a	9Da	Vincennes
2	0	1a	Da	Vincennes
3	1	Da	7a	Vincennes
4	0	1a	7a	Vincennes

Encodage important

Tout comme l’imputation, toutes les méthodes de codage catégoriel doivent être effectuées sur l’ensemble de formation, puis propagées à l’ensemble de test.

Pourquoi ?

Parce que ces méthodes “apprendront” des modèles à partir des données du train, et que vous voulez donc éviter les fuites d’informations et le surajustement. Mais surtout, parce que nous ne savons pas si, à l’avenir / dans les données en direct, toutes les catégories seront présentes dans les données d’entraienemnt, ou s’il y aura plus ou moins de catégories. Nous voulons donc anticiper cette incertitude en mettant en place les bons processus dès le départ.

 

Explorons la cardinalité

print('Nombre de catégorie de la variable  M1: {}'.format(
    len(data.M1.unique())))

Nombre de catégorie de la variable  M1: 67

print('Nombre de catégorie de la variable  M2: {}'.format(
    len(data.M2.unique())))
    
Nombre de catégorie de la variable  M2: 71

print('Nombre de catégorie de la variable  Hippodrome: {}'.format(
    len(data.Hippodrome.unique())))
    
Nombre de catégorie de la variable  Hippodrome: 199    

Comme nous le savons déjà, nous avons beaucoup de cardinalités. Dans un notebook précédant sur l’analyse des étiquettes rares, nous avons vu une technique pour diminuer les cardinalités en les regroupant.

# Je remplacerai tous les labels qui apparaissent dans moins de 2%
# utilisation de la variable pourcentage


def group_rare_labels(df, var,pourcentage=0.02):

    total_chx = len(df)

    # Je calcule d'abord le % de chevaux pour chaque catégorie
    temp_df = pd.Series(df[var].value_counts() / total_chx)

    # maintenant je crée un dictionnaire pour remplacer les étiquettes rares par les
    # chaîne "rare" si elles sont présentes dans moins de 2% des chevaux

    grouping_dict = {
        k: ('rare' if k not in temp_df[temp_df >= pourcentage].index else k)
        for k in temp_df.index
    }

    # je remplace les catégories
    tmp = df[var].map(grouping_dict)

    return tmp

# la fonction suivante calcule :

# 1) le pourcentage de chevaux par catégorie
# 2) la cote moyenne par catégorie


def calculate_mean_target_per_category(df, var):

    # taille du df
    total_chx = len(df)

    # pourcentage de chevaux par catégorie
    temp_df = pd.Series(df[var].value_counts() / total_chx).reset_index()
    temp_df.columns = [var, 'perc_chx']

    # cote moyenne par catégorie
    temp_df = temp_df.merge(df.groupby([var])['place'].mean().reset_index(),
                            on=var,
                            how='left')

    return temp_df

# Maintenant je crée une fonction pour tracer de la
# fréquence de la catégorie et la cote moyenne.

# Cela nous aidera à visualiser la relation entre la
# cible et les étiquettes de la variable catégorielle

def plot_categories(df, var, seuil=0.02):
    
    fig, ax = plt.subplots(figsize=(8, 4))
    plt.xticks(df.index, df[var], rotation=90)

    ax2 = ax.twinx()
    ax.bar(df.index, df["perc_chx"], color='lightgrey')
    ax2.plot(df.index, df["place"], color='green', label='Seconds')
    ax.axhline(y=seuil, color='red')
    ax.set_ylabel('Pourcentage')
    ax.set_xlabel(var)
    ax2.set_ylabel('place moyenne')
    plt.show()
    
data['M1_groupe'] = group_rare_labels(data, 'M1')
data['M2_groupe'] = group_rare_labels(data, 'M2')
data['Hippodrome_groupe'] = group_rare_labels(data, 'Hippodrome',0.003)   

temp_df = calculate_mean_target_per_category(data, 'M1_groupe')
plot_categories(temp_df, 'M1_groupe')
one hot encoding 1
temp_df = calculate_mean_target_per_category(data, 'M2_groupe')
plot_categories(temp_df, 'M2_groupe')
one hot encoding 2
temp_df = calculate_mean_target_per_category(data, 'Hippodrome_groupe')
plot_categories(temp_df, 'Hippodrome_groupe')
one hot encoding 3
# On supprime les colonnes initiales
data.drop(['M1','M2','Hippodrome'], axis=1, inplace=True)

# Création du jeu d'entrainement et de test

X_train, X_test, y_train, y_test = train_test_split(
    data[['M1_groupe', 'M2_groupe', 'Hippodrome_groupe']],  # predictors
    data['place'], 
    test_size=0.3,  
    random_state=0) 

X_train.shape, X_test.shape

((14352, 3), (6152, 3))

Un encodage à chaud avec pandas

Avantages

  • rapide
  • retourne un dataframe pandas
  • renvoie les noms des caractéristiques pour les variables factices

Limites des pandas :

  • elle ne préserve pas les informations des données d’entrainement pour les propager aux données de test

La méthode pandas get_dummies(), créera autant de variables binaires que de catégories dans la variable :

Si la couleur de la variable a 3 catégories dans les données du train, elle créera 2 variables factices. Cependant, si la couleur de la variable a 5 catégories dans les données de test, elle créera 4 variables binaires. Par conséquent, les ensembles de train et de test se retrouveront avec un nombre différent de caractéristiques et seront incompatibles avec la formation et la notation à l’aide de Scikit-learn.

Dans la pratique, nous ne devrions pas utiliser de “get-dummies” dans nos pipelines d’apprentissage machine. Il est cependant utile, pour une exploration rapide des données. Voyons cela à l’aide d’exemples.

# nous pouvons créer des variables factices avec l'intégration
# méthode pandas get_dummies

tmp = pd.get_dummies(X_train['M1_groupe'])

tmp.head()
1a	2a	3a	4a	5a	6a	7a	8a	Da	rare
2540	0	0	0	0	1	0	0	0	0	0
19008	1	0	0	0	0	0	0	0	0	0
7624	0	0	0	0	0	0	1	0	0	0
2575	0	1	0	0	0	0	0	0	0	0
852	0	0	0	0	0	1	0	0	0	0
# Pour mieux voir les infos

pd.concat([X_train['M1_groupe'],
           pd.get_dummies(X_train['M1_groupe'])], axis=1).head()
	M1_groupe	1a	2a	3a	4a	5a	6a	7a	8a	Da	rare
2540	5a	0	0	0	0	1	0	0	0	0	0
19008	1a	1	0	0	0	0	0	0	0	0	0
7624	7a	0	0	0	0	0	0	1	0	0	0
2575	2a	0	1	0	0	0	0	0	0	0	0
852	6a	0	0	0	0	0	1	0	0	0	0
# idem pour M2_groupe

tmp = pd.get_dummies(X_train['M2_groupe'])

tmp.head()
1a	2a	3a	4a	5a	6a	7a	8a	9a	Da	rare
2540	0	0	0	0	1	0	0	0	0	0	0
19008	0	0	1	0	0	0	0	0	0	0	0
7624	0	0	0	0	0	0	0	0	0	1	0
2575	0	0	0	0	0	0	0	0	0	0	1
852	0	0	0	0	1	0	0	0	0	0	0
pd.concat([X_train['M2_groupe'],
           pd.get_dummies(X_train['M2_groupe'])], axis=1).head()
	M2_groupe	1a	2a	3a	4a	5a	6a	7a	8a	9a	Da	rare
2540	5a	0	0	0	0	1	0	0	0	0	0	0
19008	3a	0	0	1	0	0	0	0	0	0	0	0
7624	Da	0	0	0	0	0	0	0	0	0	1	0
2575	rare	0	0	0	0	0	0	0	0	0	0	1
852	5a	0	0	0	0	1	0	0	0	0	0	0
# et pour Hippodrome_groupe

tmp = pd.get_dummies(X_train['Hippodrome_groupe'])

tmp.head()
	Aby	Agen	Amiens	Angers	Argentan	Avenches	Beaumont-de-Lomagne	Bordeaux Le Bouscat	Cabourg	Caen	...	Saint-Galmier	Saint-Malo	Solvalla	Strasbourg	Toulouse	Vichy	Vincennes	Vire	Wolvega	rare
2540	0	0	0	0	0	0	0	0	1	0	...	0	0	0	0	0	0	0	0	0	0
19008	0	0	0	0	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
7624	0	0	0	0	0	0	0	0	0	0	...	0	0	0	0	0	0	1	0	0	0
2575	0	0	0	0	0	0	0	0	1	0	...	0	0	0	0	0	0	0	0	0	0
852	0	1	0	0	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
5 rows × 55 columns
# Toutes les variables ensemble

tmp = pd.get_dummies(X_train)

print(tmp.shape)

tmp.head()
(14352, 76)
	M1_groupe_1a	M1_groupe_2a	M1_groupe_3a	M1_groupe_4a	M1_groupe_5a	M1_groupe_6a	M1_groupe_7a	M1_groupe_8a	M1_groupe_Da	M1_groupe_rare	...	Hippodrome_groupe_Saint-Galmier	Hippodrome_groupe_Saint-Malo	Hippodrome_groupe_Solvalla	Hippodrome_groupe_Strasbourg	Hippodrome_groupe_Toulouse	Hippodrome_groupe_Vichy	Hippodrome_groupe_Vincennes	Hippodrome_groupe_Vire	Hippodrome_groupe_Wolvega	Hippodrome_groupe_rare
2540	0	0	0	0	1	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
19008	1	0	0	0	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
7624	0	0	0	0	0	0	1	0	0	0	...	0	0	0	0	0	0	1	0	0	0
2575	0	1	0	0	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
852	0	0	0	0	0	1	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
5 rows × 76 columns
# Toutes les variables ensemble pour l'ensemble de test
tmp = pd.get_dummies(X_test)

print(tmp.shape)

tmp.head()
	M1_groupe_1a	M1_groupe_2a	M1_groupe_3a	M1_groupe_4a	M1_groupe_5a	M1_groupe_6a	M1_groupe_7a	M1_groupe_8a	M1_groupe_Da	M1_groupe_rare	...	Hippodrome_groupe_Saint-Galmier	Hippodrome_groupe_Saint-Malo	Hippodrome_groupe_Solvalla	Hippodrome_groupe_Strasbourg	Hippodrome_groupe_Toulouse	Hippodrome_groupe_Vichy	Hippodrome_groupe_Vincennes	Hippodrome_groupe_Vire	Hippodrome_groupe_Wolvega	Hippodrome_groupe_rare
9263	0	0	1	0	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
18643	0	0	0	1	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
4750	0	0	0	0	0	0	0	0	1	0	...	0	0	0	0	0	0	0	0	0	0
19501	0	0	0	0	0	1	0	0	0	0	...	0	0	0	0	0	0	1	0	0	0
15401	0	1	0	0	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
5 rows × 76 columns

Un encodage à chaud avec Scikit-learn

Avantages

  • rapide
  • Crée le même nombre de fonctions dans le train et le banc d’essai

Limitations

  • il renvoie un tableau numérique au lieu d’une trame de données de pandas
  • il ne renvoie pas les noms des variables, ce qui est peu pratique pour l’exploration des variables
# Création de l'encodeur

encoder = OneHotEncoder(categories='auto',
                       drop='first', #pour renvoyer k-1
                       sparse=False,
                       handle_unknown='error') # aide à gérer les labels rares

encoder.fit(X_train.fillna('Absent'))

# nous observons les catégories apprises
encoder.categories_
[array(['1a', '2a', '3a', '4a', '5a', '6a', '7a', '8a', 'Da', 'rare'],
       dtype=object),
 array(['1a', '2a', '3a', '4a', '5a', '6a', '7a', '8a', '9a', 'Da', 'rare'],
       dtype=object),
 array(['Aby', 'Agen', 'Amiens', 'Angers', 'Argentan', 'Avenches',
        'Beaumont-de-Lomagne', 'Bordeaux  Le Bouscat', 'Cabourg', 'Caen',
        'Cagnes', 'Cagnes-sur-Mer', 'Cavaillon', 'Chartres',
        'Chatelaillon-La Rochelle', 'Cherbourg', 'Châteaubriant',
        'Cordemais', 'Divonne-les-Bains', 'Enghien', 'Feurs', 'Graignes',
        'Hyères', 'La Capelle', 'Langon-Libourne', 'Laval',
        'Le Croisé-Laroche', 'Le Mans', 'Le Mont-Saint-Michel',
        'Les Sables-d&#039Olonne', 'Lisieux', 'Lyon-La Soie',
        'Lyon-Parilly', 'Marseille-Borély', 'Marseille-Vivaux',
        'Mauquenchy', 'Maure-de-Bretagne', 'Meslay-du-Maine', 'Mons',
        'Nancy', 'Nantes', 'Pontchâteau', 'Pornichet', 'Reims',
        'Saint-Brieuc', 'Saint-Galmier', 'Saint-Malo', 'Solvalla',
        'Strasbourg', 'Toulouse', 'Vichy', 'Vincennes', 'Vire', 'Wolvega',
        'rare'], dtype=object)]
# Transformatio du jeu d'entrainement

tmp = encoder.transform(X_train.fillna('Absent'))

pd.DataFrame(tmp).head()
0	1	2	3	4	5	6	7	8	9	...	63	64	65	66	67	68	69	70	71	72
0	0.0	0.0	0.0	1.0	0.0	0.0	0.0	0.0	0.0	0.0	...	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0
1	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	...	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0
2	0.0	0.0	0.0	0.0	0.0	1.0	0.0	0.0	0.0	0.0	...	0.0	0.0	0.0	0.0	0.0	0.0	1.0	0.0	0.0	0.0
3	1.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	...	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0
4	0.0	0.0	0.0	0.0	1.0	0.0	0.0	0.0	0.0	0.0	...	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0
5 rows × 73 columns
# NOUVEAU : dans la dernière version de Scikit-learn
# nous pouvons maintenant récupérer les noms des éléments comme suit :
encoder.get_feature_names()

array(['x0_2a', 'x0_3a', 'x0_4a', 'x0_5a', 'x0_6a', 'x0_7a', 'x0_8a',
       'x0_Da', 'x0_rare', 'x1_2a', 'x1_3a', 'x1_4a', 'x1_5a', 'x1_6a',
       'x1_7a', 'x1_8a', 'x1_9a', 'x1_Da', 'x1_rare', 'x2_Agen',
       'x2_Amiens', 'x2_Angers', 'x2_Argentan', 'x2_Avenches',
       'x2_Beaumont-de-Lomagne', 'x2_Bordeaux  Le Bouscat', 'x2_Cabourg',
       'x2_Caen', 'x2_Cagnes', 'x2_Cagnes-sur-Mer', 'x2_Cavaillon',
       'x2_Chartres', 'x2_Chatelaillon-La Rochelle', 'x2_Cherbourg',
       'x2_Châteaubriant', 'x2_Cordemais', 'x2_Divonne-les-Bains',
       'x2_Enghien', 'x2_Feurs', 'x2_Graignes', 'x2_Hyères',
       'x2_La Capelle', 'x2_Langon-Libourne', 'x2_Laval',
       'x2_Le Croisé-Laroche', 'x2_Le Mans', 'x2_Le Mont-Saint-Michel',
       'x2_Les Sables-d&#039Olonne', 'x2_Lisieux', 'x2_Lyon-La Soie',
       'x2_Lyon-Parilly', 'x2_Marseille-Borély', 'x2_Marseille-Vivaux',
       'x2_Mauquenchy', 'x2_Maure-de-Bretagne', 'x2_Meslay-du-Maine',
       'x2_Mons', 'x2_Nancy', 'x2_Nantes', 'x2_Pontchâteau',
       'x2_Pornichet', 'x2_Reims', 'x2_Saint-Brieuc', 'x2_Saint-Galmier',
       'x2_Saint-Malo', 'x2_Solvalla', 'x2_Strasbourg', 'x2_Toulouse',
       'x2_Vichy', 'x2_Vincennes', 'x2_Vire', 'x2_Wolvega', 'x2_rare'],
      dtype=object)
# Nous pouvons aller de l'avant et transfomer l'ensemble de test
# puis le reconstituer en un cadre de données pandas
# et ajouter les noms des caractéristiques dérivées par OHE

tmp = encoder.transform(X_test.fillna('Absent'))

tmp = pd.DataFrame(tmp)
tmp.columns = encoder.get_feature_names()

tmp.head()
x0_2a	x0_3a	x0_4a	x0_5a	x0_6a	x0_7a	x0_8a	x0_Da	x0_rare	x1_2a	...	x2_Saint-Galmier	x2_Saint-Malo	x2_Solvalla	x2_Strasbourg	x2_Toulouse	x2_Vichy	x2_Vincennes	x2_Vire	x2_Wolvega	x2_rare
0	0.0	1.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	...	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0
1	0.0	0.0	1.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	...	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0
2	0.0	0.0	0.0	0.0	0.0	0.0	0.0	1.0	0.0	0.0	...	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0
3	0.0	0.0	0.0	0.0	1.0	0.0	0.0	0.0	0.0	0.0	...	0.0	0.0	0.0	0.0	0.0	0.0	1.0	0.0	0.0	0.0
4	1.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	...	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0	0.0
5 rows × 73 columns

Nous pouvons voir que train et test contiennent le même nombre de caractéristiques.

Vous trouverez plus de détails sur OneHotEncoder de Scikit-learn à l’adresse suivante : https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html.

 

Un encodage à chaud avec Feature-Engine

Avantages

  • rapide
  • renvoie une trame de données
  • renvoie des noms de caractéristiques
  • permet de sélectionner les caractéristiques à encoder

Limitations

  • Pas encore sûr.
ohe_enc = OneHotCategoricalEncoder(
    top_categories=None,
    variables=['M1_groupe', 'M2_groupe','Hippodrome_groupe'], # Selection des variables
    drop_last=True) 


ohe_enc.fit(X_train.fillna('Absent'))
tmp = ohe_enc.transform(X_train.fillna('Absent'))

tmp.head()
M1_groupe_5a	M1_groupe_1a	M1_groupe_7a	M1_groupe_2a	M1_groupe_6a	M1_groupe_4a	M1_groupe_rare	M1_groupe_3a	M1_groupe_Da	M2_groupe_5a	...	Hippodrome_groupe_Lisieux	Hippodrome_groupe_Le Croisé-Laroche	Hippodrome_groupe_Meslay-du-Maine	Hippodrome_groupe_Langon-Libourne	Hippodrome_groupe_Le Mont-Saint-Michel	Hippodrome_groupe_Maure-de-Bretagne	Hippodrome_groupe_Vire	Hippodrome_groupe_Pornichet	Hippodrome_groupe_Cavaillon	Hippodrome_groupe_Cagnes
2540	1	0	0	0	0	0	0	0	0	1	...	0	0	0	0	0	0	0	0	0	0
19008	0	1	0	0	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
7624	0	0	1	0	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
2575	0	0	0	1	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
852	0	0	0	0	1	0	0	0	0	1	...	0	0	0	0	0	0	0	0	0	0
5 rows × 73 columns

Notez comment le moteur retourne les variables factices avec leurs noms, et laisse tomber la variable originale, laissant l’ensemble de données prêt pour une exploration plus approfondie ou la construction de modèles d’apprentissage machine.

tmp = ohe_enc.transform(X_test.fillna('Absent'))

tmp.head()
M1_groupe_5a	M1_groupe_1a	M1_groupe_7a	M1_groupe_2a	M1_groupe_6a	M1_groupe_4a	M1_groupe_rare	M1_groupe_3a	M1_groupe_Da	M2_groupe_5a	...	Hippodrome_groupe_Lisieux	Hippodrome_groupe_Le Croisé-Laroche	Hippodrome_groupe_Meslay-du-Maine	Hippodrome_groupe_Langon-Libourne	Hippodrome_groupe_Le Mont-Saint-Michel	Hippodrome_groupe_Maure-de-Bretagne	Hippodrome_groupe_Vire	Hippodrome_groupe_Pornichet	Hippodrome_groupe_Cavaillon	Hippodrome_groupe_Cagnes
9263	0	0	0	0	0	0	0	1	0	0	...	0	0	0	0	0	0	0	0	0	0
18643	0	0	0	0	0	1	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
4750	0	0	0	0	0	0	0	0	1	0	...	0	0	0	0	0	0	0	0	0	0
19501	0	0	0	0	1	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
15401	0	0	0	1	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
5 rows × 73 columns
# Feature-Engine's one hot encoder peut aussi sélectionner automatiquement les catégories

ohe_enc = OneHotCategoricalEncoder(
top_categories=None,
drop_last=True) # to return k-1, false to return k


ohe_enc.fit(X_train.fillna('Missing'))

ohe_enc.variables

['M1_groupe', 'M2_groupe', 'Hippodrome_groupe']

tmp = ohe_enc.transform(X_train.fillna('Absent'))

tmp.head()
	M1_groupe_5a	M1_groupe_1a	M1_groupe_7a	M1_groupe_2a	M1_groupe_6a	M1_groupe_4a	M1_groupe_rare	M1_groupe_3a	M1_groupe_Da	M2_groupe_5a	...	Hippodrome_groupe_Lisieux	Hippodrome_groupe_Le Croisé-Laroche	Hippodrome_groupe_Meslay-du-Maine	Hippodrome_groupe_Langon-Libourne	Hippodrome_groupe_Le Mont-Saint-Michel	Hippodrome_groupe_Maure-de-Bretagne	Hippodrome_groupe_Vire	Hippodrome_groupe_Pornichet	Hippodrome_groupe_Cavaillon	Hippodrome_groupe_Cagnes
2540	1	0	0	0	0	0	0	0	0	1	...	0	0	0	0	0	0	0	0	0	0
19008	0	1	0	0	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
7624	0	0	1	0	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
2575	0	0	0	1	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
852	0	0	0	0	1	0	0	0	0	1	...	0	0	0	0	0	0	0	0	0	0
5 rows × 73 columns
tmp = ohe_enc.transform(X_test.fillna('Absent'))

tmp.head()
M1_groupe_5a	M1_groupe_1a	M1_groupe_7a	M1_groupe_2a	M1_groupe_6a	M1_groupe_4a	M1_groupe_rare	M1_groupe_3a	M1_groupe_Da	M2_groupe_5a	...	Hippodrome_groupe_Lisieux	Hippodrome_groupe_Le Croisé-Laroche	Hippodrome_groupe_Meslay-du-Maine	Hippodrome_groupe_Langon-Libourne	Hippodrome_groupe_Le Mont-Saint-Michel	Hippodrome_groupe_Maure-de-Bretagne	Hippodrome_groupe_Vire	Hippodrome_groupe_Pornichet	Hippodrome_groupe_Cavaillon	Hippodrome_groupe_Cagnes
9263	0	0	0	0	0	0	0	1	0	0	...	0	0	0	0	0	0	0	0	0	0
18643	0	0	0	0	0	1	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
4750	0	0	0	0	0	0	0	0	1	0	...	0	0	0	0	0	0	0	0	0	0
19501	0	0	0	0	1	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
15401	0	0	0	1	0	0	0	0	0	0	...	0	0	0	0	0	0	0	0	0	0
5 rows × 73 columns

L’avantage d’utiliser Feature-Engine c’est que vous aurez tjs un encodage correct.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.