Transformation des Ziels für lineare Regression

Machine LearningMachine LearningBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab werden wir lernen, wie man den TransformedTargetRegressor aus der scikit-learn-Bibliothek verwendet. Wir werden ihn auf zwei verschiedene Datensätze anwenden, um die Vorteile der Transformation der Zielwerte vor dem Training eines linearen Regressionsmodells zu beobachten. Wir werden synthetische Daten und den Ames Housing-Datensatz verwenden, um die Auswirkungen der Transformation der Zielwerte zu veranschaulichen.

VM-Tipps

Nachdem die VM gestartet ist, klicken Sie in der oberen linken Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu öffnen.

Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund der Einschränkungen in Jupyter Notebook nicht automatisiert werden.

Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/ModelSelectionandEvaluationGroup(["Model Selection and Evaluation"]) sklearn(("Sklearn")) -.-> sklearn/UtilitiesandDatasetsGroup(["Utilities and Datasets"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn(("Sklearn")) -.-> sklearn/CoreModelsandAlgorithmsGroup(["Core Models and Algorithms"]) sklearn(("Sklearn")) -.-> sklearn/DataPreprocessingandFeatureEngineeringGroup(["Data Preprocessing and Feature Engineering"]) sklearn/CoreModelsandAlgorithmsGroup -.-> sklearn/linear_model("Linear Models") sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/preprocessing("Preprocessing and Normalization") sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/model_selection("Model Selection") sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/metrics("Metrics") sklearn/ModelSelectionandEvaluationGroup -.-> sklearn/compose("Composite Estimators") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/datasets("Datasets") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/linear_model -.-> lab-49321{{"Transformation des Ziels für lineare Regression"}} sklearn/preprocessing -.-> lab-49321{{"Transformation des Ziels für lineare Regression"}} sklearn/model_selection -.-> lab-49321{{"Transformation des Ziels für lineare Regression"}} sklearn/metrics -.-> lab-49321{{"Transformation des Ziels für lineare Regression"}} sklearn/compose -.-> lab-49321{{"Transformation des Ziels für lineare Regression"}} sklearn/datasets -.-> lab-49321{{"Transformation des Ziels für lineare Regression"}} ml/sklearn -.-> lab-49321{{"Transformation des Ziels für lineare Regression"}} end

Importieren der erforderlichen Bibliotheken und Laden von synthetischen Daten

Wir beginnen mit dem Importieren der erforderlichen Bibliotheken und dem Laden von synthetischen Daten. Wir generieren einen synthetischen zufälligen Regressionsdatensatz und modifizieren die Zielwerte, indem wir alle Zielwerte so transformieren, dass alle Einträge nicht-negativ sind, und indem wir eine Exponentialfunktion anwenden, um nicht-lineare Zielwerte zu erhalten, die mit einem einfachen linearen Modell nicht angepasst werden können. Anschließend verwenden wir eine logarithmische (np.log1p) und eine Exponentialfunktion (np.expm1), um die Zielwerte zu transformieren, bevor wir ein lineares Regressionsmodell trainieren und es zur Vorhersage verwenden.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.compose import TransformedTargetRegressor
from sklearn.linear_model import RidgeCV
from sklearn.metrics import median_absolute_error, r2_score, PredictionErrorDisplay

## Generate synthetic data
X, y = make_regression(n_samples=10_000, noise=100, random_state=0)

## Modify the targets
y = np.expm1((y + abs(y.min())) / 200)
y_trans = np.log1p(y)

Zeichnen der Zielverteilungen

Wir zeichnen die Wahrscheinlichkeitsdichtefunktionen des Ziels vor und nach der Anwendung der logarithmischen Funktionen.

f, (ax0, ax1) = plt.subplots(1, 2)

ax0.hist(y, bins=100, density=True)
ax0.set_xlim([0, 2000])
ax0.set_ylabel("Wahrscheinlichkeit")
ax0.set_xlabel("Ziel")
ax0.set_title("Zielverteilung")

ax1.hist(y_trans, bins=100, density=True)
ax1.set_ylabel("Wahrscheinlichkeit")
ax1.set_xlabel("Ziel")
ax1.set_title("Transformierte Zielverteilung")

f.suptitle("Synthetische Daten", y=1.05)
plt.tight_layout()

Trainieren und Auswerten eines linearen Regressionsmodells auf den ursprünglichen Zielwerten

Wir trainieren und evaluieren ein lineares Regressionsmodell auf den ursprünglichen Zielwerten. Aufgrund der Nichtlinearität wird das trainierte Modell bei der Vorhersage nicht präzise sein.

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

ridge_cv = RidgeCV().fit(X_train, y_train)
y_pred_ridge = ridge_cv.predict(X_test)

score = {
    "R2": f"{r2_score(y_test, y_pred_ridge):.3f}",
    "MedAE": f"{median_absolute_error(y_test, y_pred_ridge):.3f}",
}

print("Lineare Regression auf ursprüngliche Zielwerte:")
for key, val in score.items():
    print(f"{key}: {val}")

Trainieren und Auswerten eines linearen Regressionsmodells auf den transformierten Zielwerten

Wir trainieren und evaluieren ein lineares Regressionsmodell auf den transformierten Zielwerten mithilfe von TransformedTargetRegressor. Die logarithmische Funktion linearisiert die Zielwerte, was eine bessere Vorhersage ermöglicht, auch mit einem ähnlichen linearen Modell, wie dies durch den median absolute error (MedAE) berichtet wird.

ridge_cv_with_trans_target = TransformedTargetRegressor(
    regressor=RidgeCV(), func=np.log1p, inverse_func=np.expm1
).fit(X_train, y_train)
y_pred_ridge_with_trans_target = ridge_cv_with_trans_target.predict(X_test)

score = {
    "R2": f"{r2_score(y_test, y_pred_ridge_with_trans_target):.3f}",
    "MedAE": f"{median_absolute_error(y_test, y_pred_ridge_with_trans_target):.3f}",
}

print("\nLineare Regression auf transformierte Zielwerte:")
for key, val in score.items():
    print(f"{key}: {val}")

Zeichnen von tatsächlichen vs vorhergesagten Werten für beide Modelle

Wir zeichnen die tatsächlichen vs vorhergesagten Werte für beide Modelle und fügen die Bewertung in der Legende jeder Achse hinzu.

f, (ax0, ax1) = plt.subplots(1, 2, sharey=True)

PredictionErrorDisplay.from_predictions(
    y_test,
    y_pred_ridge,
    kind="actual_vs_predicted",
    ax=ax0,
    scatter_kwargs={"alpha": 0.5},
)
PredictionErrorDisplay.from_predictions(
    y_test,
    y_pred_ridge_with_trans_target,
    kind="actual_vs_predicted",
    ax=ax1,
    scatter_kwargs={"alpha": 0.5},
)

for ax, y_pred in zip([ax0, ax1], [y_pred_ridge, y_pred_ridge_with_trans_target]):
    for name, score in score.items():
        ax.plot([], [], " ", label=f"{name}={score}")
    ax.legend(loc="upper left")

ax0.set_title("Ridge-Regression \n ohne Zieltransformation")
ax1.set_title("Ridge-Regression \n mit Zieltransformation")
f.suptitle("Synthetische Daten", y=1.05)
plt.tight_layout()

Laden und Vorverarbeiten der Ames Wohnungsdaten

Wir laden den Ames Wohnungsdatensatz und verarbeiten ihn, indem wir nur numerische Spalten beibehalten und Spalten mit NaN- oder Inf-Werten entfernen. Das Ziel, das vorhergesagt werden soll, ist der Verkaufspreis jedes Hauses.

from sklearn.datasets import fetch_openml
from sklearn.preprocessing import quantile_transform

ames = fetch_openml(name="house_prices", as_frame=True, parser="pandas")

## Behalte nur numerische Spalten
X = ames.data.select_dtypes(np.number)

## Entferne Spalten mit NaN- oder Inf-Werten
X = X.drop(columns=["LotFrontage", "GarageYrBlt", "MasVnrArea"])

## Lasse den Preis in k$ liegen
y = ames.target / 1000
y_trans = quantile_transform(
    y.to_frame(), n_quantiles=900, output_distribution="normal", copy=True
).squeeze()

Zeichnen der Zielverteilungen für die Ames Wohnungsdaten

Wir zeichnen die Wahrscheinlichkeitsdichtefunktionen des Ziels vor und nach der Anwendung des QuantileTransformers.

f, (ax0, ax1) = plt.subplots(1, 2)

ax0.hist(y, bins=100, density=True)
ax0.set_ylabel("Wahrscheinlichkeit")
ax0.set_xlabel("Ziel")
ax0.set_title("Zielverteilung")

ax1.hist(y_trans, bins=100, density=True)
ax1.set_ylabel("Wahrscheinlichkeit")
ax1.set_xlabel("Ziel")
ax1.set_title("Transformierte Zielverteilung")

f.suptitle("Ames Wohnungsdaten: Verkaufspreis", y=1.05)
plt.tight_layout()

Trainieren und Auswerten eines linearen Regressionsmodells auf den ursprünglichen Zielwerten für die Ames Wohnungsdaten

Wir trainieren und evaluieren ein lineares Regressionsmodell auf den ursprünglichen Zielwerten für die Ames Wohnungsdaten.

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)

ridge_cv = RidgeCV().fit(X_train, y_train)
y_pred_ridge = ridge_cv.predict(X_test)

score = {
    "R2": f"{r2_score(y_test, y_pred_ridge):.3f}",
    "MedAE": f"{median_absolute_error(y_test, y_pred_ridge):.3f}",
}

print("\nLineare Regression auf ursprüngliche Zielwerte:")
for key, val in score.items():
    print(f"{key}: {val}")

Trainieren und Auswerten eines linearen Regressionsmodells auf den transformierten Zielwerten für die Ames Wohnungsdaten

Wir trainieren und evaluieren ein lineares Regressionsmodell auf den transformierten Zielwerten mit Hilfe von TransformedTargetRegressor für die Ames Wohnungsdaten.

ridge_cv_with_trans_target = TransformedTargetRegressor(
    regressor=RidgeCV(),
    transformer=QuantileTransformer(n_quantiles=900, output_distribution="normal"),
).fit(X_train, y_train)
y_pred_ridge_with_trans_target = ridge_cv_with_trans_target.predict(X_test)

score = {
    "R2": f"{r2_score(y_test, y_pred_ridge_with_trans_target):.3f}",
    "MedAE": f"{median_absolute_error(y_test, y_pred_ridge_with_trans_target):.3f}",
}

print("\nLineare Regression auf transformierte Zielwerte:")
for key, val in score.items():
    print(f"{key}: {val}")

Zeichnen von tatsächlichen vs vorhergesagten Werten und Residuen vs vorhergesagten Werten für beide Modelle

Wir zeichnen tatsächliche vs vorhergesagte Werte und Residuen vs vorhergesagte Werte für beide Modelle und fügen die Bewertung in die Legende jeder Achse ein.

f, (ax0, ax1) = plt.subplots(2, 2, sharey="row", figsize=(6.5, 8))

PredictionErrorDisplay.from_predictions(
    y_test,
    y_pred_ridge,
    kind="actual_vs_predicted",
    ax=ax0[0],
    scatter_kwargs={"alpha": 0.5},
)
PredictionErrorDisplay.from_predictions(
    y_test,
    y_pred_ridge_with_trans_target,
    kind="actual_vs_predicted",
    ax=ax0[1],
    scatter_kwargs={"alpha": 0.5},
)

for ax, y_pred in zip([ax0[0], ax0[1]], [y_pred_ridge, y_pred_ridge_with_trans_target]):
    for name, score in score.items():
        ax.plot([], [], " ", label=f"{name}={score}")
    ax.legend(loc="upper left")

ax0[0].set_title("Ridge-Regression \n ohne Zieltransformation")
ax0[1].set_title("Ridge-Regression \n mit Zieltransformation")

PredictionErrorDisplay.from_predictions(
    y_test,
    y_pred_ridge,
    kind="residual_vs_predicted",
    ax=ax1[0],
    scatter_kwargs={"alpha": 0.5},
)
PredictionErrorDisplay.from_predictions(
    y_test,
    y_pred_ridge_with_trans_target,
    kind="residual_vs_predicted",
    ax=ax1[1],
    scatter_kwargs={"alpha": 0.5},
)
ax1[0].set_title("Ridge-Regression \n ohne Zieltransformation")
ax1[1].set_title("Ridge-Regression \n mit Zieltransformation")

f.suptitle("Ames Wohnungsdaten: Verkaufspreis", y=1.05)
plt.tight_layout()
plt.show()

Zusammenfassung

In diesem Lab haben wir gelernt, wie man den TransformedTargetRegressor aus der scikit-learn-Bibliothek verwendet. Wir haben es auf zwei verschiedene Datensätze angewandt, um die Vorteile der Transformation der Zielwerte vor dem Training eines linearen Regressionsmodells zu beobachten. Wir haben synthetische Daten und den Ames Wohnungsdatensatz verwendet, um die Auswirkungen der Transformation der Zielwerte zu veranschaulichen. Wir haben beobachtet, dass die logarithmische Funktion die Zielwerte linearisierte, was es ermöglichte, auch mit einem ähnlichen linearen Modell bessere Vorhersagen zu machen, wie dies durch den median absolute error (MedAE) berichtet wurde. Wir haben auch beobachtet, dass der Effekt des Transformers für den Ames Wohnungsdatensatz schwächer war, aber dennoch zu einer Zunahme von R2 und einem großen Rückgang des MedAE führte.