Читать книгу Praxiseinstieg Machine Learning mit Scikit-Learn, Keras und TensorFlow - Aurélien Géron - Страница 82
Gittersuche
ОглавлениеEine Möglichkeit wäre, von Hand an den Hyperparametern herumzubasteln, bis Sie eine gute Kombination finden. Dies wäre sehr mühselig, und Sie hätten nicht die Zeit, viele Kombinationen auszuprobieren.
Stattdessen sollten Sie die Scikit-Learn-Klasse GridSearchCV die Suche für Sie erledigen lassen. Sie müssen ihr lediglich sagen, mit welchen Hyperparametern Sie experimentieren möchten und welche Werte ausprobiert werden sollen. Dann werden alle möglichen Kombinationen von Hyperparametern über eine Kreuzvalidierung evaluiert. Der folgende Code sucht die beste Kombination der Hyperparameter für den RandomForestRegressor:
from sklearn.model_selection import GridSearchCV
param_grid = [
{'n_estimators': [3, 10, 30], 'max_features': [2, 4, 6, 8]},
{'bootstrap': [False], 'n_estimators': [3, 10], 'max_features': [2, 3, 4]},
]
forest_reg = RandomForestRegressor()
grid_search = GridSearchCV(forest_reg, param_grid, cv=5,
scoring='neg_mean_squared_error',
return_train_score=True)
grid_search.fit(housing_prepared, housing_labels)
Wenn Sie keine Ahnung haben, welchen Wert ein Hyperparameter haben soll, können Sie einfach Zehnerpotenzen ausprobieren (oder für eine feinkörnigere Suche Potenzen einer kleineren Zahl, wie im Beispiel beim Hyperparameter n_estimators). |
Das param_grid weist Scikit-Learn an, zuerst alle Kombinationen von 3 × 4 = 12 der Hyperparameter n_estimators und max_features mit den im ersten dict angegebenen Werten auszuprobieren (keine Sorge, wenn Sie die Bedeutung der Hyperparameter noch nicht kennen; diese werden in Kapitel 7 erklärt). Anschließend werden alle Kombinationen 2 × 3 = 6 der Hyperparameter im zweiten dict ausprobiert, diesmal ist jedoch der Hyperparameter bootstrap auf False statt auf True (den Standardwert) gesetzt.
Insgesamt probiert die Gittersuche Kombinationen von 12 + 6 = 18 der Hyperparameter mit dem RandomForestRegressor aus. Jedes Modell wird fünf Mal trainiert (weil wir eine fünffache Kreuzvalidierung verwenden). Anders gesagt, es gibt Trainingsrunden der Art 18 × 5 = 90! Es kann eine ganze Weile dauern, aber schließlich können Sie die beste Parameterkombination wie folgt abfragen:
>>> grid_search.best_params_
{'max_features': 8, 'n_estimators': 30}
Da 8 und 30 die maximalen ausprobierten Werte sind, sollten wir noch einmal mit höheren Werten suchen, da der Score vielleicht noch besser wird. |
Sie können auch direkt auf den besten Estimator zugreifen:
>>> grid_search.best_estimator_
RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,
max_features=8, max_leaf_nodes=None, min_impurity_decrease=0.0,
min_impurity_split=None, min_samples_leaf=1,
min_samples_split=2, min_weight_fraction_leaf=0.0,
n_estimators=30, n_jobs=None, oob_score=False, random_state=None,
verbose=0, warm_start=False)
Falls GridSearchCV mit refit=True initialisiert wird (der Standardeinstellung), wird der beste über Kreuzvalidierung gefundene Estimator noch einmal mit dem gesamten Trainingsdatensatz trainiert. Dies ist grundsätzlich eine gute Idee, da mehr Daten voraussichtlich die Genauigkeit erhöhen. |
Natürlich sind auch die Scores der Evaluation verfügbar:
>>> cvres = grid_search.cv_results_
>>> for mean_score, params in zip(cvres["mean_test_score"], cvres["params"]):
... print(np.sqrt(-mean_score), params)
...
63669.05791727153 {'max_features': 2, 'n_estimators': 3}
55627.16171305252 {'max_features': 2, 'n_estimators': 10}
53384.57867637289 {'max_features': 2, 'n_estimators': 30}
60965.99185930139 {'max_features': 4, 'n_estimators': 3}
52740.98248528835 {'max_features': 4, 'n_estimators': 10}
50377.344409590376 {'max_features': 4, 'n_estimators': 30}
58663.84733372485 {'max_features': 6, 'n_estimators': 3}
52006.15355973719 {'max_features': 6, 'n_estimators': 10}
50146.465964159885 {'max_features': 6, 'n_estimators': 30}
57869.25504027614 {'max_features': 8, 'n_estimators': 3}
51711.09443660957 {'max_features': 8, 'n_estimators': 10}
49682.25345942335 {'max_features': 8, 'n_estimators': 30}
62895.088889905004 {'bootstrap': False, 'max_features': 2, 'n_estimators': 3}
54658.14484390074 {'bootstrap': False, 'max_features': 2, 'n_estimators': 10}
59470.399594730654 {'bootstrap': False, 'max_features': 3, 'n_estimators': 3}
52725.01091081235 {'bootstrap': False, 'max_features': 3, 'n_estimators': 10}
57490.612956065226 {'bootstrap': False, 'max_features': 4, 'n_estimators': 3}
51009.51445842374 {'bootstrap': False, 'max_features': 4, 'n_estimators': 10}
In diesem Beispiel erhalten wir die beste Lösung, indem wir den Hyperparameter max_features auf 8 setzen und den Hyperparameter n_estimators auf 30. Der RMSE beträgt bei dieser Kombination 49682, was etwas besser als der zuvor mit den voreingestellten Hyperparametern berechnete Wert ist (dieser betrug 50182). Herzlichen Glückwunsch, Sie haben Ihr bestes Modell erfolgreich optimiert!
Vergessen Sie nicht, dass Sie auch einige der Vorverarbeitungsschritte als Hyperparameter ansehen können. Die Gittersuche kann automatisch herausfinden, ob Sie ein Merkmal hinzufügen sollten, dessen Sie sich nicht sicher sind (z.B. den Hyperparameter add_bedrooms_per_room Ihres Transformers CombinedAttributes Adder). In ähnlicher Weise kann die Gittersuche die beste Möglichkeit finden, mit Ausreißern und fehlenden Werten umzugehen, Merkmale auszuwählen und mehr. |