Das Plotten von Lernkurven

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

Zweck dieses Labors ist es, zu zeigen, wie man die Klasse LearningCurveDisplay aus scikit-learn verwendet, um Lernkurven zu plotten. Lernkurven zeigen die Auswirkungen der Hinzufügung von mehr Proben während des Trainingsvorgangs. Wir werden die Lernkurve eines Naiven Bayes-Klassifikators und eines SVM-Klassifikators mit einem RBF-Kern unter Verwendung des Digits-Datensatzes analysieren. Darüber hinaus werden wir die Skalierbarkeit dieser prädiktiven Modelle betrachten, indem wir ihre Rechenkosten und nicht nur ihre statistische Genauigkeit betrachten.

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 von 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.

Lade den Datensatz

from sklearn.datasets import load_digits

X, y = load_digits(return_X_y=True)

Definiere die Modelle

from sklearn.naive_bayes import GaussianNB
from sklearn.svm import SVC

naive_bayes = GaussianNB()
svc = SVC(kernel="rbf", gamma=0.001)

Plotte die Lernkurven

import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import LearningCurveDisplay, ShuffleSplit

fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 6), sharey=True)

common_params = {
    "X": X,
    "y": y,
    "train_sizes": np.linspace(0.1, 1.0, 5),
    "cv": ShuffleSplit(n_splits=50, test_size=0.2, random_state=0),
    "score_type": "both",
    "n_jobs": 4,
    "line_kw": {"marker": "o"},
    "std_display_style": "fill_between",
    "score_name": "Accuracy",
}

for ax_idx, estimator in enumerate([naive_bayes, svc]):
    LearningCurveDisplay.from_estimator(estimator, **common_params, ax=ax[ax_idx])
    handles, label = ax[ax_idx].get_legend_handles_labels()
    ax[ax_idx].legend(handles[:2], ["Training Score", "Test Score"])
    ax[ax_idx].set_title(f"Learning Curve for {estimator.__class__.__name__}")

Analysiere die Lernkurven

## Interpret the learning curves

Wir können die Lernkurve des Naiven Bayes-Klassifikators analysieren. Ihre Form kann in komplexeren Datensätzen sehr häufig gefunden werden: Die Trainingsgenauigkeit ist sehr hoch, wenn nur wenige Proben zum Training verwendet werden, und sinkt, wenn die Anzahl der Proben erhöht wird, während die Testgenauigkeit am Anfang sehr niedrig ist und dann steigt, wenn Proben hinzugefügt werden. Die Trainings- und Testgenauigkeiten werden realistischer, wenn alle Proben zum Training verwendet werden.

Wir sehen eine andere typische Lernkurve für den SVM-Klassifikator mit RBF-Kern. Die Trainingsgenauigkeit bleibt hoch, unabhängig von der Größe des Trainingssatzes. Andererseits steigt die Testgenauigkeit mit der Größe des Trainingsdatensatzes. Tatsächlich steigt sie bis zu einem Punkt, an dem sie einen Plateau erreicht. Das Beobachten eines solchen Plateaus deutet darauf hin, dass es möglicherweise nicht nützlich ist, neue Daten zum Trainieren des Modells zu erwerben, da die Generalisierungskapazität des Modells nicht mehr zunehmen wird.

Überprüfe die Skalierbarkeit der Modelle

from sklearn.model_selection import learning_curve

common_params = {
    "X": X,
    "y": y,
    "train_sizes": np.linspace(0.1, 1.0, 5),
    "cv": ShuffleSplit(n_splits=50, test_size=0.2, random_state=0),
    "n_jobs": 4,
    "return_times": True,
}

train_sizes, _, test_scores_nb, fit_times_nb, score_times_nb = learning_curve(
    naive_bayes, **common_params
)
train_sizes, _, test_scores_svm, fit_times_svm, score_times_svm = learning_curve(
    svc, **common_params
)

Plotte die Skalierbarkeit der Modelle

fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(16, 12), sharex=True)

for ax_idx, (fit_times, score_times, estimator) in enumerate(
    zip(
        [fit_times_nb, fit_times_svm],
        [score_times_nb, score_times_svm],
        [naive_bayes, svc],
    )
):
    ## Skalierbarkeit im Hinblick auf die Anpassungszeit
    ax[0, ax_idx].plot(train_sizes, fit_times.mean(axis=1), "o-")
    ax[0, ax_idx].fill_between(
        train_sizes,
        fit_times.mean(axis=1) - fit_times.std(axis=1),
        fit_times.mean(axis=1) + fit_times.std(axis=1),
        alpha=0.3,
    )
    ax[0, ax_idx].set_ylabel("Anpassungszeit (s)")
    ax[0, ax_idx].set_title(
        f"Skalierbarkeit des {estimator.__class__.__name__} - Klassifikators"
    )

    ## Skalierbarkeit im Hinblick auf die Bewertungszeit
    ax[1, ax_idx].plot(train_sizes, score_times.mean(axis=1), "o-")
    ax[1, ax_idx].fill_between(
        train_sizes,
        score_times.mean(axis=1) - score_times.std(axis=1),
        score_times.mean(axis=1) + score_times.std(axis=1),
        alpha=0.3,
    )
    ax[1, ax_idx].set_ylabel("Bewertungszeit (s)")
    ax[1, ax_idx].set_xlabel("Anzahl der Trainingsbeispiele")

Prüfe das Kompromiss zwischen erhöhter Trainingszeit und Kreuzvalidierungs-Score

fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(16, 6))

for ax_idx, (fit_times, test_scores, estimator) in enumerate(
    zip(
        [fit_times_nb, fit_times_svm],
        [test_scores_nb, test_scores_svm],
        [naive_bayes, svc],
    )
):
    ax[ax_idx].plot(fit_times.mean(axis=1), test_scores.mean(axis=1), "o-")
    ax[ax_idx].fill_between(
        fit_times.mean(axis=1),
        test_scores.mean(axis=1) - test_scores.std(axis=1),
        test_scores.mean(axis=1) + test_scores.std(axis=1),
        alpha=0.3,
    )
    ax[ax_idx].set_ylabel("Genauigkeit")
    ax[ax_idx].set_xlabel("Anpassungszeit (s)")
    ax[ax_idx].set_title(
        f"Leistung des {estimator.__class__.__name__} - Klassifikators"
    )

plt.show()

Zusammenfassung

In diesem Lab haben wir gezeigt, wie man die LearningCurveDisplay-Klasse aus scikit-learn verwendet, um Lernkurven zu plotten. Wir haben die Lernkurve eines Naiven Bayes-Klassifikators und eines SVM-Klassifikators mit RBF-Kern mithilfe des digits-Datensatzes analysiert. Darüber hinaus haben wir uns die Skalierbarkeit dieser prädiktiven Modelle anhand ihres Rechenaufwands und nicht nur ihrer statistischen Genauigkeit angesehen. Wir haben festgestellt, dass die Skalierbarkeit der SVM- und des Naiven Bayes-Klassifikatoren sehr unterschiedlich ist. Die Komplexität des SVM-Klassifikators bei der Anpassung und der Bewertung steigt schnell mit der Anzahl der Proben. Im Gegensatz dazu skaliert der Naive Bayes-Klassifikator viel besser mit einer geringeren Komplexität bei der Anpassung und der Bewertung. Wir haben auch das Kompromiss zwischen erhöhter Trainingszeit und dem Kreuzvalidierungs-Score überprüft.