3.2. Hyperparameter-Tuning eines Schätzers#
Hyperparameter sind Parameter, die nicht direkt innerhalb von Schätzern gelernt werden. In scikit-learn werden sie als Argumente an den Konstruktor der Schätzerklassen übergeben. Typische Beispiele sind C, kernel und gamma für den Support Vector Classifier, alpha für Lasso usw.
Es ist möglich und empfohlen, den Hyperparameterraum nach der besten Kreuzvalidierungsbewertung zu durchsuchen.
Jeder Parameter, der bei der Konstruktion eines Schätzers übergeben wird, kann auf diese Weise optimiert werden. Um die Namen und aktuellen Werte aller Parameter für einen gegebenen Schätzer zu finden, verwenden Sie
estimator.get_params()
Eine Suche besteht aus
einem Schätzer (Regressor oder Klassifikator wie
sklearn.svm.SVC());einem Parameterraum;
einer Methode zum Suchen oder Abtasten von Kandidaten;
einem Kreuzvalidierungsschema; und
einer Bewertungsfunktion.
In scikit-learn werden zwei allgemeine Ansätze zur Parametersuche bereitgestellt: für gegebene Werte durchsucht GridSearchCV erschöpfend alle Parameterkombinationen, während RandomizedSearchCV eine gegebene Anzahl von Kandidaten aus einem Parameterraum mit einer spezifizierten Verteilung abtasten kann. Beide Werkzeuge haben Gegenstücke mit sukzessiver Halbierung, HalvingGridSearchCV und HalvingRandomSearchCV, die bei der Suche nach einer guten Parameterkombination deutlich schneller sein können.
Nachdem wir diese Werkzeuge beschrieben haben, detaillieren wir bewährte Vorgehensweisen, die für diese Ansätze gelten. Einige Modelle erlauben spezialisierte, effiziente Strategien zur Parametersuche, die in Alternativen zur Brute-Force-Parametersuche beschrieben werden.
Beachten Sie, dass es üblich ist, dass eine kleine Teilmenge dieser Parameter einen großen Einfluss auf die prädiktive oder rechnerische Leistung des Modells haben kann, während andere auf ihren Standardwerten belassen werden können. Es wird empfohlen, die Docstring der Schätzerklasse zu lesen, um ein besseres Verständnis ihres erwarteten Verhaltens zu erhalten, möglicherweise durch Lesen des enthaltenen Literaturverweises.
3.2.1. Erschöpfende Gitter-Suche#
Die von GridSearchCV bereitgestellte Gitter-Suche erzeugt erschöpfend Kandidaten aus einem Gitter von Parameterwerten, das mit dem Parameter param_grid spezifiziert wird. Zum Beispiel spezifiziert die folgende param_grid
param_grid = [
{'C': [1, 10, 100, 1000], 'kernel': ['linear']},
{'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001], 'kernel': ['rbf']},
]
dass zwei Gitter untersucht werden sollen: eines mit einem linearen Kernel und C-Werten in [1, 10, 100, 1000], und das zweite mit einem RBF-Kernel und dem Kreuzprodukt von C-Werten im Bereich [1, 10, 100, 1000] und Gamma-Werten in [0,001, 0,0001].
Die Instanz GridSearchCV implementiert die übliche Schätzer-API: Wenn sie auf einem Datensatz "fit" wird, werden alle möglichen Kombinationen von Parameterwerten ausgewertet und die beste Kombination beibehalten.
Beispiele
Siehe Verschachtelte vs. Nicht-verschachtelte Kreuzvalidierung für ein Beispiel der Gitter-Suche innerhalb einer Kreuzvalidierungsschleife auf dem Iris-Datensatz. Dies ist die beste Vorgehensweise zur Bewertung der Leistung eines Modells mit Gitter-Suche.
Siehe Beispiel-Pipeline für Textmerkmalextraktion und -bewertung für ein Beispiel der Gitter-Suche, die Parameter eines Textdokument-Merkmalsextraktors (N-Gramm-Zählvektorisierer und TF-IDF-Transformator) mit einem Klassifikator (hier ein linearer SVM, trainiert mit SGD mit entweder Elastic-Net oder L2-Strafe) unter Verwendung einer Instanz von
Pipelinekombiniert.
Fortgeschrittene Beispiele#
Siehe Verschachtelte vs. Nicht-verschachtelte Kreuzvalidierung für ein Beispiel der Gitter-Suche innerhalb einer Kreuzvalidierungsschleife auf dem Iris-Datensatz. Dies ist die beste Vorgehensweise zur Bewertung der Leistung eines Modells mit Gitter-Suche.
Siehe Demonstration der Mehrfachmetrikauswertung auf cross_val_score und GridSearchCV für ein Beispiel, wie
GridSearchCVzur gleichzeitigen Auswertung mehrerer Metriken verwendet wird.Siehe Modellkomplexität und kreuzvalidierte Bewertung ausbalancieren für ein Beispiel der Verwendung der
refit=callableSchnittstelle inGridSearchCV. Das Beispiel zeigt, wie diese Schnittstelle eine gewisse Flexibilität bei der Identifizierung des „besten“ Schätzers hinzufügt. Diese Schnittstelle kann auch bei der Mehrfachmetrikauswertung verwendet werden.Siehe Statistische Vergleiche von Modellen mittels Gitter-Suche für ein Beispiel, wie ein statistischer Vergleich der Ausgaben von
GridSearchCVdurchgeführt wird.
3.2.2. Zufällige Hyperparameter-Optimierung#
Während die Verwendung eines Gitters von Parametereinstellungen derzeit die am weitesten verbreitete Methode zur Parameteroptimierung ist, haben andere Suchmethoden günstigere Eigenschaften. RandomizedSearchCV implementiert eine zufällige Suche über Parameter, wobei jede Einstellung aus einer Verteilung über mögliche Parameterwerte abgetastet wird. Dies hat zwei Hauptvorteile gegenüber einer erschöpfenden Suche:
Ein Budget kann unabhängig von der Anzahl der Parameter und möglichen Werte gewählt werden.
Das Hinzufügen von Parametern, die die Leistung nicht beeinflussen, verringert nicht die Effizienz.
Die Angabe, wie Parameter abgetastet werden sollen, erfolgt mit einem Wörterbuch, sehr ähnlich der Angabe von Parametern für GridSearchCV. Zusätzlich wird ein Rechenbudget, d. h. die Anzahl der abgetasteten Kandidaten oder Abtastiterationen, mit dem Parameter n_iter spezifiziert. Für jeden Parameter kann entweder eine Verteilung über mögliche Werte oder eine Liste diskreter Auswahlmöglichkeiten (die gleichmäßig abgetastet werden) angegeben werden.
{'C': scipy.stats.expon(scale=100), 'gamma': scipy.stats.expon(scale=.1),
'kernel': ['rbf'], 'class_weight':['balanced', None]}
Dieses Beispiel verwendet das Modul scipy.stats, das viele nützliche Verteilungen zur Abtastung von Parametern enthält, wie z. B. expon, gamma, uniform, loguniform oder randint.
Prinzipiell kann jede Funktion übergeben werden, die eine rvs (random variate sample) Methode zur Abtastung eines Wertes bereitstellt. Ein Aufruf der rvs Funktion sollte bei aufeinanderfolgenden Aufrufen unabhängige Zufallsstichproben aus möglichen Parameterwerten liefern.
Warnung
Die Verteilungen in scipy.stats vor Version scipy 0.16 erlauben keine Angabe eines Zufallszustands. Stattdessen verwenden sie den globalen Numpy-Zufallszustand, der über np.random.seed gesetzt oder über np.random.set_state konfiguriert werden kann. Ab scikit-learn 0.18 setzt das Modul sklearn.model_selection jedoch den vom Benutzer bereitgestellten Zufallszustand, wenn scipy >= 0.16 ebenfalls verfügbar ist.
Für kontinuierliche Parameter wie C oben ist es wichtig, eine kontinuierliche Verteilung anzugeben, um die Zufälligkeit voll auszunutzen. Auf diese Weise führt eine Erhöhung von n_iter immer zu einer feineren Suche.
Eine kontinuierliche log-uniforme Zufallsvariable ist die kontinuierliche Version eines log-skalierten Parameters. Zum Beispiel kann zur Angabe des Äquivalents von C von oben loguniform(1, 100) anstelle von [1, 10, 100] verwendet werden.
Spiegelbildlich zum obigen Beispiel in der Gitter-Suche können wir eine kontinuierliche Zufallsvariable spezifizieren, die log-gleichmäßig zwischen 1e0 und 1e3 verteilt ist.
from sklearn.utils.fixes import loguniform
{'C': loguniform(1e0, 1e3),
'gamma': loguniform(1e-4, 1e-3),
'kernel': ['rbf'],
'class_weight':['balanced', None]}
Beispiele
Vergleich von zufälliger und Gitter-Suche für die Hyperparameter-Schätzung vergleicht die Verwendung und Effizienz der zufälligen Suche und der Gitter-Suche.
Referenzen
Bergstra, J. und Bengio, Y., Random search for hyper-parameter optimization, The Journal of Machine Learning Research (2012)
3.2.3. Suche nach optimalen Parametern mit sukzessiver Halbierung#
Scikit-learn bietet auch die Schätzer HalvingGridSearchCV und HalvingRandomSearchCV, die verwendet werden können, um einen Parameterraum mittels sukzessiver Halbierung [1] [2] zu durchsuchen. Sukzessive Halbierung (SH) ist wie ein Turnier unter Kandidaten-Parameterkombinationen. SH ist ein iterativer Auswahlprozess, bei dem alle Kandidaten (die Parameterkombinationen) in der ersten Iteration mit geringem Ressourcenaufwand bewertet werden. Nur einige dieser Kandidaten werden für die nächste Iteration ausgewählt, der mehr Ressourcen zugewiesen wird. Für das Parameter-Tuning sind die Ressourcen typischerweise die Anzahl der Trainingsstichproben, es kann aber auch ein beliebiger numerischer Parameter wie n_estimators in einem Random Forest sein.
Hinweis
Die gewählte Ressourcensteigerung sollte groß genug sein, damit eine deutliche Verbesserung der Bewertungen unter Berücksichtigung der statistischen Signifikanz erzielt wird.
Wie in der nachstehenden Abbildung gezeigt, überleben nur einige Kandidaten bis zur letzten Iteration. Dies sind die Kandidaten, die sich in allen Iterationen konstant unter den am besten bewerteten Kandidaten befanden. Jeder Iteration wird eine steigende Menge an Ressourcen pro Kandidat zugewiesen, hier die Anzahl der Stichproben.
Wir beschreiben hier kurz die wichtigsten Parameter, aber jeder Parameter und seine Wechselwirkungen werden im folgenden Dropdown-Bereich detaillierter beschrieben. Der Parameter factor (> 1) steuert die Rate, mit der die Ressourcen wachsen, und die Rate, mit der die Anzahl der Kandidaten sinkt. In jeder Iteration wird die Anzahl der Ressourcen pro Kandidat mit factor multipliziert und die Anzahl der Kandidaten durch denselben Faktor geteilt. Zusammen mit resource und min_resources ist factor der wichtigste Parameter zur Steuerung der Suche in unserer Implementierung, obwohl ein Wert von 3 im Allgemeinen gut funktioniert. factor steuert effektiv die Anzahl der Iterationen in HalvingGridSearchCV und die Anzahl der Kandidaten (standardmäßig) sowie die Iterationen in HalvingRandomSearchCV. aggressive_elimination=True kann auch verwendet werden, wenn die Anzahl der verfügbaren Ressourcen gering ist. Mehr Kontrolle ist durch die Abstimmung des Parameters min_resources möglich.
Diese Schätzer sind noch experimentell: ihre Vorhersagen und ihre API können sich ohne einen Deprecationszyklus ändern. Um sie zu verwenden, müssen Sie explizit enable_halving_search_cv importieren.
>>> from sklearn.experimental import enable_halving_search_cv # noqa
>>> from sklearn.model_selection import HalvingGridSearchCV
>>> from sklearn.model_selection import HalvingRandomSearchCV
Beispiele
Die folgenden Abschnitte befassen sich mit technischen Aspekten der sukzessiven Halbierung.
Auswahl von min_resources und der Anzahl der Kandidaten#
Neben factor sind die beiden wichtigsten Parameter, die das Verhalten einer sukzessiven Halbierungs-Suche beeinflussen, der Parameter min_resources und die Anzahl der Kandidaten (oder Parameterkombinationen), die ausgewertet werden. min_resources ist die Menge an Ressourcen, die in der ersten Iteration für jeden Kandidaten zugewiesen wird. Die Anzahl der Kandidaten wird direkt in HalvingRandomSearchCV festgelegt und aus dem Parameter param_grid von HalvingGridSearchCV ermittelt.
Betrachten wir einen Fall, in dem die Ressource die Anzahl der Stichproben ist und wir 1000 Stichproben haben. Theoretisch können wir mit min_resources=10 und factor=2 maximal 7 Iterationen mit den folgenden Stichprobenmengen durchführen: [10, 20, 40, 80, 160, 320, 640].
Abhängig von der Anzahl der Kandidaten können wir jedoch weniger als 7 Iterationen durchführen: Wenn wir mit einer kleinen Anzahl von Kandidaten beginnen, kann die letzte Iteration weniger als 640 Stichproben verwenden, was bedeutet, dass nicht alle verfügbaren Ressourcen (Stichproben) genutzt werden. Wenn wir beispielsweise mit 5 Kandidaten beginnen, benötigen wir nur 2 Iterationen: 5 Kandidaten für die erste Iteration, dann 5 // 2 = 2 Kandidaten in der zweiten Iteration, danach wissen wir, welcher Kandidat am besten abschneidet (wir brauchen also keinen dritten). Wir würden höchstens 20 Stichproben verwenden, was eine Verschwendung ist, da wir 1000 Stichproben zur Verfügung haben. Wenn wir hingegen mit einer hohen Anzahl von Kandidaten beginnen, könnten wir am Ende viele Kandidaten in der letzten Iteration haben, was nicht immer ideal ist: es bedeutet, dass viele Kandidaten mit den vollen Ressourcen laufen, was die Prozedur im Grunde auf eine Standard-Suche reduziert.
Im Fall von HalvingRandomSearchCV wird die Anzahl der Kandidaten standardmäßig so eingestellt, dass die letzte Iteration so viele der verfügbaren Ressourcen wie möglich nutzt. Für HalvingGridSearchCV wird die Anzahl der Kandidaten durch den Parameter param_grid bestimmt. Eine Änderung des Wertes von min_resources beeinflusst die Anzahl der möglichen Iterationen und hat somit auch Auswirkungen auf die ideale Anzahl der Kandidaten.
Eine weitere Überlegung bei der Wahl von min_resources ist, ob es einfach ist, gute von schlechten Kandidaten mit geringem Ressourcenaufwand zu unterscheiden. Wenn Sie beispielsweise viele Stichproben benötigen, um zwischen guten und schlechten Parametern zu unterscheiden, wird eine hohe min_resources empfohlen. Wenn die Unterscheidung hingegen auch mit geringem Stichprobenaufwand klar ist, dann ist eine geringe min_resources möglicherweise vorzuziehen, da sie die Berechnung beschleunigen würde.
Beachten Sie im obigen Beispiel, dass die letzte Iteration nicht die maximalen verfügbaren Ressourcen nutzt: Es sind 1000 Stichproben verfügbar, aber höchstens 640 werden verwendet. Standardmäßig versuchen sowohl HalvingRandomSearchCV als auch HalvingGridSearchCV, in der letzten Iteration so viele Ressourcen wie möglich zu nutzen, wobei die Einschränkung besteht, dass diese Ressourcenmenge ein Vielfaches von sowohl min_resources als auch factor sein muss (diese Einschränkung wird im nächsten Abschnitt klar). HalvingRandomSearchCV erreicht dies durch Abtasten der richtigen Anzahl von Kandidaten, während HalvingGridSearchCV dies durch korrektes Setzen von min_resources erreicht.
Menge der Ressourcen und Anzahl der Kandidaten in jeder Iteration#
In jeder Iteration i wird jedem Kandidaten eine bestimmte Menge an Ressourcen zugewiesen, die wir als n_resources_i bezeichnen. Diese Menge wird durch die Parameter factor und min_resources wie folgt gesteuert (wobei factor größer als 1 ist)
n_resources_i = factor**i * min_resources,
oder äquivalent
n_resources_{i+1} = n_resources_i * factor
wobei min_resources == n_resources_0 die in der ersten Iteration verwendete Ressourcenmenge ist. factor definiert auch die Proportionen der Kandidaten, die für die nächste Iteration ausgewählt werden.
n_candidates_i = n_candidates // (factor ** i)
oder äquivalent
n_candidates_0 = n_candidates
n_candidates_{i+1} = n_candidates_i // factor
In der ersten Iteration verwenden wir also min_resources Ressourcen n_candidates Mal. In der zweiten Iteration verwenden wir min_resources * factor Ressourcen n_candidates // factor Mal. Die dritte Iteration multipliziert wieder die Ressourcen pro Kandidat und dividiert die Anzahl der Kandidaten. Dieser Prozess stoppt, wenn die maximale Menge an Ressourcen pro Kandidat erreicht ist, oder wenn wir den besten Kandidaten identifiziert haben. Der beste Kandidat wird in der Iteration identifiziert, die factor oder weniger Kandidaten evaluiert (siehe unten für eine Erklärung).
Hier ist ein Beispiel mit min_resources=3 und factor=2, beginnend mit 70 Kandidaten
|
|
|---|---|
3 (=min_resources) |
70 (=n_candidates) |
3 * 2 = 6 |
70 // 2 = 35 |
6 * 2 = 12 |
35 // 2 = 17 |
12 * 2 = 24 |
17 // 2 = 8 |
24 * 2 = 48 |
8 // 2 = 4 |
48 * 2 = 96 |
4 // 2 = 2 |
Wir können feststellen, dass
der Prozess in der ersten Iteration stoppt, die
factor=2Kandidaten evaluiert: Der beste Kandidat ist der beste aus diesen 2 Kandidaten. Es ist nicht notwendig, eine zusätzliche Iteration durchzuführen, da diese nur einen Kandidaten evaluieren würde (nämlich den besten, den wir bereits identifiziert haben). Aus diesem Grund möchten wir im Allgemeinen, dass die letzte Iteration höchstensfactorKandidaten evaluiert. Wenn die letzte Iteration mehr alsfactorKandidaten evaluiert, dann reduziert sich diese letzte Iteration auf eine reguläre Suche (wie inRandomizedSearchCVoderGridSearchCV).jede
n_resources_iein Vielfaches von sowohlfactorals auchmin_resourcesist (was durch seine Definition oben bestätigt wird).
Die in jeder Iteration verwendete Ressourcenmenge finden Sie im Attribut n_resources_.
Auswahl einer Ressource#
Standardmäßig wird die Ressource in Bezug auf die Anzahl der Stichproben definiert. Das heißt, jede Iteration wird eine steigende Anzahl von Stichproben zum Trainieren verwenden. Sie können jedoch manuell einen Parameter als Ressource angeben, indem Sie den Parameter resource verwenden. Hier ist ein Beispiel, bei dem die Ressource in Bezug auf die Anzahl der Schätzer eines Random Forest definiert ist.
>>> from sklearn.datasets import make_classification
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.experimental import enable_halving_search_cv # noqa
>>> from sklearn.model_selection import HalvingGridSearchCV
>>> import pandas as pd
>>> param_grid = {'max_depth': [3, 5, 10],
... 'min_samples_split': [2, 5, 10]}
>>> base_estimator = RandomForestClassifier(random_state=0)
>>> X, y = make_classification(n_samples=1000, random_state=0)
>>> sh = HalvingGridSearchCV(base_estimator, param_grid, cv=5,
... factor=2, resource='n_estimators',
... max_resources=30).fit(X, y)
>>> sh.best_estimator_
RandomForestClassifier(max_depth=5, n_estimators=24, random_state=0)
Beachten Sie, dass es nicht möglich ist, auf einen Parameter zu budgetieren, der Teil des Parametergitters ist.
Erschöpfung der verfügbaren Ressourcen#
Wie oben erwähnt, hängt die in jeder Iteration verwendete Ressourcenmenge vom Parameter min_resources ab. Wenn Sie viele Ressourcen zur Verfügung haben, aber mit einer geringen Anzahl von Ressourcen beginnen, könnten einige davon verschwendet werden (d. h. nicht genutzt werden).
>>> from sklearn.datasets import make_classification
>>> from sklearn.svm import SVC
>>> from sklearn.experimental import enable_halving_search_cv # noqa
>>> from sklearn.model_selection import HalvingGridSearchCV
>>> import pandas as pd
>>> param_grid= {'kernel': ('linear', 'rbf'),
... 'C': [1, 10, 100]}
>>> base_estimator = SVC(gamma='scale')
>>> X, y = make_classification(n_samples=1000)
>>> sh = HalvingGridSearchCV(base_estimator, param_grid, cv=5,
... factor=2, min_resources=20).fit(X, y)
>>> sh.n_resources_
[20, 40, 80]
Der Suchprozess wird höchstens 80 Ressourcen verwenden, während unser maximaler verfügbarer Ressourcenbetrag n_samples=1000 beträgt. Hier haben wir min_resources = r_0 = 20.
Für HalvingGridSearchCV ist der Parameter min_resources standardmäßig auf 'exhaust' gesetzt. Das bedeutet, dass min_resources automatisch so eingestellt wird, dass die letzte Iteration so viele Ressourcen wie möglich nutzen kann, innerhalb des Limits von max_resources.
>>> sh = HalvingGridSearchCV(base_estimator, param_grid, cv=5,
... factor=2, min_resources='exhaust').fit(X, y)
>>> sh.n_resources_
[250, 500, 1000]
min_resources wurde hier automatisch auf 250 gesetzt, was dazu führt, dass die letzte Iteration alle Ressourcen nutzt. Der genaue Wert hängt von der Anzahl der Kandidatenparameter, von max_resources und von factor ab.
Für HalvingRandomSearchCV kann die Erschöpfung der Ressourcen auf 2 Arten erfolgen:
durch Setzen von
min_resources='exhaust', genau wie beiHalvingGridSearchCV;durch Setzen von
n_candidates='exhaust'.
Beide Optionen sind gegenseitig ausschließend: Die Verwendung von min_resources='exhaust' erfordert die Kenntnis der Anzahl der Kandidaten, und symmetrisch erfordert n_candidates='exhaust' die Kenntnis von min_resources.
Im Allgemeinen führt die Erschöpfung der Gesamtzahl der Ressourcen zu einem besseren endgültigen Kandidatenparameter und ist geringfügig zeitaufwendiger.
3.2.3.1. Aggressive Eliminierung von Kandidaten#
Mit dem Parameter aggressive_elimination können Sie den Suchprozess dazu zwingen, in der letzten Iteration mit weniger als factor Kandidaten zu enden.
Codebeispiel für aggressive Eliminierung#
Idealerweise möchten wir, dass die letzte Iteration factor Kandidaten evaluiert. Dann müssen wir nur noch den besten auswählen. Wenn die Anzahl der verfügbaren Ressourcen im Verhältnis zur Anzahl der Kandidaten gering ist, muss die letzte Iteration möglicherweise mehr als factor Kandidaten evaluieren.
>>> from sklearn.datasets import make_classification
>>> from sklearn.svm import SVC
>>> from sklearn.experimental import enable_halving_search_cv # noqa
>>> from sklearn.model_selection import HalvingGridSearchCV
>>> import pandas as pd
>>> param_grid = {'kernel': ('linear', 'rbf'),
... 'C': [1, 10, 100]}
>>> base_estimator = SVC(gamma='scale')
>>> X, y = make_classification(n_samples=1000)
>>> sh = HalvingGridSearchCV(base_estimator, param_grid, cv=5,
... factor=2, max_resources=40,
... aggressive_elimination=False).fit(X, y)
>>> sh.n_resources_
[20, 40]
>>> sh.n_candidates_
[6, 3]
Da wir nicht mehr als max_resources=40 Ressourcen verwenden können, muss der Prozess in der zweiten Iteration stoppen, die mehr als factor=2 Kandidaten evaluiert.
Wenn aggressive_elimination verwendet wird, eliminiert der Prozess so viele Kandidaten wie nötig unter Verwendung von min_resources Ressourcen.
>>> sh = HalvingGridSearchCV(base_estimator, param_grid, cv=5,
... factor=2,
... max_resources=40,
... aggressive_elimination=True,
... ).fit(X, y)
>>> sh.n_resources_
[20, 20, 40]
>>> sh.n_candidates_
[6, 3, 2]
Beachten Sie, dass wir in der letzten Iteration mit 2 Kandidaten enden, da wir während der ersten Iterationen genug Kandidaten eliminiert haben, unter Verwendung von n_resources = min_resources = 20.
3.2.3.2. Analyse der Ergebnisse mit dem Attribut cv_results_#
Das Attribut cv_results_ enthält nützliche Informationen zur Analyse der Ergebnisse einer Suche. Es kann mit df = pd.DataFrame(est.cv_results_) in einen Pandas-DataFrame umgewandelt werden. Das Attribut cv_results_ von HalvingGridSearchCV und HalvingRandomSearchCV ähnelt dem von GridSearchCV und RandomizedSearchCV, mit zusätzlichen Informationen, die sich auf den Prozess der sukzessiven Halbierung beziehen.
Beispiel für einen (abgeschnittenen) Ausgabe-DataFrame:#
iter |
n_resources |
mean_test_score |
params |
|
|---|---|---|---|---|
0 |
0 |
125 |
0.983667 |
{‘criterion’: ‘log_loss’, ‘max_depth’: None, ‘max_features’: 9, ‘min_samples_split’: 5} |
1 |
0 |
125 |
0.983667 |
{'Kriterium': 'gini', 'max_tiefe': None, 'max_merkmale': 8, 'min_stichproben_aufteilung': 7} |
2 |
0 |
125 |
0.983667 |
{'Kriterium': 'gini', 'max_tiefe': None, 'max_merkmale': 10, 'min_stichproben_aufteilung': 10} |
3 |
0 |
125 |
0.983667 |
{'Kriterium': 'log_loss', 'max_tiefe': None, 'max_merkmale': 6, 'min_stichproben_aufteilung': 6} |
… |
… |
… |
… |
… |
15 |
2 |
500 |
0.951958 |
{'Kriterium': 'log_loss', 'max_tiefe': None, 'max_merkmale': 9, 'min_stichproben_aufteilung': 10} |
16 |
2 |
500 |
0.947958 |
{'Kriterium': 'gini', 'max_tiefe': None, 'max_merkmale': 10, 'min_stichproben_aufteilung': 10} |
17 |
2 |
500 |
0.951958 |
{'Kriterium': 'gini', 'max_tiefe': None, 'max_merkmale': 10, 'min_stichproben_aufteilung': 4} |
18 |
3 |
1000 |
0.961009 |
{'Kriterium': 'log_loss', 'max_tiefe': None, 'max_merkmale': 9, 'min_stichproben_aufteilung': 10} |
19 |
3 |
1000 |
0.955989 |
{'Kriterium': 'gini', 'max_tiefe': None, 'max_merkmale': 10, 'min_stichproben_aufteilung': 4} |
Jede Zeile entspricht einer gegebenen Parameterkombination (einem Kandidaten) und einer gegebenen Iteration. Die Iteration wird durch die Spalte iter angegeben. Die Spalte n_resources gibt an, wie viele Ressourcen verwendet wurden.
In dem obigen Beispiel ist die beste Parameterkombination {'criterion': 'log_loss', 'max_depth': None, 'max_features': 9, 'min_samples_split': 10}, da sie die letzte Iteration (3) mit dem höchsten Score: 0,96 erreicht hat.
Referenzen
3.2.4. Tipps für die Parametersuche#
3.2.4.1. Angabe einer Zielfunktion#
Standardmäßig verwendet die Parametersuche die score-Funktion des Schätzers zur Bewertung einer Parametereinstellung. Dies sind sklearn.metrics.accuracy_score für Klassifikation und sklearn.metrics.r2_score für Regression. Für einige Anwendungen sind andere Bewertungsfunktionen besser geeignet (z. B. bei unausgeglichener Klassifikation ist der Genauigkeitswert oft informativ), siehe Welche Bewertungsfunktion sollte ich verwenden? für einige Hinweise. Eine alternative Bewertungsfunktion kann über den Parameter scoring der meisten Parameter-Suchwerkzeuge angegeben werden, siehe Der Parameter scoring: Regeln für die Modellbewertung definieren für weitere Details.
3.2.4.2. Angabe mehrerer Metriken für die Bewertung#
GridSearchCV und RandomizedSearchCV erlauben die Angabe mehrerer Metriken für den Parameter scoring.
Mehrwertige Bewertung kann entweder als Liste von Zeichenketten mit vordefinierten Score-Namen oder als Wörterbuch, das den Scorer-Namen auf die Scorer-Funktion und/oder die vordefinierten Scorer-Namen abbildet, angegeben werden. Siehe Verwendung von mehrwertiger Bewertung für weitere Details.
Bei Angabe mehrerer Metriken muss der Parameter refit auf die Metrik (Zeichenkette) gesetzt werden, für die die best_params_ gefunden und zum Aufbau des best_estimator_ auf dem gesamten Datensatz verwendet werden. Wenn die Suche nicht neu angepasst werden soll, setzen Sie refit=False. Wenn refit auf dem Standardwert None belassen wird, führt dies bei Verwendung mehrerer Metriken zu einem Fehler.
Siehe Demonstration der mehrwertigen Bewertung auf cross_val_score und GridSearchCV für ein Anwendungsbeispiel.
HalvingRandomSearchCV und HalvingGridSearchCV unterstützen keine mehrwertige Bewertung.
3.2.4.3. Zusammengesetzte Schätzer und Parameterbereiche#
GridSearchCV und RandomizedSearchCV ermöglichen die Suche nach Parametern von zusammengesetzten oder verschachtelten Schätzern wie Pipeline, ColumnTransformer, VotingClassifier oder CalibratedClassifierCV unter Verwendung einer dedizierten <estimator>__<parameter>-Syntax
>>> from sklearn.model_selection import GridSearchCV
>>> from sklearn.calibration import CalibratedClassifierCV
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.datasets import make_moons
>>> X, y = make_moons()
>>> calibrated_forest = CalibratedClassifierCV(
... estimator=RandomForestClassifier(n_estimators=10))
>>> param_grid = {
... 'estimator__max_depth': [2, 4, 6, 8]}
>>> search = GridSearchCV(calibrated_forest, param_grid, cv=5)
>>> search.fit(X, y)
GridSearchCV(cv=5,
estimator=CalibratedClassifierCV(estimator=RandomForestClassifier(n_estimators=10)),
param_grid={'estimator__max_depth': [2, 4, 6, 8]})
Hier ist <estimator> der Parametername des verschachtelten Schätzers, in diesem Fall estimator. Wenn der Meta-Schätzer als eine Sammlung von Schätzern wie in pipeline.Pipeline aufgebaut ist, dann bezieht sich <estimator> auf den Namen des Schätzers, siehe Zugriff auf verschachtelte Parameter. In der Praxis kann es mehrere Ebenen der Verschachtelung geben.
>>> from sklearn.pipeline import Pipeline
>>> from sklearn.feature_selection import SelectKBest
>>> pipe = Pipeline([
... ('select', SelectKBest()),
... ('model', calibrated_forest)])
>>> param_grid = {
... 'select__k': [1, 2],
... 'model__estimator__max_depth': [2, 4, 6, 8]}
>>> search = GridSearchCV(pipe, param_grid, cv=5).fit(X, y)
Bitte beachten Sie Pipeline: Schätzer verketten für die Durchführung von Parametersuchen über Pipelines.
3.2.4.4. Modellauswahl: Entwicklung und Bewertung#
Die Modellauswahl durch Bewertung verschiedener Parametereinstellungen kann als eine Methode angesehen werden, um die gelabelten Daten zu verwenden, um die Parameter des Rasters zu "trainieren".
Bei der Bewertung des resultierenden Modells ist es wichtig, dies auf zurückgehaltenen Stichproben zu tun, die während des Raster-Suchprozesses nicht gesehen wurden: Es wird empfohlen, die Daten in einen Entwicklungsdatensatz (der an die GridSearchCV-Instanz übergeben wird) und einen Bewertungsdatensatz zur Berechnung von Leistungsmetriken aufzuteilen.
Dies kann durch die Verwendung der Hilfsfunktion train_test_split erfolgen.
3.2.4.5. Parallelisierung#
Die Parameter-Suchwerkzeuge werten jede Parameterkombination auf jeder Datenfalte unabhängig aus. Berechnungen können parallel durch Verwendung des Schlüsselworts n_jobs=-1 ausgeführt werden. Siehe die Funktionssignatur für weitere Details und auch den Glossareintrag für n_jobs.
3.2.4.6. Robustheit gegenüber Fehlern#
Einige Parametereinstellungen können dazu führen, dass die Anpassung an eine oder mehrere Datenfalten fehlschlägt. Standardmäßig ist der Score für diese Einstellungen np.nan. Dies kann gesteuert werden, indem error_score="raise" gesetzt wird, um eine Ausnahme auszulösen, wenn eine Anpassung fehlschlägt, oder z. B. error_score=0, um einen anderen Wert für den Score von fehlgeschlagenen Parameterkombinationen festzulegen.
3.2.5. Alternativen zur Brute-Force-Parametersuche#
3.2.5.1. Modellspezifische Kreuzvalidierung#
Einige Modelle können Daten für einen Bereich von Werten eines Parameters fast so effizient anpassen wie die Anpassung des Schätzers für einen einzelnen Parameterwert. Diese Funktion kann genutzt werden, um eine effizientere Kreuzvalidierung für die Modellauswahl dieses Parameters durchzuführen.
Der häufigste Parameter, der für diese Strategie geeignet ist, ist der Parameter, der die Stärke des Regularisierers kodiert. In diesem Fall sagen wir, dass wir den Regularisierungspfad des Schätzers berechnen.
Hier ist die Liste solcher Modelle
|
Elastic Net Modell mit iterativem Anpassen entlang eines Regularisierungspfades. |
|
Kreuzvalidiertes Least Angle Regression Modell. |
|
Lasso-Linearmodell mit iterativem Anpassen entlang eines Regularisierungspfades. |
|
Kreuzvalidiertes Lasso unter Verwendung des LARS-Algorithmus. |
|
Logistische Regression CV (auch bekannt als Logit, MaxEnt) Klassifikator. |
|
Multi-Task L1/L2 ElasticNet mit integrierter Kreuzvalidierung. |
|
Multi-Task Lasso Modell, trainiert mit L1/L2 Mixed-Norm als Regularisator. |
Kreuzvalidiertes Orthogonal Matching Pursuit Modell (OMP). |
|
|
Ridge-Regression mit integrierter Kreuzvalidierung. |
|
Ridge-Klassifikator mit integrierter Kreuzvalidierung. |
3.2.5.2. Informationskriterium#
Einige Modelle können eine informations-theoretische geschlossene Formel für die optimale Schätzung des Regularisierungsparameters bieten, indem sie einen einzelnen Regularisierungspfad berechnen (anstelle mehrerer bei Verwendung von Kreuzvalidierung).
Hier ist die Liste der Modelle, die das Akaike-Informationskriterium (AIC) oder das Bayes'sche Informationskriterium (BIC) für die automatisierte Modellauswahl nutzen.
|
Lasso-Modell, angepasst mit Lars, unter Verwendung von BIC oder AIC zur Modellauswahl. |
3.2.5.3. Out-of-Bag-Schätzungen#
Bei der Verwendung von Ensemble-Methoden, die auf Bagging basieren, d. h. Erzeugung neuer Trainingsdatensätze durch Stichprobenentnahme mit Zurücklegen, bleibt ein Teil des Trainingsdatensatzes ungenutzt. Für jeden Klassifikator im Ensemble wird ein anderer Teil des Trainingsdatensatzes weggelassen.
Dieser weggelassene Teil kann verwendet werden, um den Generalisierungsfehler abzuschätzen, ohne auf einen separaten Validierungsdatensatz angewiesen zu sein. Diese Schätzung ist "kostenlos", da keine zusätzlichen Daten benötigt werden und für die Modellauswahl verwendet werden kann.
Dies ist derzeit in den folgenden Klassen implementiert
Ein Random-Forest-Klassifikator. |
|
Ein Random-Forest-Regressor. |
|
Ein Extra-Trees-Klassifikator. |
|
|
Ein Extra-Trees-Regressor. |
|
Gradient Boosting für Klassifikation. |
|
Gradient Boosting für Regression. |