Unteranpassung (Underfitting) und Überanpassung (Overfitting)

Beginner

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

Einführung

Dieses Lab demonstriert die Probleme des Unteranpassens (Underfitting) und Überanpassens (Overfitting) in der maschinellen Lernens und wie wir lineare Regression mit polynomiellen Merkmalen verwenden können, um nichtlineare Funktionen zu approximieren. Wir werden scikit-learn nutzen, um Daten zu generieren, Modelle anzupassen und die Leistung der Modelle zu bewerten.

Tipps für die virtuelle Maschine (VM)

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

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

Wenn Sie während des Lernens Probleme haben, können Sie sich gerne an Labby wenden. Geben Sie nach der Sitzung Feedback ab, und wir werden das Problem umgehend für Sie lösen.

Importieren von Bibliotheken

Zunächst werden wir die für dieses Lab erforderlichen Bibliotheken importieren.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score

Daten generieren

Wir werden 30 Stichproben aus einer Kosinusfunktion generieren und diesen Stichproben etwas Zufallsrauschen hinzufügen.

def true_fun(X):
    return np.cos(1.5 * np.pi * X)

np.random.seed(0)

n_samples = 30

X = np.sort(np.random.rand(n_samples))
y = true_fun(X) + np.random.randn(n_samples) * 0.1

Daten visualisieren

Wir werden die wahre Funktion und die generierten Stichproben grafisch darstellen.

plt.figure(figsize=(6, 4))
plt.plot(np.linspace(0, 1, 100), true_fun(np.linspace(0, 1, 100)), label="True function")
plt.scatter(X, y, edgecolor="b", s=20, label="Samples")
plt.xlabel("x")
plt.ylabel("y")
plt.legend(loc="best")
plt.show()

Modelle mit polynomiellen Merkmalen anpassen

Wir werden Modelle mit polynomiellen Merkmalen vom Grad 1, 4 und 15 anpassen und die Ergebnisse grafisch darstellen.

degrees = [1, 4, 15]

plt.figure(figsize=(14, 5))

for i in range(len(degrees)):
    ax = plt.subplot(1, len(degrees), i + 1)
    plt.setp(ax, xticks=(), yticks=())

    polynomial_features = PolynomialFeatures(degree=degrees[i], include_bias=False)
    linear_regression = LinearRegression()
    pipeline = Pipeline(
        [
            ("polynomial_features", polynomial_features),
            ("linear_regression", linear_regression),
        ]
    )
    pipeline.fit(X[:, np.newaxis], y)

    X_test = np.linspace(0, 1, 100)
    plt.plot(X_test, pipeline.predict(X_test[:, np.newaxis]), label="Model")
    plt.plot(X_test, true_fun(X_test), label="True function")
    plt.scatter(X, y, edgecolor="b", s=20, label="Samples")
    plt.xlabel("x")
    plt.ylabel("y")
    plt.xlim((0, 1))
    plt.ylim((-2, 2))
    plt.legend(loc="best")
    plt.title("Degree {}".format(degrees[i]))

plt.show()

Modellleistung auswerten

Wir werden die Modelle mithilfe von Kreuzvalidierung (cross-validation) auswerten und den mittleren quadratischen Fehler (Mean Squared Error, MSE) auf dem Validierungssatz berechnen.

degrees = [1, 4, 15]

plt.figure(figsize=(14, 5))

for i in range(len(degrees)):
    ax = plt.subplot(1, len(degrees), i + 1)
    plt.setp(ax, xticks=(), yticks=())

    polynomial_features = PolynomialFeatures(degree=degrees[i], include_bias=False)
    linear_regression = LinearRegression()
    pipeline = Pipeline(
        [
            ("polynomial_features", polynomial_features),
            ("linear_regression", linear_regression),
        ]
    )
    pipeline.fit(X[:, np.newaxis], y)

    ## Evaluate the models using crossvalidation
    scores = cross_val_score(
        pipeline, X[:, np.newaxis], y, scoring="neg_mean_squared_error", cv=10
    )

    X_test = np.linspace(0, 1, 100)
    plt.plot(X_test, pipeline.predict(X_test[:, np.newaxis]), label="Model")
    plt.plot(X_test, true_fun(X_test), label="True function")
    plt.scatter(X, y, edgecolor="b", s=20, label="Samples")
    plt.xlabel("x")
    plt.ylabel("y")
    plt.xlim((0, 1))
    plt.ylim((-2, 2))
    plt.legend(loc="best")
    plt.title(
        "Degree {}\nMSE = {:.2e}(+/- {:.2e})".format(
            degrees[i], -scores.mean(), scores.std()
        )
    )

plt.show()

Zusammenfassung

Dieses Lab (Praktikum) hat gezeigt, wie man lineare Regression mit polynomiellen Merkmalen verwendet, um nichtlineare Funktionen zu approximieren, und wie man die Modellleistung mithilfe von Kreuzvalidierung (cross-validation) auswertet. Wir haben gesehen, dass eine lineare Funktion nicht ausreicht, um die Trainingsstichproben anzupassen, und dass ein Polynom vom Grad 4 die wahre Funktion fast perfekt approximiert. Bei höheren Graden jedoch wird das Modell die Trainingsdaten überanpassen (overfitting) und das Rauschen der Trainingsdaten lernen. Wir können Kreuzvalidierung und den mittleren quadratischen Fehler (Mean Squared Error, MSE) verwenden, um die Modellleistung auszuwerten und Überanpassung zu vermeiden.