Einführung
Die Feature-Skalierung ist ein wichtiger Vorverarbeitungsschritt für viele Machine-Learning-Algorithmen. Dabei wird jedes Feature so skaliert, dass es eine Standardabweichung von 1 und einen Mittelwert von 0 hat. In diesem Lab werden wir die Wichtigkeit der Feature-Skalierung und ihren Einfluss auf Machine-Learning-Modelle mit der scikit-learn-Bibliothek in Python untersuchen.
Tipps für die VM
Nachdem der VM-Start abgeschlossen ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.
Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund der Einschränkungen von Jupyter Notebook nicht automatisiert werden.
Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback ab, und wir werden das Problem für Sie prompt beheben.
Daten laden und vorbereiten
Wir werden den Weindatensatz aus scikit-learn laden und ihn in Trainings- und Testsets unterteilen. Wir skalieren auch die Features im Trainingsset mit dem StandardScaler aus dem scikit-learn-Vorverarbeitungsmodul.
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)
Effekt der Skalierung auf ein k-Nearest-Neighbors-Modell
Wir werden einen Unterbereich von zwei Features aus dem Weindatensatz verwenden, um einen K-Nearest-Neighbors-Klassifizierer zu trainieren. Wir visualisieren die Entscheidungsgrenze des Klassifizierers mit nicht skalierten und skalierten Daten.
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 ohne Skalierung")
fit_and_plot_model(X_plot_scaled, y, clf, ax2)
ax2.set_xlabel("skaliertes proline")
ax2.set_ylabel("skaliertes hue")
_ = ax2.set_title("KNN mit Skalierung")
Effekt der Skalierung auf die PCA-Dimensionalitätreduzierung
Wir werden die Hauptkomponentenanalyse (PCA) verwenden, um die Dimensionalität des Weindatensatzes zu reduzieren. Wir werden die Hauptkomponenten, die mit PCA auf nicht skalierten Daten gefunden werden, mit denen vergleichen, die erhalten werden, wenn man zuerst die Daten mit StandardScaler skaliert.
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="Gewichte der ersten Hauptkomponente", figsize=(6, 8)
)
_ = plt.tight_layout()
fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(10, 5))
target_classes = range(0, 3)
colors = ("blau", "rot", "grün")
markierungen = ("^", "s", "o")
for target_class, color, marker in zip(target_classes, colors, markierungen):
ax1.scatter(
x=X_train_transformed[y_train == target_class, 0],
y=X_train_transformed[y_train == target_class, 1],
color=color,
label=f"Klasse {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"Klasse {target_class}",
alpha=0.5,
marker=marker,
)
ax1.set_title("Nicht skalierter Trainingsdatensatz nach PCA")
ax2.set_title("Standardisierter Trainingsdatensatz nach PCA")
for ax in (ax1, ax2):
ax.set_xlabel("1. Hauptkomponente")
ax.set_ylabel("2. Hauptkomponente")
ax.legend(loc="oben rechts")
ax.grid()
_ = plt.tight_layout()
Effekt der Skalierung auf die Modellleistung
Wir werden ein logistisches Regressionsmodell mit PCA-reduzierten Daten trainieren, um den Effekt der Feature-Skalierung auf die Modellleistung zu evaluieren. Wir werden die Leistung des Modells mit nicht skalierten und skalierten Features vergleichen.
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("Testgenauigkeit für die nicht skalierte PCA")
print(f"{accuracy_score(y_test, y_pred):.2%}\n")
print("Testgenauigkeit für die standardisierten Daten mit PCA")
print(f"{accuracy_score(y_test, y_pred_scaled):.2%}\n")
print("Log-Loss für die nicht skalierte PCA")
print(f"{log_loss(y_test, y_proba):.3}\n")
print("Log-Loss für die standardisierten Daten mit PCA")
print(f"{log_loss(y_test, y_proba_scaled):.3}")
Zusammenfassung
In diesem Lab haben wir die Wichtigkeit der Feature-Skalierung in der Machine Learning und ihren Effekt auf die Modellleistung gelernt. Wir haben den Effekt der Feature-Skalierung auf ein k-Nearest-Neighbors-Modell und die PCA-Dimensionalitätreduzierung untersucht. Wir haben auch ein logistisches Regressionsmodell mit PCA-reduzierten Daten trainiert, um den Effekt der Feature-Skalierung auf die Modellleistung zu evaluieren. Wir haben festgestellt, dass das Skalieren der Features vor der Reduzierung der Dimensionalität zu Komponenten von der gleichen Größenordnung führt und die Trennbarkeit der Klassen verbessert, was zu einer besseren Modellleistung führt.