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')
temp_df = calculate_mean_target_per_category(data, 'M2_groupe')
plot_categories(temp_df, 'M2_groupe')
temp_df = calculate_mean_target_per_category(data, 'Hippodrome_groupe')
plot_categories(temp_df, 'Hippodrome_groupe')
# 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'Olonne', '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'Olonne', '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.