3.5. Validierungskurven: Plotten von Scores zur Bewertung von Modellen#

Jeder Schätzer hat seine Vor- und Nachteile. Sein Generalisierungsfehler kann in Bias, Varianz und Rauschen zerlegt werden. Der Bias eines Schätzers ist sein durchschnittlicher Fehler für verschiedene Trainingssätze. Die Varianz eines Schätzers gibt an, wie empfindlich er auf unterschiedliche Trainingssätze reagiert. Rauschen ist eine Eigenschaft der Daten.

Im folgenden Diagramm sehen wir eine Funktion \(f(x) = \cos (\frac{3}{2} \pi x)\) und einige verrauschte Stichproben dieser Funktion. Wir verwenden drei verschiedene Schätzer, um die Funktion anzupassen: lineare Regression mit Polynommerkmalen vom Grad 1, 4 und 15. Wir sehen, dass der erste Schätzer aufgrund seiner Einfachheit (hoher Bias) bestenfalls nur eine schlechte Anpassung an die Stichproben und die wahre Funktion liefern kann, der zweite Schätzer nähert sie fast perfekt an und der letzte Schätzer passt die Trainingsdaten perfekt an, passt aber nicht sehr gut zur wahren Funktion, d. h. er ist sehr empfindlich gegenüber variierenden Trainingsdaten (hohe Varianz).

../_images/sphx_glr_plot_underfitting_overfitting_001.png

Bias und Varianz sind inhärente Eigenschaften von Schätzern, und wir müssen normalerweise Lernalgorithmen und Hyperparameter so auswählen, dass sowohl Bias als auch Varianz so niedrig wie möglich sind (siehe Bias-Varianz-Dilemma). Eine weitere Möglichkeit, die Varianz eines Modells zu reduzieren, ist die Verwendung von mehr Trainingsdaten. Sie sollten jedoch nur mehr Trainingsdaten sammeln, wenn die wahre Funktion zu komplex ist, um von einem Schätzer mit geringerer Varianz angenähert zu werden.

Bei dem einfachen eindimensionalen Problem, das wir im Beispiel gesehen haben, ist es einfach zu erkennen, ob der Schätzer unter Bias oder Varianz leidet. In hochdimensionalen Räumen können Modelle jedoch sehr schwer zu visualisieren sein. Aus diesem Grund ist es oft hilfreich, die unten beschriebenen Werkzeuge zu verwenden.

Beispiele

3.5.1. Validierungskurve#

Um ein Modell zu validieren, benötigen wir eine Scoring-Funktion (siehe Metriken und Scoring: Quantifizierung der Vorhersagegüte), z. B. Genauigkeit für Klassifikatoren. Der richtige Weg zur Auswahl mehrerer Hyperparameter eines Schätzers ist natürlich die Grid-Suche oder ähnliche Methoden (siehe Optimierung der Hyperparameter eines Schätzers), die den Hyperparameter mit dem maximalen Score auf einem Validierungsdatensatz oder mehreren Validierungsdatensätzen auswählen. Beachten Sie, dass der Validierungs-Score verzerrt ist und keine gute Schätzung der Generalisierung mehr darstellt, wenn wir die Hyperparameter basierend auf einem Validierungs-Score optimieren. Um eine ordnungsgemäße Schätzung der Generalisierung zu erhalten, müssen wir den Score auf einem anderen Testdatensatz berechnen.

Es ist jedoch manchmal hilfreich, den Einfluss eines einzelnen Hyperparameters auf den Trainings-Score und den Validierungs-Score zu plotten, um festzustellen, ob der Schätzer für bestimmte Hyperparameterwerte über- oder unteranpasst.

Die Funktion validation_curve kann in diesem Fall helfen

>>> import numpy as np
>>> from sklearn.model_selection import validation_curve
>>> from sklearn.datasets import load_iris
>>> from sklearn.svm import SVC

>>> np.random.seed(0)
>>> X, y = load_iris(return_X_y=True)
>>> indices = np.arange(y.shape[0])
>>> np.random.shuffle(indices)
>>> X, y = X[indices], y[indices]

>>> train_scores, valid_scores = validation_curve(
...     SVC(kernel="linear"), X, y, param_name="C", param_range=np.logspace(-7, 3, 3),
... )
>>> train_scores
array([[0.90, 0.94, 0.91, 0.89, 0.92],
       [0.9 , 0.92, 0.93, 0.92, 0.93],
       [0.97, 1   , 0.98, 0.97, 0.99]])
>>> valid_scores
array([[0.9, 0.9 , 0.9 , 0.96, 0.9 ],
       [0.9, 0.83, 0.96, 0.96, 0.93],
       [1. , 0.93, 1   , 1   , 0.9 ]])

Wenn Sie nur die Validierungskurven plotten möchten, ist die Klasse ValidationCurveDisplay direkter als die manuelle Verwendung von Matplotlib auf den Ergebnissen eines Aufrufs von validation_curve. Sie können die Methode from_estimator ähnlich wie validation_curve verwenden, um die Validierungskurve zu generieren und zu plotten.

from sklearn.datasets import load_iris
from sklearn.model_selection import ValidationCurveDisplay
from sklearn.svm import SVC
from sklearn.utils import shuffle
X, y = load_iris(return_X_y=True)
X, y = shuffle(X, y, random_state=0)
ValidationCurveDisplay.from_estimator(
   SVC(kernel="linear"), X, y, param_name="C", param_range=np.logspace(-7, 3, 10)
)
../_images/learning_curve-1.png

Wenn der Trainings-Score und der Validierungs-Score beide niedrig sind, wird der Schätzer unteranpassen. Wenn der Trainings-Score hoch und der Validierungs-Score niedrig ist, überanpasst der Schätzer, und ansonsten funktioniert er sehr gut. Ein niedriger Trainings-Score und ein hoher Validierungs-Score sind normalerweise nicht möglich.

3.5.2. Lernkurve#

Eine Lernkurve zeigt den Validierungs- und Trainings-Score eines Schätzers für eine variable Anzahl von Trainingsstichproben. Sie ist ein Werkzeug, um herauszufinden, wie sehr wir von der Hinzufügung weiterer Trainingsdaten profitieren und ob der Schätzer mehr unter einem Varianzfehler oder einem Biasfehler leidet. Betrachten Sie das folgende Beispiel, in dem wir die Lernkurve eines Naive-Bayes-Klassifikators und eines SVM plotten.

Für Naive Bayes konvergieren sowohl der Validierungs-Score als auch der Trainings-Score mit zunehmender Größe des Trainingssatzes zu einem Wert, der ziemlich niedrig ist. Daher werden wir wahrscheinlich nicht viel von mehr Trainingsdaten profitieren.

Im Gegensatz dazu ist für kleine Datenmengen der Trainings-Score des SVM deutlich höher als der Validierungs-Score. Das Hinzufügen weiterer Trainingsstichproben wird die Generalisierung höchstwahrscheinlich verbessern.

../_images/sphx_glr_plot_learning_curve_001.png

Wir können die Funktion learning_curve verwenden, um die Werte zu generieren, die zum Plotten einer solchen Lernkurve erforderlich sind (Anzahl der verwendeten Stichproben, die durchschnittlichen Scores auf den Trainingssätzen und die durchschnittlichen Scores auf den Validierungssätzen).

>>> from sklearn.model_selection import learning_curve
>>> from sklearn.svm import SVC

>>> train_sizes, train_scores, valid_scores = learning_curve(
...     SVC(kernel='linear'), X, y, train_sizes=[50, 80, 110], cv=5)
>>> train_sizes
array([ 50, 80, 110])
>>> train_scores
array([[0.98, 0.98 , 0.98, 0.98, 0.98],
       [0.98, 1.   , 0.98, 0.98, 0.98],
       [0.98, 1.   , 0.98, 0.98, 0.99]])
>>> valid_scores
array([[1. ,  0.93,  1. ,  1. ,  0.96],
       [1. ,  0.96,  1. ,  1. ,  0.96],
       [1. ,  0.96,  1. ,  1. ,  0.96]])

Wenn Sie nur die Lernkurven plotten möchten, ist die Klasse LearningCurveDisplay einfacher zu verwenden. Sie können die Methode from_estimator ähnlich wie learning_curve verwenden, um die Lernkurve zu generieren und zu plotten.

from sklearn.datasets import load_iris
from sklearn.model_selection import LearningCurveDisplay
from sklearn.svm import SVC
from sklearn.utils import shuffle
X, y = load_iris(return_X_y=True)
X, y = shuffle(X, y, random_state=0)
LearningCurveDisplay.from_estimator(
   SVC(kernel="linear"), X, y, train_sizes=[50, 80, 110], cv=5)
../_images/learning_curve-2.png

Beispiele