

Discover more from Tinz Twins Tech Blog
Eine visuelle Einführung in die Kreuzvalidierung
Lerne wie du die Kreuzvalidierung einsetzen kannst (mit Python-Beispielen)
Die Kreuzvalidierung (engl. Cross Validation, kurz CV) ist ein statistisches Testverfahren, das auf einer erneuten Stichprobenziehung beruht. Es ist ein wesentliches Instrument der modernen Statistik. Unter Resampling versteht man die wiederholte Entnahme von Stichproben aus einem Trainingsdatensatz und die erneute Anpassung eines Modells an jede Stichprobe. Dieser Ansatz ermöglicht es, wichtige Informationen über das angepasste Modell zu erhalten.
Resampling-Methoden können sehr rechenintensiv sein, da das statistische Modell mehrmals auf verschiedene Teilmengen des Trainingsdatensatzes angewendet wird. Du kannst zum Beispiel die Kreuzvalidierung verwenden, um den Testfehler zu schätzen. Anhand des Testfehlers kannst du die Leistung einer Lernmethode bewerten oder das geeignete Maß an Flexibilität auswählen. Die Bewertung der Leistung eines Modells wird als Modellbeurteilung bezeichnet. Die Auswahl des Flexibilitätsgrads eines Modells wird als Modellauswahl bezeichnet. [1]
Grundidee
In der Realität ist ein großer Testdatensatz zum Testen eines statistischen Modells in der Regel nicht verfügbar. Es gibt verschiedene Methoden der Kreuzvalidierung, um dieses Problem zu lösen. Die Grundidee hinter der Kreuzvalidierung ist, dass wir nicht den gesamten Datensatz verwenden, um ein statistisches Modell anzupassen. Wir teilen den Datensatz in einen Trainingsdatensatz und einen Validierungsdatensatz auf. Der Validierungsdatensatz ist normalerweise etwas kleiner als der Trainingsdatensatz. Die folgende Abbildung veranschaulicht dies.
Wir passen ein statistisches Modell mit dem Trainingsdatensatz an. Dann wenden wir das trainierte Modell auf den Validierungsdatensatz an.
Die zentrale Frage ist: Wie gut funktioniert das statistische Modell auf dem Testdatensatz? Man kann dies auch als Güte der Anpassung bezeichnen.
Anpassungsgüte
Du kannst die Anpassungsgüte einer Vorhersage messen. Dann kannst du sehen, wie gut die Vorhersage mit den Daten übereinstimmt. Es gibt drei Raten:
Test Error Rate: Fehler bei der Vorhersage von Testdaten
Validation Error Rate: Geschätzte Test Error Rate
Training Error Rate: Fehler bei der Vorhersage von Trainingsdaten
In der Regel wird der mittlere quadratische Fehler (engl. Mean Squared Error, kurz MSE) zur Berechnung dieser Raten verwendet.
Formel MSE:
Beispiel Datensatz
In diesem Artikel verwenden wir den "California housing dataset" (lizenziert unter BSD 3 Clause) als Beispieldatensatz. Das Ziel ist die Vorhersage von Hauspreisen.
Importieren der Daten
Im ersten Schritt importieren wir die Daten mit folgendem Python Code:
from sklearn import datasets
california_housing = datasets.fetch_california_housing(as_frame=True)
Beschreibung der Variablen
Schauen wir uns nun die Beschreibung der einzelnen Variablen an, um die Faktoren zu verstehen, die den Hauspreis beeinflussen.
print(california_housing.DESCR)
# Output:
# . _california_housing_dataset:
#
# California Housing dataset
# --------------------------
#
# **Data Set Characteristics:**
#
# :Number of Instances: 20640
#
# :Number of Attributes: 8 numeric, predictive attributes and the target
#
# :Attribute Information:
# - MedInc median income in block group
# - HouseAge median house age in block group
# - AveRooms average number of rooms per household
# - AveBedrms average number of bedrooms per household
# - Population block group population
# - AveOccup average number of household members
# - Latitude block group latitude
# - Longitude block group longitude
Datensatz im Detail
Nun speichern wir die Daten ohne die Zielvariable in X
.
X = california_housing.data
X.head()
Ausgabe:
Im Folgenden speichern wir die Zielvariable “MedHouseVal” in y
. Die Zielvariable ist der mediane Hauswert für die kalifornischen Bezirke (in Hunderttausenden von Dollar - 100.000 $).
# target variable
y = california_housing.target
y.head()
# Output:
# 0 4.526
# 1 3.585
# 2 3.521
# 3 3.413
# 4 3.422
# Name: MedHouseVal, dtype: float64
Validation Set Approach
Der Validierungssatz-Ansatz (engl. validation set approach) ist die einfachste Art der Kreuzvalidierung. Dabei wird der Datensatz in einen Trainings- und einen Validierungsdatensatz unterteilt. Dies veranschaulicht die folgende Abbildung.
Der Ansatz besteht darin, das Modell anhand des Trainingsdatensatzes anzupassen. Anschließend wird geprüft, wie gut das Modell die Daten im Validierungsdatensatz vorhersagen kann. Die Formel für die Validation Error Rate lautet wie folgt:
Die Validation Error Rate liefert eine Schätzung für die Test Error Rate.
Vorteile
Sehr einfache Strategie: Schnelle Ausführungszeit
Nachteile
Starke Abhängigkeit von der Verteilung: Der Trainingsdatensatz und der Validierungsdatensatz weisen häufig unterschiedliche Eigenschaften auf.
Anpassung des Modells nur auf den Trainingsdatensatz
Code Beispiel: Validation Set Approach
Jetzt zeigen wir dir, wie du den Validation Set Approach in Python verwenden kannst. Als Beispiel verwenden wir eine einfache lineare Regression. Wir berechnen die Validation Error Rate und führen eine Laufzeitmessung durch.
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import LinearRegression
from time import perf_counter
start = perf_counter()
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
linear_regression = LinearRegression()
linear_regression.fit(X_train, y_train)
y_pred = linear_regression.predict(X_val)
val_error_rate = mean_squared_error(y_val, y_pred)
print(perf_counter()-start)
# Output:
# 0.018002947996137664 s
print(val_error_rate)
# Output:
# 0.5558915986952442
Wir verwenden die Funktion train_test_split()
aus dem Python-Paket sklearn, um den Datensatz in einen Trainings- und einen Validierungsdatensatz aufzuteilen. Dann passen wir ein lineares Regressionsmodell mit den Trainingsdaten an. Wir verwenden das trainierte Modell, um die Validierungsdaten vorherzusagen. Anschließend berechnen wir die Validation Error Rate mit der oben dargestellten Formel. Die Laufzeit beträgt ca. 18 ms und die Validation Error Rate liegt bei ca. 0,56.
Leave-One-Out Cross-Validation (LOOCV)
Wie beim Validation Set Approach wird auch beim LOOCV-Ansatz der Datensatz in zwei Teile aufgeteilt. Bei LOOCV wird eine einzige Beobachtung als Validierungsdatensatz (Validierungsdatenpunkt) verwendet, während die übrigen Beobachtungen zum Trainingsdatensatz gehören. Jede Beobachtung ist genau einmal der Validierungsdatenpunkt. Die folgende Abbildung veranschaulicht das Verfahren.
Wir führen die Anpassung des Modells und die Vorhersage eines Validierungsdatenpunkts insgesamt n-mal durch. Die Berechnung läuft wie folgt ab:
Wir berechnen den MSE für jede i-te Ausführung. Dann können wir den durchschnittlichen Validierungs-MSE berechnen.
Vorteile
Wir verwenden den gesamten Datensatz für das Modelltraining. Bei diesem Ansatz wird die Test Error Rate nicht so stark überschätzt wie beim Validation Set Approach.
Die Aufteilung des Datensatzes ist schematisch. Jeder Datenpunkt ist ein Validierungsdatenpunkt.
Nachteile
Hoher Aufwand: Wir müssen das Modell n-mal anpassen.
Code Beispiel: LOOCV
Wir verwenden wieder eine einfache Regression. Bei LOOCV ist jeder Datenpunkt einmal ein Validierungsdatenpunkt, so dass wir für jede Iteration eine Modellanpassung durchführen. Wir verwenden die Funktion LeaveOneOut()
aus dem Python-Paket sklearn. Darüber hinaus berechnen wir erneut die Validation Error Rate und messen die Laufzeit.
from sklearn.model_selection import LeaveOneOut
from sklearn.metrics import mean_squared_error
from statistics import mean
from sklearn.linear_model import LinearRegression
from time import perf_counter
start = perf_counter()
loo = LeaveOneOut()
linear_regression = LinearRegression()
mse_i_list = []
for train, val in loo.split(X):
X_train, X_val, y_train, y_val = X.loc[train], X.loc[val], y[train], y[val]
linear_regression.fit(X_train, y_train)
y_pred = linear_regression.predict(X_val)
mse_i = mean_squared_error(y_val, y_pred)
mse_i_list.append(mse_i)
val_error_rate = mean(mse_i_list)
print(perf_counter()-start)
# Output:
# 204.986410274003 s
print(val_error_rate)
# Output:
# 0.528246204371246
Wir führen die Berechnung des mse_i
für jede i-te Iteration durch. Wir speichern die Ergebnisse in der Liste mse_i_list
. Nach n Iterationen berechnen wir die Validation Error Rate, indem wir die Werte der Liste mitteln. Die Validation Error Rate beträgt ca. 0,53. Die LOOCV-Methode hat eine lange Laufzeit (ca. 204,99 s). Dies war zu erwarten, da die Modellanpassung n-mal durchgeführt wird. Die Validation Error Rate ist niedriger als beim Validation Set Approach.
K-Fold Cross-Validation (k-fold CV)
Dieser Ansatz stellt einen Kompromiss zwischen dem Validation Set Approach und dem LOOCV-Ansatz dar. Bei diesem Ansatz wird die Menge der Beobachtungen nach dem Zufallsprinzip in k Gruppen (Folds) von annähernd gleicher Größe unterteilt. Die folgende Abbildung veranschaulicht dies.
Die Abbildung zeigt eine 3-fold Kreuzvalidierung. Im ersten Durchlauf ist die erste Gruppe der Validierungsdatensatz und die anderen Gruppen sind der Trainingsdatensatz. Im zweiten Durchlauf ist die zweite Gruppe der Validierungsdatensatz. Im dritten Durchlauf ist die dritte Gruppe der Validierungsdatensatz. Dieses Verfahren führt zu k Schätzungen des Test Errors, MSE_1 , MSE_2 , . . . , MSE_k . Wir berechnen die Validation Error Rate, indem wir diese Werte mitteln:
In der Praxis wird häufig eine k-fold CV mit k = 5 oder k = 10 durchgeführt.
Vorteile
Weniger verzerrtes Modell (engl. less biased model) als bei den anderen Methoden
Es ist eine der besten Methoden, wenn nur begrenzte Eingabedaten verfügbar sind.
Nachteile
Wir müssen das Modell k-mal passen. Diesen Nachteil können wir jedoch in Kauf nehmen, um die Test Error Rate so genau wie möglich zu schätzen.
Code Beispiel: k-fold CV
Wir führen wieder eine einfache lineare Regression durch. Aber jetzt teilen wir unseren Datensatz in zehn Gruppen ein. Es gibt also zehn Iterationen. Jede Gruppe ist einmal der Validierungsdatensatz. Wir verwenden dazu KFold
aus dem Modul sklearn.model_selection
. Wir messen wieder die Laufzeit und berechnen die Validation Error Rate.
from sklearn.model_selection import KFold
from sklearn.metrics import mean_squared_error
from statistics import mean
from sklearn.linear_model import LinearRegression
from time import perf_counter
start = perf_counter()
kf = KFold(n_splits=10)
linear_regression = LinearRegression()
mse_i_list = []
for train, val in kf.split(X):
X_train, X_val, y_train, y_val = X.loc[train], X.loc[val], y[train], y[val]
linear_regression.fit(X_train, y_train)
y_pred = linear_regression.predict(X_val)
mse_i = mean_squared_error(y_val, y_pred)
mse_i_list.append(mse_i)
val_error_rate = mean(mse_i_list)
print(perf_counter()-start)
# Output:
# 0.19677724000939634 s
print(val_error_rate)
# Output:
# 0.5509524296956597
Für jede i-te Iteration berechnen wir den mse_i
und speichern ihn in der Liste mse_i_list
. Dann berechnen wir die Validation Error Rate, indem wir die Werte der Liste mitteln. Wir erhalten eine Validation Error Rate von ca. 0,55. Wir erkennen auch, dass die k-fold CV eine viel kürzere Laufzeit hat als die LOOCV (ca. 19,68).
Fazit
Die Kreuzvalidierung ist ein Werkzeug für die Modellauswahl und die Leistungsabschätzung. Sie ermöglicht eine robuste und zuverlässige Bewertung von Modellen des maschinellen Lernens.
Lessons Learned:
Validation Set Approach: Du teilst den Datensatz in einen Trainings- und einen Validierungsdatensatz auf. Bei einem kleinen Datensatz hat diese Methode den Nachteil, dass die Trainingsdaten möglicherweise keine wichtigen Informationen enthalten.
Leave-One-Out Cross-Validation: Bei der LOOCV wird eine einzige Beobachtung als Validierungsdatenpunkt verwendet, während die übrigen Daten zum Trainingsdatensatz gehören. Dieser Ansatz liefert die beste Schätzung für die Testfehlerrate. Es ist jedoch sehr rechenintensiv.
K-Fold Cross-Validation: Bei diesem Ansatz wird der Datensatz nach dem Zufallsprinzip in k gleich große Gruppen aufgeteilt. In der Praxis verwendet man gewöhnlich k = 5 oder k = 10. Diese Anzahl von Gruppen führt zu ausreichend guten Ergebnissen.
👉🏽 Du findest alle digitalen Produkte von uns in unserem Online Shop! Schaue gerne mal vorbei.
Dir gefällt unserer Content und wir konnten dir weiterhelfen? Dann unterstütze uns doch, indem du unsere Spendenoption auf Buy me a coffee nutzt oder unsere Artikel mit anderen teilst. Vergesse auch nicht, uns auf YouTube zu folgen. Vielen Dank für deine Unterstützung! 🙏🏽🙏🏽
Erfahre mehr über uns auf unserer About-Seite. Du kannst unseren Tech Blog auch gerne weiterempfehlen. Nutze hierfür einfach unser Empfehlungsprogramm und sichere dir Vorteile. Vielen Dank fürs Lesen.
Referenzen
* Affiliate-Link / Anzeige: Die Links sind Affiliate-Links, d.h. wir erhalten eine Provision, wenn du über diese Links einkaufst. Es entstehen keine zusätzlichen Kosten für dich.