Einführung
In diesem Lab wird gezeigt, wie man mit Hilfe der scikit-learn-Bibliothek die Hyperparameteroptimierung mit Kreuzvalidierung durchführt. Ziel ist es, handschriftliche Ziffernbilder mit einer binären Klassifizierung zu klassifizieren, um das Verständnis zu erleichtern: zu bestimmen, ob eine Ziffer 8 ist oder nicht. Als Datensatz wird der digits-Datensatz verwendet. Die Leistung der ausgewählten Hyperparameter und des trainierten Modells wird anschließend auf einem separaten Evaluierungssatz gemessen, der nicht während des Modellauswahlschritts verwendet wurde.
Tipps für die VM
Nachdem der Start der VM abgeschlossen ist, klicken Sie in der linken oberen 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 von Jupyter Notebook nicht automatisiert werden.
Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback ab, und wir werden das Problem für Sie prompt beheben.
Daten laden
Wir werden den digits-Datensatz laden und die Bilder zu Vektoren flachziehen. Jede 8x8-Pixel-Bild muss in einen Vektor von 64 Pixeln transformiert werden. Somit erhalten wir ein endgültiges Datenarray der Form (n_images, n_pixels). Wir werden die Daten auch in einen Trainings- und einen Testsatz gleicher Größe unterteilen.
from sklearn import datasets
from sklearn.model_selection import train_test_split
digits = datasets.load_digits()
n_samples = len(digits.images)
X = digits.images.reshape((n_samples, -1))
y = digits.target == 8
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)
Grid-Search-Strategie definieren
Wir werden eine Funktion definieren, die an den refit-Parameter der GridSearchCV-Instanz übergeben wird. Sie wird die benutzerdefinierte Strategie implementieren, um den besten Kandidaten aus dem cv_results_-Attribut der GridSearchCV auszuwählen. Nachdem der Kandidat ausgewählt ist, wird er automatisch von der GridSearchCV-Instanz erneut trainiert.
Hierbei ist die Strategie, die Modelle aufzulisten, die in Bezug auf Präzision und Recall die besten sind. Aus den ausgewählten Modellen wählen wir schließlich das am schnellsten vorhersagende Modell. Beachten Sie, dass diese benutzerdefinierten Auswahlkriterien völlig willkürlich sind.
import pandas as pd
from sklearn.metrics import classification_report
def print_dataframe(filtered_cv_results):
"""Schönformatiertes Ausgeben eines gefilterten DataFrames"""
for mean_precision, std_precision, mean_recall, std_recall, params in zip(
filtered_cv_results["mean_test_precision"],
filtered_cv_results["std_test_precision"],
filtered_cv_results["mean_test_recall"],
filtered_cv_results["std_test_recall"],
filtered_cv_results["params"],
):
print(
f"Präzision: {mean_precision:0.3f} (±{std_precision:0.03f}),"
f" Recall: {mean_recall:0.3f} (±{std_recall:0.03f}),"
f" für {params}"
)
print()
def refit_strategy(cv_results):
"""Definiert die Strategie, um den besten Schätzer auszuwählen.
Die hier definierte Strategie besteht darin, alle Ergebnisse unter einem Präzisionsschwellenwert
von 0.98 auszuschließen, die verbleibenden nach Recall zu rangieren und alle Modelle mit einer
Standardabweichung des besten nach Recall zu behalten. Nachdem diese Modelle ausgewählt sind,
können wir das am schnellsten vorhersagende Modell auswählen.
Parameter
----------
cv_results : dict von numpy (maskierten) ndarrays
CV-Ergebnisse, wie sie von der `GridSearchCV` zurückgegeben werden.
Rückgabewert
-------
best_index : int
Der Index des besten Schätzers, wie er in `cv_results` erscheint.
"""
## Druckt die Informationen zur Grid-Search für die verschiedenen Scores
precision_threshold = 0.98
cv_results_ = pd.DataFrame(cv_results)
print("Alle Grid-Search-Ergebnisse:")
print_dataframe(cv_results_)
## Filtert alle Ergebnisse unterhalb der Schwelle aus
high_precision_cv_results = cv_results_[
cv_results_["mean_test_precision"] > precision_threshold
]
print(f"Modelle mit einer Präzision höher als {precision_threshold}:")
print_dataframe(high_precision_cv_results)
high_precision_cv_results = high_precision_cv_results[
[
"mean_score_time",
"mean_test_recall",
"std_test_recall",
"mean_test_precision",
"std_test_precision",
"rank_test_recall",
"rank_test_precision",
"params",
]
]
## Wählt die leistungsfähigsten Modelle in Bezug auf Recall aus
## (innerhalb von 1 Sigma vom besten)
best_recall_std = high_precision_cv_results["mean_test_recall"].std()
best_recall = high_precision_cv_results["mean_test_recall"].max()
best_recall_threshold = best_recall - best_recall_std
high_recall_cv_results = high_precision_cv_results[
high_precision_cv_results["mean_test_recall"] > best_recall_threshold
]
print(
"Von den zuvor ausgewählten Modellen mit hoher Präzision behalten wir alle\n"
"die Modelle innerhalb einer Standardabweichung des Modells mit der höchsten Recall:\n"
)
print_dataframe(high_recall_cv_results)
## Aus den besten Kandidaten wählt das am schnellsten vorhersagende Modell aus
fastest_top_recall_high_precision_index = high_recall_cv_results[
"mean_score_time"
].idxmin()
print(
"\nDas ausgewählte finale Modell ist das am schnellsten vorhersagende aus der zuvor\n"
"ausgewählten Teilmenge der besten Modelle basierend auf Präzision und Recall.\n"
"Seine Bewertungszeit ist:\n\n"
f"{high_recall_cv_results.loc[fastest_top_recall_high_precision_index]}"
)
return fastest_top_recall_high_precision_index
Hyperparameter definieren
Wir werden die Hyperparameter definieren und die GridSearchCV-Instanz erstellen.
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
tuned_parameters = [
{"kernel": ["rbf"], "gamma": [1e-3, 1e-4], "C": [1, 10, 100, 1000]},
{"kernel": ["linear"], "C": [1, 10, 100, 1000]},
]
grid_search = GridSearchCV(
SVC(), tuned_parameters, scoring=["precision", "recall"], refit=refit_strategy
)
Modell anpassen und Vorhersagen treffen
Wir werden das Modell anpassen und Vorhersagen auf dem Evaluierungssatz treffen.
grid_search.fit(X_train, y_train)
## Die von der Grid-Search mit unserer benutzerdefinierten Strategie ausgewählten Parameter sind:
grid_search.best_params_
## Schließlich evaluieren wir das feingestellte Modell auf dem ausgelassenen Evaluierungssatz: das
## `grid_search`-Objekt **wurde automatisch erneut trainiert** auf dem gesamten Trainingssatz
## mit den von unserer benutzerdefinierten Refit-Strategie ausgewählten Parametern.
y_pred = grid_search.predict(X_test)
print(classification_report(y_test, y_pred))
Zusammenfassung
In diesem Lab haben wir gelernt, wie man mit Hilfe der scikit-learn-Bibliothek Hyperparameter-Tuning mit Kreuzvalidierung durchführt. Wir haben den digits-Datensatz verwendet und eine benutzerdefinierte Refit-Strategie definiert, um den besten Kandidaten aus dem cv_results_-Attribut der GridSearchCV-Instanz auszuwählen. Schließlich haben wir das feingestellte Modell auf dem ausgelassenen Evaluierungssatz ausgewertet.