Binary Encoding: une alternative intelligente au One-Hot Encoding
Compacité et efficacité avec le Binary Encoding
Le
Binary Encoding est une technique de transformation des variables catégorielles qui consiste à attribuer un entier à chaque catégorie (comme dans le
Label Encoding), puis à convertir cet entier en sa représentation binaire et à répartir les bits obtenus dans plusieurs colonnes.
La technique du Binary Encoding permet de réduire le nombre de colonnes nécessaires par rapport au
One-Hot Encoding qui crée une colonne pour chaque catégorie. L’avantage principal du Binary Encoding est donc sa compacité car il conserve une représentation numérique exploitable par les algorithmes tout en limitant la dimensionnalité du jeu de données, ce qui est particulièrement utile lorsque le nombre de catégories est élevé et que le One-Hot risquerait de générer un grand nombre de colonnes redondantes.
Par exemple, si on dispose de 8 catégories pour un champs (une variable catégorielle), alors une transformation en One-Hot Encoding générera 8 colonnes, tandis que la technique du Binary Encoding ne générera que 3 colonnes car on peut représenter jusqu'à 8 valeurs distinctes avec 3 bits seulement.
Mise en pratique du Binary Encoding sur le Dataset Titanic
Encore une fois, je vais vous donner le code en intégralité, puis j'expliquerai les parties essentielles juste après.
Je rappelle que les variables Sex et Embarked seront transformées à l'aide du Label Encoding, alors que seule la variable Pclass sera traitée en utilisant le Binary Encoding.
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from category_encoders import BinaryEncoder
df = pd.read_csv("titanic.csv")
data = df[['Sex', 'Embarked', 'Pclass', 'Survived']].dropna()
X = data[['Sex', 'Embarked', 'Pclass']]
y = data['Survived']
# Encodage avec LabelEncoder pour Sex et Embarked
le_sex = LabelEncoder()
X['Sex'] = le_sex.fit_transform(X['Sex'])
le_embarked = LabelEncoder()
X['Embarked'] = le_embarked.fit_transform(X['Embarked'])
# Binary Encoding pour Pclass
binary_encoder = BinaryEncoder(cols=['Pclass'])
pclass_encoded = binary_encoder.fit_transform(X[['Pclass']])
# Fusionner avec X et supprimer la colonne originale
X = pd.concat([X.drop('Pclass', axis=1), pclass_encoded], axis=1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
print("Accuracy k-NN:", accuracy_score(y_test, y_pred))
print("Extrait Binary Encoding de Pclass:")
print(pclass_encoded.head(10))
Il se peut que vous ayez besoin d'installer les modules
patsy et
statsmodels souvent requis par la librairie
category_encoders. Donc, il suffit d'exécuter ces deux commandes:
!pip install patsy
!pip install statsmodels
Voyons ce que fait le code précédent.
Comme d'habitude, on commence par importer les modules nécessaires, en l'occurrence la classe
BinaryEncoder depuis la librairie
category_encoders:
from category_encoders import BinaryEncoder
Ensuite, on crée un encodeur binaire pour la colonne Pclass qui transforme ses valeurs en représentation binaire répartie sur plusieurs colonnes:
binary_encoder = BinaryEncoder(cols=['Pclass'])
pclass_encoded = binary_encoder.fit_transform(X[['Pclass']])
Juste après, on remplace la colonne Pclass par sa version encodée en binaire en fusionnant les nouvelles colonnes avec le reste du DataFrame:
X = pd.concat([X.drop('Pclass', axis=1), pclass_encoded], axis=1)
Le reste du code est identique à ce qu'on a vu avant.
Après exécution, on obtient:
Accuracy k-NN: 0.7640449438202247
Extrait Binary Encoding de Pclass:
Pclass_0 Pclass_1
0 0 1
1 1 0
2 0 1
3 1 0
4 0 1
5 0 1
6 1 0
7 0 1
8 0 1
9 1 1
On constate la transformation de la variable Pclass en deux colonnes binaires (Pclass_0 et Pclass_1) où les valeurs 1, 2 et 3 sont représentées respectivement par leur forme binaire correspondante (01, 10 et 11).