Python 使用 RandomizedSearchCV 对 XGBClassifier 进行超参数优化
Python Hyperparameter Optimization for XGBClassifier using RandomizedSearchCV
我正在尝试为 XGBClassifier 获取最佳超参数,这将导致获得最具预测性的属性。我正在尝试使用 RandomizedSearchCV 通过 KFold 进行迭代和验证。
由于我 运行 这个过程总共 5 次 (numFolds=5),我希望将最好的结果保存在一个名为 collector 的数据框中(在下面指定)。所以每次迭代,我都希望将最好的结果和分数附加到收集器数据框。
from scipy import stats
from scipy.stats import randint
from sklearn.model_selection import RandomizedSearchCV
from sklearn.metrics import
precision_score,recall_score,accuracy_score,f1_score,roc_auc_score
clf_xgb = xgb.XGBClassifier(objective = 'binary:logistic')
param_dist = {'n_estimators': stats.randint(150, 1000),
'learning_rate': stats.uniform(0.01, 0.6),
'subsample': stats.uniform(0.3, 0.9),
'max_depth': [3, 4, 5, 6, 7, 8, 9],
'colsample_bytree': stats.uniform(0.5, 0.9),
'min_child_weight': [1, 2, 3, 4]
}
clf = RandomizedSearchCV(clf_xgb, param_distributions = param_dist, n_iter = 25, scoring = 'roc_auc', error_score = 0, verbose = 3, n_jobs = -1)
numFolds = 5
folds = cross_validation.KFold(n = len(X), shuffle = True, n_folds = numFolds)
collector = pd.DataFrame()
estimators = []
results = np.zeros(len(X))
score = 0.0
for train_index, test_index in folds:
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
clf.fit(X_train, y_train)
estimators.append(clf.best_estimator_)
estcoll = pd.DataFrame(estimators)
estcoll['score'] = score
pd.concat([collector,estcoll])
print "\n", len(collector), "\n"
score /= numFolds
由于某种原因,没有任何内容被保存到数据框中,请帮忙。
另外,我有大约 350 个属性要循环,其中 3.5K 行在训练中,2K 行在测试中。通过贝叶斯超参数优化过程 运行 宁此可能会改善我的结果吗?或者它只会节省处理时间?
RandomizedSearchCV()
会为您做的比您想象的要多。探索适合的 CV 对象的 cv_results
属性 at the documentation page
这是您的代码,几乎没有变化。我添加的两个更改:
- 我从 25 改为
n_iter=5
。这将执行 5 组参数,这与你的 5 折交叉验证意味着总共 25 次拟合。
- 我在 RandomizedSearchCV 之前定义了您的
kfold
对象,然后在构建 RandomizedSearchCV 时将其引用为 cv
参数
_
clf_xgb = xgb.XGBClassifier(objective = 'binary:logistic')
param_dist = {'n_estimators': stats.randint(150, 1000),
'learning_rate': stats.uniform(0.01, 0.59),
'subsample': stats.uniform(0.3, 0.6),
'max_depth': [3, 4, 5, 6, 7, 8, 9],
'colsample_bytree': stats.uniform(0.5, 0.4),
'min_child_weight': [1, 2, 3, 4]
}
numFolds = 5
kfold_5 = cross_validation.KFold(n = len(X), shuffle = True, n_folds = numFolds)
clf = RandomizedSearchCV(clf_xgb,
param_distributions = param_dist,
cv = kfold_5,
n_iter = 5, # you want 5 here not 25 if I understand you correctly
scoring = 'roc_auc',
error_score = 0,
verbose = 3,
n_jobs = -1)
这里是我的答案与您的代码明显不同的地方。只适合 randomizedsearchcv
对象一次,无需循环。它使用 cv
参数处理 CV 循环。
clf.fit(X_train, y_train)
您所有的交叉验证结果现在都在 clf.cv_results_
中。例如,您可以通过以下方式获得交叉验证(平均 5 次)训练分数:
clf.cv_results_['mean_train_score']
或交叉验证的测试集(保留数据)得分为 clf.cv_results_['mean_test_score']
。您还可以获得其他有用的东西,例如 mean_fit_time
、params
和 clf
,一旦安装,将自动记住您的 best_estimator_
作为属性。
这些与确定模型拟合的最佳超参数集相关。对于来自 n_iter
的单次迭代中使用的 5 次折叠中的每一次,一组超参数是恒定的,因此您不必查看一次迭代中多次折叠之间的不同分数。
我正在尝试为 XGBClassifier 获取最佳超参数,这将导致获得最具预测性的属性。我正在尝试使用 RandomizedSearchCV 通过 KFold 进行迭代和验证。
由于我 运行 这个过程总共 5 次 (numFolds=5),我希望将最好的结果保存在一个名为 collector 的数据框中(在下面指定)。所以每次迭代,我都希望将最好的结果和分数附加到收集器数据框。
from scipy import stats
from scipy.stats import randint
from sklearn.model_selection import RandomizedSearchCV
from sklearn.metrics import
precision_score,recall_score,accuracy_score,f1_score,roc_auc_score
clf_xgb = xgb.XGBClassifier(objective = 'binary:logistic')
param_dist = {'n_estimators': stats.randint(150, 1000),
'learning_rate': stats.uniform(0.01, 0.6),
'subsample': stats.uniform(0.3, 0.9),
'max_depth': [3, 4, 5, 6, 7, 8, 9],
'colsample_bytree': stats.uniform(0.5, 0.9),
'min_child_weight': [1, 2, 3, 4]
}
clf = RandomizedSearchCV(clf_xgb, param_distributions = param_dist, n_iter = 25, scoring = 'roc_auc', error_score = 0, verbose = 3, n_jobs = -1)
numFolds = 5
folds = cross_validation.KFold(n = len(X), shuffle = True, n_folds = numFolds)
collector = pd.DataFrame()
estimators = []
results = np.zeros(len(X))
score = 0.0
for train_index, test_index in folds:
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
clf.fit(X_train, y_train)
estimators.append(clf.best_estimator_)
estcoll = pd.DataFrame(estimators)
estcoll['score'] = score
pd.concat([collector,estcoll])
print "\n", len(collector), "\n"
score /= numFolds
由于某种原因,没有任何内容被保存到数据框中,请帮忙。
另外,我有大约 350 个属性要循环,其中 3.5K 行在训练中,2K 行在测试中。通过贝叶斯超参数优化过程 运行 宁此可能会改善我的结果吗?或者它只会节省处理时间?
RandomizedSearchCV()
会为您做的比您想象的要多。探索适合的 CV 对象的 cv_results
属性 at the documentation page
这是您的代码,几乎没有变化。我添加的两个更改:
- 我从 25 改为
n_iter=5
。这将执行 5 组参数,这与你的 5 折交叉验证意味着总共 25 次拟合。 - 我在 RandomizedSearchCV 之前定义了您的
kfold
对象,然后在构建 RandomizedSearchCV 时将其引用为cv
参数
_
clf_xgb = xgb.XGBClassifier(objective = 'binary:logistic')
param_dist = {'n_estimators': stats.randint(150, 1000),
'learning_rate': stats.uniform(0.01, 0.59),
'subsample': stats.uniform(0.3, 0.6),
'max_depth': [3, 4, 5, 6, 7, 8, 9],
'colsample_bytree': stats.uniform(0.5, 0.4),
'min_child_weight': [1, 2, 3, 4]
}
numFolds = 5
kfold_5 = cross_validation.KFold(n = len(X), shuffle = True, n_folds = numFolds)
clf = RandomizedSearchCV(clf_xgb,
param_distributions = param_dist,
cv = kfold_5,
n_iter = 5, # you want 5 here not 25 if I understand you correctly
scoring = 'roc_auc',
error_score = 0,
verbose = 3,
n_jobs = -1)
这里是我的答案与您的代码明显不同的地方。只适合 randomizedsearchcv
对象一次,无需循环。它使用 cv
参数处理 CV 循环。
clf.fit(X_train, y_train)
您所有的交叉验证结果现在都在 clf.cv_results_
中。例如,您可以通过以下方式获得交叉验证(平均 5 次)训练分数:
clf.cv_results_['mean_train_score']
或交叉验证的测试集(保留数据)得分为 clf.cv_results_['mean_test_score']
。您还可以获得其他有用的东西,例如 mean_fit_time
、params
和 clf
,一旦安装,将自动记住您的 best_estimator_
作为属性。
这些与确定模型拟合的最佳超参数集相关。对于来自 n_iter
的单次迭代中使用的 5 次折叠中的每一次,一组超参数是恒定的,因此您不必查看一次迭代中多次折叠之间的不同分数。