Wie verwende ich XGboost.cv mit der Optimierung von Hyperparametern?

11

Ich möchte die Hyperparameter von XGboost mithilfe der Kreuzvalidierung optimieren. Es ist jedoch nicht klar, wie man das Modell erhält xgb.cv. Zum Beispiel rufe ich objective(params)von an fmin. Dann wird das Modell montiert dtrainund validiert dvalid. Was ist, wenn ich KFold Crossvalidation verwenden möchte, anstatt zu trainieren dtrain?

from hyperopt import fmin, tpe
import xgboost as xgb

params = {
             'n_estimators' : hp.quniform('n_estimators', 100, 1000, 1),
             'eta' : hp.quniform('eta', 0.025, 0.5, 0.025),
             'max_depth' : hp.quniform('max_depth', 1, 13, 1)
             #...
         }
best = fmin(objective, space=params, algo=tpe.suggest)

def objective(params):
    dtrain = xgb.DMatrix(X_train, label=y_train)
    dvalid = xgb.DMatrix(X_valid, label=y_valid)
    watchlist = [(dtrain, 'train'), (dvalid, 'eval')]
    model = xgb.train(params, dtrain, num_boost_round, 
                      evals=watchlist, feval=myFunc)
    # xgb.cv(param, dtrain, num_boost_round, nfold = 5, seed = 0,
    #        feval=myFunc)
Klausos
quelle

Antworten:

19

Auf diese Weise habe ich einen xgboostKlassifikator mit einer 5-fachen Kreuzvalidierung trainiert , um den F1-Score mithilfe der zufälligen Suche nach Hyperparameteroptimierung zu optimieren. Beachten Sie, dass Xund yhier sollten Pandas-Datenrahmen sein.

from scipy import stats
from xgboost import XGBClassifier
from sklearn.model_selection import RandomizedSearchCV, KFold
from sklearn.metrics import f1_score

clf_xgb = XGBClassifier(objective = 'binary:logistic')
param_dist = {'n_estimators': stats.randint(150, 500),
              'learning_rate': stats.uniform(0.01, 0.07),
              'subsample': stats.uniform(0.3, 0.7),
              'max_depth': [3, 4, 5, 6, 7, 8, 9],
              'colsample_bytree': stats.uniform(0.5, 0.45),
              'min_child_weight': [1, 2, 3]
             }
clf = RandomizedSearchCV(clf_xgb, param_distributions = param_dist, n_iter = 25, scoring = 'f1', error_score = 0, verbose = 3, n_jobs = -1)

numFolds = 5
folds = KFold(n_splits = numFolds, shuffle = True)

estimators = []
results = np.zeros(len(X))
score = 0.0
for train_index, test_index in folds.split(X):
    X_train, X_test = X.iloc[train_index,:], X.iloc[test_index,:]
    y_train, y_test = y.iloc[train_index].values.ravel(), y.iloc[test_index].values.ravel()
    clf.fit(X_train, y_train)

    estimators.append(clf.best_estimator_)
    results[test_index] = clf.predict(X_test)
    score += f1_score(y_test, results[test_index])
score /= numFolds

Am Ende erhalten Sie eine Liste der trainierten Klassifizierer in estimators, eine Vorhersage für den gesamten Datensatz in resultsaus nicht zusammenhängenden Vorhersagen und eine Schätzung für den Score in .F1score

darXider
quelle
1
Wie verwaltet dieser Code num_boost_round und Early_stopping_rounds?
Mfaieghi
3

Ich habe nicht genug Ruf, um die Antwort von @ darXider zu kommentieren. Also füge ich eine "Antwort" hinzu, um Kommentare abzugeben.

Warum benötigen Sie, for train_index, test_index in folds:da clfbereits eine Kreuzvalidierung durchgeführt wird, um den besten Satz von Hyperparameterwerten auszuwählen?

In Ihrem Code sieht es so aus, als würden Sie für jede der fünf Falten einen Lebenslauf erstellen (einen "verschachtelten" Lebenslauf), um das beste Modell für diese bestimmte Falte auszuwählen. Am Ende haben Sie also fünf "beste" Schätzer. Höchstwahrscheinlich haben sie nicht dieselben Hyperparameterwerte.

Korrigieren Sie mich, wenn ich falsch liege.

panc
quelle
Ja, standardmäßig verwendet RandomizedSearchCV einen dreifachen Lebenslauf, um die Parameter zu bestimmen. Sie kann bei Bedarf in eine beliebige andere Anzahl von Falten geändert werden.
Satwik Bhattamishra
1
Wie Sie bemerkt haben, handelt es sich hierbei um ein verschachteltes Kreuzvalidierungsschema, und Sie haben Recht, dass die fünf "besten" Modelle nicht dieselben Hyperparameter haben. Am Ende erhalten Sie jedoch 5 äquivalente "beste" Modelle (und Sie können sie beispielsweise in einem Ensemble verwenden), um Ihre Vorhersagen zu treffen. Darüber hinaus liefert dieses Schema Vorhersagen für den gesamten Datensatz (wie ich in meiner Antwort erwähnt habe, indem die ungleichen Vorhersagen jedes Modells kombiniert werden). Darüber hinaus erhalten Sie eine Schätzung für die Streuung in der Punktzahl (im Gegensatz zu nur einem Wert).
DarXider