Introduction
La mise à l'échelle des fonctionnalités est une étape de prétraitement importante pour de nombreux algorithmes d'apprentissage automatique. Elle consiste à redimensionner chaque fonctionnalité de sorte qu'elle ait une écart-type de 1 et une moyenne de 0. Dans ce laboratoire, nous explorerons l'importance de la mise à l'échelle des fonctionnalités et son effet sur les modèles d'apprentissage automatique en utilisant la bibliothèque scikit-learn en Python.
Conseils sur la machine virtuelle
Une fois le démarrage de la machine virtuelle terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Carnet de notes pour accéder au carnet Jupyter pour la pratique.
Parfois, vous devrez peut-être attendre quelques secondes pour que le carnet Jupyter ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations du carnet Jupyter.
Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez des commentaires après la session, et nous résoudrons rapidement le problème pour vous.
Charger et préparer les données
Nous allons charger l'ensemble de données sur le vin à partir de scikit-learn et le diviser en ensembles d'entraînement et de test. Nous allons également mettre à l'échelle les fonctionnalités dans l'ensemble d'entraînement en utilisant le StandardScaler du module de prétraitement scikit-learn.
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
X, y = load_wine(return_X_y=True, as_frame=True)
scaler = StandardScaler().set_output(transform="pandas")
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.30, random_state=42
)
scaled_X_train = scaler.fit_transform(X_train)
Effet de la mise à l'échelle sur un modèle K-plus-proches-voisins
Nous utiliserons un sous-ensemble de deux fonctionnalités de l'ensemble de données sur le vin pour entraîner un classifieur K-plus-proches-voisins. Nous visualiserons la frontière de décision du classifieur en utilisant des données non mises à l'échelle et mises à l'échelle.
import matplotlib.pyplot as plt
from sklearn.inspection import DecisionBoundaryDisplay
from sklearn.neighbors import KNeighborsClassifier
X_plot = X[["proline", "hue"]]
X_plot_scaled = scaler.fit_transform(X_plot)
clf = KNeighborsClassifier(n_neighbors=20)
def fit_and_plot_model(X_plot, y, clf, ax):
clf.fit(X_plot, y)
disp = DecisionBoundaryDisplay.from_estimator(
clf,
X_plot,
response_method="predict",
alpha=0.5,
ax=ax,
)
disp.ax_.scatter(X_plot["proline"], X_plot["hue"], c=y, s=20, edgecolor="k")
disp.ax_.set_xlim((X_plot["proline"].min(), X_plot["proline"].max()))
disp.ax_.set_ylim((X_plot["hue"].min(), X_plot["hue"].max()))
return disp.ax_
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 6))
fit_and_plot_model(X_plot, y, clf, ax1)
ax1.set_title("KNN sans mise à l'échelle")
fit_and_plot_model(X_plot_scaled, y, clf, ax2)
ax2.set_xlabel("proline mis à l'échelle")
ax2.set_ylabel("teinte mise à l'échelle")
_ = ax2.set_title("KNN avec mise à l'échelle")
Effet de la mise à l'échelle sur la réduction de dimension par l'Analyse en Composantes Principales (PCA)
Nous utiliserons l'Analyse en Composantes Principales (PCA) pour réduire la dimension de l'ensemble de données sur le vin. Nous comparerons les composantes principales trouvées en utilisant la PCA sur des données non mises à l'échelle avec celles obtenues lorsqu'on utilise d'abord un StandardScaler pour mettre à l'échelle les données.
import pandas as pd
from sklearn.decomposition import PCA
pca = PCA(n_components=2).fit(X_train)
scaled_pca = PCA(n_components=2).fit(scaled_X_train)
X_train_transformed = pca.transform(X_train)
X_train_std_transformed = scaled_pca.transform(scaled_X_train)
first_pca_component = pd.DataFrame(
pca.components_[0], index=X.columns, columns=["without scaling"]
)
first_pca_component["with scaling"] = scaled_pca.components_[0]
first_pca_component.plot.bar(
title="Weights of the first principal component", figsize=(6, 8)
)
_ = plt.tight_layout()
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))
target_classes = range(0, 3)
colors = ("blue", "red", "green")
markers = ("^", "s", "o")
for target_class, color, marker in zip(target_classes, colors, markers):
ax1.scatter(
x=X_train_transformed[y_train == target_class, 0],
y=X_train_transformed[y_train == target_class, 1],
color=color,
label=f"class {target_class}",
alpha=0.5,
marker=marker,
)
ax2.scatter(
x=X_train_std_transformed[y_train == target_class, 0],
y=X_train_std_transformed[y_train == target_class, 1],
color=color,
label=f"class {target_class}",
alpha=0.5,
marker=marker,
)
ax1.set_title("Ensemble d'entraînement non mis à l'échelle après PCA")
ax2.set_title("Ensemble d'entraînement standardisé après PCA")
for ax in (ax1, ax2):
ax.set_xlabel("1ère composante principale")
ax.set_ylabel("2ème composante principale")
ax.legend(loc="upper right")
ax.grid()
_ = plt.tight_layout()
Effet de la mise à l'échelle sur les performances du modèle
Nous allons entraîner un modèle de régression logistique avec des données réduites par PCA pour évaluer l'effet de la mise à l'échelle des fonctionnalités sur les performances du modèle. Nous comparerons les performances du modèle avec des fonctionnalités non mises à l'échelle et mises à l'échelle.
import numpy as np
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LogisticRegressionCV
from sklearn.metrics import accuracy_score
from sklearn.metrics import log_loss
Cs = np.logspace(-5, 5, 20)
unscaled_clf = make_pipeline(pca, LogisticRegressionCV(Cs=Cs))
unscaled_clf.fit(X_train, y_train)
scaled_clf = make_pipeline(scaler, pca, LogisticRegressionCV(Cs=Cs))
scaled_clf.fit(X_train, y_train)
y_pred = unscaled_clf.predict(X_test)
y_pred_scaled = scaled_clf.predict(X_test)
y_proba = unscaled_clf.predict_proba(X_test)
y_proba_scaled = scaled_clf.predict_proba(X_test)
print("Précision sur le test pour la PCA non mise à l'échelle")
print(f"{accuracy_score(y_test, y_pred):.2%}\n")
print("Précision sur le test pour les données standardisées avec PCA")
print(f"{accuracy_score(y_test, y_pred_scaled):.2%}\n")
print("Perte logarithmique pour la PCA non mise à l'échelle")
print(f"{log_loss(y_test, y_proba):.3}\n")
print("Perte logarithmique pour les données standardisées avec PCA")
print(f"{log_loss(y_test, y_proba_scaled):.3}")
Sommaire
Dans ce laboratoire, nous avons appris l'importance de la mise à l'échelle des fonctionnalités en apprentissage automatique et son effet sur les performances du modèle. Nous avons exploré l'effet de la mise à l'échelle des fonctionnalités sur un modèle K-plus-proches-voisins et la réduction de dimension par l'Analyse en Composantes Principales (PCA). Nous avons également entraîné un modèle de régression logistique avec des données réduites par PCA pour évaluer l'effet de la mise à l'échelle des fonctionnalités sur les performances du modèle. Nous avons constaté que la mise à l'échelle des fonctionnalités avant la réduction de dimension conduit à des composantes d'un même ordre de grandeur et améliore la séparabilité des classes, ce qui se traduit par de meilleures performances du modèle.