Hyperparameter sind abhängig vom jeweiligen Modell festgelegte Einstellungen, welche die Konfiguration des Modells verändern. Bspw. die Anzahl der Bäume in einem Random Forest. Es gibt verschiedene Verfahren um Hyperparameter in einem Modell zu optimieren.
Grid Search
Die einfachste Methode zur Hyperparameter Optimierung ist Grid Search. Dabei wird einfach eine Kombination an Parametern vorgegeben die dann durchprobiert und evaluiert werden. Dadurch ist Grid Search zwar sehr einfach zu implementieren, aber auch sehr rechenaufwendig und ineffizient.
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
# Datensatz laden
X, y = load_iris(return_X_y=True)
# Modell und Hyperparameter-Raster definieren
model = RandomForestClassifier()
param_grid = {
'n_estimators': [10, 50, 100],
'max_depth': [None, 10, 20],
'min_samples_split': [2, 5, 10]
}
# Grid Search
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5)
grid_search.fit(X, y)
print("Beste Parameter:", grid_search.best_params_)Random Search
Ähnlich wie bei Grid Search werden hier verschiedene Parameter einfach druchprobiert. Dabei wird in diesem Fall aber nicht jede Variante ausprobiert, sondern eine zufällige Stichprobe aus unterschiedlichen Kombinationen der vordefinierten Hyperparametern gezogen. Dadurch ist Random Search weniger rechenintensiv als Grid Search, aber immer noch keine effiziente Vorgehensweise
from sklearn.model_selection import RandomizedSearchCV
# Random Search
random_search = RandomizedSearchCV(
estimator=model,
param_distributions=param_grid,
n_iter=10, # Anzahl der zufälligen Kombinationen
cv=5
)
random_search.fit(X, y)
print("Beste Parameter:", random_search.best_params_)Bayessche Optimierung
Entgegen der vorherigen Ansätze probiert Bayessische Optimierung nicht nur zufällig verschiedene Kombinationen von Hyperparametern durch, sondern versucht tatsächlich Schritt für Schritt zu einer optimalen Kombination zu kommen.
Das Verfahren basiert auf probabilistischen Modellen wie Gaussian Processes und modelliert die Beziehung zwischen den Hyperparamtern und der Performance des Modells. Dabei wird eine sogenannte „Surrogate Funktion“ verwendet, welche die Leistung verschiedener Parameterkombinationen basierend auf den bereits getesteten Werten schätzt.
Im Detail:
- Initialisierung: Eine zufällige Kombination von Hyperparamtern testen
- Surrogate-Modell: Ein Modell rechnen um den Effekt der der Hyperparamter auf die Modell-Performance zu schätzen
- Akquisitionsfunktion: Nächste Kombination auswählen (bspw. durch „Expected Improvement“ oder „Upper Confidence Bound“
- Iterative Verbesserung: Neue Kombination testen und das Surrogate-Modell aktualisieren
Durch dieses Verfahren werden bei jedem Schritt die Ergebnisse aus den vorherigen Tests berücksichtigt um einen effizienten Lernprozess zu ermöglichen. Die Anzahl an notwendigen Tests wird dadurch erheblich reduziert. Allerdings ist die Implementierung deutlich komplexer.
Das hier gezeigte Beispiel nutzt skopt (= scikit-optimize). Dieses kann mit diesem Befehl installiert werden:
pip install scikit-optimizeEin einfaches Beispiel:
from skopt import BayesSearchCV
# Bayessche Optimierung
bayes_search = BayesSearchCV(
estimator=model,
search_spaces=param_grid,
n_iter=10, # Anzahl der Iterationen
cv=5
)
bayes_search.fit(X, y)
print("Beste Parameter:", bayes_search.best_params_)Ray Tune
Ray Tune ist ein leistungsstarkes Framework, das eine Vielzahl von Optimierungsstrategien für Hyperparameter unterstützt. Unter anderem unterstützt es auch fortgeschrittene Methoden wie HyperBand, ASHA (Asynchronous Successive Halving Algorithm) und (PBT) Population-Based Training. Es kann zudem auch auf verteilten System ausgeführt werden um die Laufzeit zu verkürzen.
Die Installation erfolgt mit PIP:
pip install "ray[tune]" "ray[default]"
Ein einfaches Beispiel:
from ray import tune
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# Datensatz laden
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
def train_model(config):
model = RandomForestClassifier(
n_estimators=config['n_estimators'],
max_depth=config['max_depth']
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
tune.report(accuracy=accuracy_score(y_test, y_pred))
# Ray Tune Konfiguration
search_space = {
'n_estimators': tune.grid_search([10, 50, 100]),
'max_depth': tune.choice([None, 10, 20])
}
analysis = tune.run(train_model, config=search_space)
print("Beste Konfiguration:", analysis.best_config)
print("Beste Ergebnisse:", analysis.best_result)