GridSearchCV 没有为 xgboost 选择最佳超参数
GridSearchCV not choosing the best hyperparameters for xgboost
我目前正在使用 xgboost 开发回归模型。由于 xgboost 有多个超参数,我添加了 GridSearchCV()
的交叉验证逻辑。作为试验,我设置了 max_depth: [2,3]
。我的 python 代码如下。
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import make_scorer
from sklearn.metrics import mean_squared_error
xgb_reg = xgb.XGBRegressor()
# Obtain the best hyper parameter
scorer=make_scorer(mean_squared_error, False)
params = {'max_depth': [2,3],
'eta': [0.1],
'colsample_bytree': [1.0],
'colsample_bylevel': [0.3],
'subsample': [0.9],
'gamma': [0],
'lambda': [1],
'alpha':[0],
'min_child_weight':[1]
}
grid_xgb_reg=GridSearchCV(xgb_reg,
param_grid=params,
scoring=scorer,
cv=5,
n_jobs=-1)
grid_xgb_reg.fit(X_train, y_train)
y_pred = grid_xgb_reg.predict(X_test)
y_train_pred = grid_xgb_reg.predict(X_train)
## Evaluate model
from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score
print('RMSE train: %.3f, test: %.3f' %(np.sqrt(mean_squared_error(y_train, y_train_pred)),np.sqrt(mean_squared_error(y_test, y_pred))))
print('R^2 train: %.3f, test: %.3f' %(r2_score(y_train, y_train_pred),r2_score(y_test, y_pred)))
问题是 GridSearchCV
似乎没有选择最佳超参数。在我的例子中,当我将max_depth
设置为[2,3]
时,结果如下。在以下情况下,GridSearchCV
选择 max_depth:2
作为最佳超参数。
# The result when max_depth is 2
RMSE train: 11.861, test: 15.113
R^2 train: 0.817, test: 0.601
但是,如果我将 max_depth
更新为 [3]
(通过去掉 2
),测试分数比以前的值更好,如下所示。
# The result when max_depth is 3
RMSE train: 9.951, test: 14.752
R^2 train: 0.871, test: 0.620
问题
我的理解是,即使我将 max_depth
设置为 [2,3]
,GridSearchCV
方法也应该选择 max_depth:3
作为自 max_depth:3
以来的最佳超参数return 在 RSME 或 R^2 方面的得分是否比 max_depth:2
更好。谁能告诉我为什么当我将 max_depth
设置为 [2,3]
时我的代码无法选择最佳超参数?
如果您 运行 使用 max_depth:2
进行第二次实验,那么即使 运行 使用 [=12],结果也无法与使用 max_depth:[2,3]
的第一次实验相比较=],因为你的代码中有一些你没有明确控制的随机源,即你的代码不是 可重现的。
随机性的第一个来源是 CV 折叠;为了确保实验将 运行 在相同的数据分割上,您应该按如下方式定义您的 GridSearchCV:
from sklearn.model_selection import KFold
seed_cv = 123 # any random value here
kf = KFold(n_splits=5, random_state=seed_cv)
grid_xgb_reg=GridSearchCV(xgb_reg,
param_grid=params,
scoring=scorer,
cv=kf, # <- change here
n_jobs=-1)
第二个随机性来源是 XGBRegressor 本身,它还包括一个 random_state
参数(参见 docs);你应该把它改成:
seed_xgb = 456 # any random value here (can even be the same with seed_cv)
xgb_reg = xgb.XGBRegressor(random_state=seed_xgb)
但即使有了这些安排,虽然您的数据拆分现在将是相同的,但在一般情况下构建的回归模型不一定如此;在这里,如果你保持这样的实验,即首先使用 max_depth:[2,3]
然后使用 max_depth:2
,结果确实是相同的;但是如果你把它改成,比如说,先用 max_depth:[2,3]
然后用 max_depth:3
,他们会 而不是 ,因为在第一个实验中, 运行 with max_depth:3
将以随机数生成器的不同状态开始(即 运行 with max_depth:2
完成后的状态)。
在这种情况下,您可以做出不同的 运行 的程度是有限的;对于一个非常细微的差异的例子,它仍然破坏了两个实验之间的精确再现性,请参阅我在
中的回答
我目前正在使用 xgboost 开发回归模型。由于 xgboost 有多个超参数,我添加了 GridSearchCV()
的交叉验证逻辑。作为试验,我设置了 max_depth: [2,3]
。我的 python 代码如下。
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import make_scorer
from sklearn.metrics import mean_squared_error
xgb_reg = xgb.XGBRegressor()
# Obtain the best hyper parameter
scorer=make_scorer(mean_squared_error, False)
params = {'max_depth': [2,3],
'eta': [0.1],
'colsample_bytree': [1.0],
'colsample_bylevel': [0.3],
'subsample': [0.9],
'gamma': [0],
'lambda': [1],
'alpha':[0],
'min_child_weight':[1]
}
grid_xgb_reg=GridSearchCV(xgb_reg,
param_grid=params,
scoring=scorer,
cv=5,
n_jobs=-1)
grid_xgb_reg.fit(X_train, y_train)
y_pred = grid_xgb_reg.predict(X_test)
y_train_pred = grid_xgb_reg.predict(X_train)
## Evaluate model
from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score
print('RMSE train: %.3f, test: %.3f' %(np.sqrt(mean_squared_error(y_train, y_train_pred)),np.sqrt(mean_squared_error(y_test, y_pred))))
print('R^2 train: %.3f, test: %.3f' %(r2_score(y_train, y_train_pred),r2_score(y_test, y_pred)))
问题是 GridSearchCV
似乎没有选择最佳超参数。在我的例子中,当我将max_depth
设置为[2,3]
时,结果如下。在以下情况下,GridSearchCV
选择 max_depth:2
作为最佳超参数。
# The result when max_depth is 2
RMSE train: 11.861, test: 15.113
R^2 train: 0.817, test: 0.601
但是,如果我将 max_depth
更新为 [3]
(通过去掉 2
),测试分数比以前的值更好,如下所示。
# The result when max_depth is 3
RMSE train: 9.951, test: 14.752
R^2 train: 0.871, test: 0.620
问题
我的理解是,即使我将 max_depth
设置为 [2,3]
,GridSearchCV
方法也应该选择 max_depth:3
作为自 max_depth:3
以来的最佳超参数return 在 RSME 或 R^2 方面的得分是否比 max_depth:2
更好。谁能告诉我为什么当我将 max_depth
设置为 [2,3]
时我的代码无法选择最佳超参数?
如果您 运行 使用 max_depth:2
进行第二次实验,那么即使 运行 使用 [=12],结果也无法与使用 max_depth:[2,3]
的第一次实验相比较=],因为你的代码中有一些你没有明确控制的随机源,即你的代码不是 可重现的。
随机性的第一个来源是 CV 折叠;为了确保实验将 运行 在相同的数据分割上,您应该按如下方式定义您的 GridSearchCV:
from sklearn.model_selection import KFold
seed_cv = 123 # any random value here
kf = KFold(n_splits=5, random_state=seed_cv)
grid_xgb_reg=GridSearchCV(xgb_reg,
param_grid=params,
scoring=scorer,
cv=kf, # <- change here
n_jobs=-1)
第二个随机性来源是 XGBRegressor 本身,它还包括一个 random_state
参数(参见 docs);你应该把它改成:
seed_xgb = 456 # any random value here (can even be the same with seed_cv)
xgb_reg = xgb.XGBRegressor(random_state=seed_xgb)
但即使有了这些安排,虽然您的数据拆分现在将是相同的,但在一般情况下构建的回归模型不一定如此;在这里,如果你保持这样的实验,即首先使用 max_depth:[2,3]
然后使用 max_depth:2
,结果确实是相同的;但是如果你把它改成,比如说,先用 max_depth:[2,3]
然后用 max_depth:3
,他们会 而不是 ,因为在第一个实验中, 运行 with max_depth:3
将以随机数生成器的不同状态开始(即 运行 with max_depth:2
完成后的状态)。
在这种情况下,您可以做出不同的 运行 的程度是有限的;对于一个非常细微的差异的例子,它仍然破坏了两个实验之间的精确再现性,请参阅我在