如何使用 XGboost.cv 进行超参数优化?

机器算法验证 交叉验证 Python 助推 超参数 坡度
2022-02-15 15:00:14

我想使用交叉验证优化 XGboost 的超参数。但是,尚不清楚如何从中获取模型xgb.cv例如,我objective(params)fmin. 然后在 上拟dtrain合并验证模型dvalid如果我想使用 KFold 交叉验证而不是训练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)
2个回答

这就是我如何xgboost使用 5 折交叉验证训练分类器,以使用随机搜索进行超参数优化来优化 F1 分数。请注意,X这里y应该是熊猫数据框。

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

最后,您会在 中获得经过训练的分类器列表、根据折叠预测构建estimators的整个数据集的分数的估计resultsF1score

我没有足够的声誉对@darXider 的回答发表评论。所以我添加一个“答案”来发表评论。

for train_index, test_index in folds:既然clf已经在进行交叉验证以选择最佳的超参数值集,为什么还需要?

在您的代码中,您似乎为五个折叠(“嵌套”CV)中的每一个执行 CV 以选择该特定折叠的最佳模型。所以最后,你将有五个“最佳”估计器。很可能,它们没有相同的超参数值。

如果我错了,请纠正我。