Scaling et normalisation sur le dataset Breast Cancer Wisconsin
Dataset Breast Cancer Wisconsin (Diagnostic)
Nous allons mettre en pratique les techniques de scaling et de normalisation en nous appuyant sur le dataset Breast Cancer Wisconsin (Diagnostic), un jeu de données de référence en apprentissage automatique. Il constitue un excellent support pour illustrer l’importance du prétraitement, notamment lorsque l’on utilise des modèles sensibles aux distances comme le K‑NN, le SVM ou le clustering.
Le dataset
Breast Cancer Wisconsin contient 569 observations décrivant des cellules mammaires à partir d’images médicales. Chaque échantillon est caractérisé par 30 variables numériques regroupées en trois familles, à savoir les valeurs mean, les erreurs standards et les valeur maximales de mesures telles que le rayon, la texture, la compacité, la concavité, la symétrie ou encore l’aire de la cellule.
Les variables du jeu de données n’ont pas du tout la même échelle. En effet, certaines sont proches de 0 et d’autres dépassent largement 1000. Cette hétérogénéité rend le dataset particulièrement pertinent pour montrer pourquoi le scaling est indispensable. Sans mise à l’échelle, les features de grande amplitude dominent les distances et faussent le comportement des modèles basés sur la proximité.
Le dataset Breast Cancer Wisconsin (Diagnostic) est directement accessible depuis scikit‑learn via load_breast_cancer(). Il est également disponible sur le
UCI Machine Learning Repository, qui constitue sa source originale.
Mise en pratique du scaling avec le dataset Breast Cancer
Je vais, une fois de plus, vous présenter l’intégralité du code, puis je détaillerai les nouveaux aspects liés au scaling:
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import accuracy_score, confusion_matrix
import pandas as pd
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# Modèle KNN sans scaling
knn_no_scaling = KNeighborsClassifier(n_neighbors=5)
knn_no_scaling.fit(X_train, y_train)
y_pred_no_scaling = knn_no_scaling.predict(X_test)
acc_no_scaling = accuracy_score(y_test, y_pred_no_scaling)
cm_no_scaling = confusion_matrix(y_test, y_pred_no_scaling)
print("KNN SANS SCALING")
print("Accuracy:", acc_no_scaling)
print(cm_no_scaling)
# Min-Max Scaling
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Modèle KNN avec scaling
knn_scaled = KNeighborsClassifier(n_neighbors=5)
knn_scaled.fit(X_train_scaled, y_train)
y_pred_scaled = knn_scaled.predict(X_test_scaled)
acc_scaled = accuracy_score(y_test, y_pred_scaled)
cm_scaled = confusion_matrix(y_test, y_pred_scaled)
print("KNN AVEC MIN-MAX SCALING")
print("Accuracy:", acc_scaled)
print(cm_scaled)
Après avoir importer les modules nécessaires dont
MinMaxScaler, on charge le dataset Breast Cancer inclus dans scikit-learn:
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target
Le code précédent crée un DataFrame pandas regroupant toutes les variables explicatives (features), où chaque colonne correspond à une caractéristique mesurée comme la taille du noyau ou la texture, tandis que
y = data.target stocke la variable cible (les labels). C’est exactement le même principe que pour le célèbre dataset iris que nous avons traité lors du cours de Machine Learning, avec ses caractéristiques florales et sa variable cible représentant l’espèce.
Après avoir entraîné le modèle k-NN sans mise à l’échelle des données, nous avons ensuite appliqué le scaling:
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
On crée d’abord un objet
MinMaxScaler chargé de ramener chaque feature dans une plage donnée (par défaut entre 0 et 1). Le scaler ajuste ensuite ses bornes min et max sur l’ensemble d’entraînement (fit) avant d’appliquer la transformation (transform), ce qui normalise toutes les variables de X_train. Ces deux opérations sont effectuées en une seule fois à l'aide de la méthode
fit_transform(). Enfin, la même transformation est appliquée au jeu de test à l'aide de la méthode
transform(), en utilisant les bornes calculées sur le train afin d’éviter toute fuite d’information.
Lorsqu’on applique le scaling, il est essentiel de calculer les bornes min et max uniquement sur l’ensemble d’entraînement. Ces valeurs servent ensuite à transformer aussi bien le train que le test. Si l’on recalculait les bornes directement sur le test, on introduirait des informations extérieures au modèle avant son apprentissage, ce qui créerait une fuite d’information (data leakage). En pratique, cela fausserait l’évaluation car le modèle bénéficierait de données qu’il n’est pas censé connaître.
Après exécution du code, on obtient ce résultat:
KNN SANS SCALING
Accuracy: 0.9122807017543859
[[ 38 4 ]
[ 6 66 ]]
KNN AVEC MIN-MAX SCALING
Accuracy: 0.9824561403508771
[[ 40 2 ]
[ 0 72 ]]
Les résultats montrent clairement l’impact du scaling sur les performances du modèle k-NN. Sans mise à l’échelle, l’accuracy atteint environ 91%, avec quelques erreurs de classification (4 faux positifs et 6 faux négatifs). En revanche, après application du Min-Max Scaling, l’accuracy grimpe à près de 98% et la matrice de confusion indique une amélioration notable: seulement 2 faux positifs et aucun faux négatif.
Ces résultats illustrent que la normalisation des données permet au k-NN de mieux comparer les distances entre observations en réduisant les erreurs et en améliorant significativement la qualité des prédictions.
Standardisation et normalisation: même principe avec des modules différents
De la même manière que pour le Min-Max Scaling, on peut appliquer d’autres techniques de mise à l’échelle en suivant exactement le même principe. Par exemple :
- La standardisation: (centrer et réduire les données pour obtenir une moyenne nulle et un écart-type de 1) avec le module StandardScaler de sklearn.preprocessing.
- La normalisation: (ramener chaque vecteur de données à une norme unitaire) avec le module Normalizer de sklearn.preprocessing.
Le workflow reste identique. On effet, on crée l’objet du scaler choisi, on ajuste sur les données d’entraînement (fit), puis on transforme (transform) aussi bien le train que le test en utilisant les paramètres calculés sur le train.