Fra*_*ina 9 python machine-learning scikit-learn xgboost
我正在尝试将 XGBoost 用于包含大约 500,000 个观察值和 10 个特征的特定数据集。我正在尝试使用 进行一些超参数调整RandomizedSeachCV,并且具有最佳参数的模型的性能比具有默认参数的模型的性能差。
具有默认参数的模型:
model = XGBRegressor()
model.fit(X_train,y_train["speed"])
y_predict_speed = model.predict(X_test)
from sklearn.metrics import r2_score
print("R2 score:", r2_score(y_test["speed"],y_predict_speed, multioutput='variance_weighted'))
R2 score: 0.3540656307310167
Run Code Online (Sandbox Code Playgroud)
随机搜索的最佳模型:
booster=['gbtree','gblinear']
base_score=[0.25,0.5,0.75,1]
## Hyper Parameter Optimization
n_estimators = [100, 500, 900, 1100, 1500]
max_depth = [2, 3, 5, 10, 15]
booster=['gbtree','gblinear']
learning_rate=[0.05,0.1,0.15,0.20]
min_child_weight=[1,2,3,4]
# Define the grid of hyperparameters to search
hyperparameter_grid = {
'n_estimators': n_estimators,
'max_depth':max_depth,
'learning_rate':learning_rate,
'min_child_weight':min_child_weight,
'booster':booster,
'base_score':base_score
}
# Set up the random search with 4-fold cross validation
random_cv = RandomizedSearchCV(estimator=regressor,
param_distributions=hyperparameter_grid,
cv=5, n_iter=50,
scoring = 'neg_mean_absolute_error',n_jobs = 4,
verbose = 5,
return_train_score = True,
random_state=42)
random_cv.fit(X_train,y_train["speed"])
random_cv.best_estimator_
XGBRegressor(base_score=0.5, booster='gblinear', colsample_bylevel=None,
colsample_bynode=None, colsample_bytree=None, gamma=None,
gpu_id=-1, importance_type='gain', interaction_constraints=None,
learning_rate=0.15, max_delta_step=None, max_depth=15,
min_child_weight=3, missing=nan, monotone_constraints=None,
n_estimators=500, n_jobs=16, num_parallel_tree=None,
random_state=0, reg_alpha=0, reg_lambda=0, scale_pos_weight=1,
subsample=None, tree_method=None, validate_parameters=1,
verbosity=None)
Run Code Online (Sandbox Code Playgroud)
使用最佳模型:
regressor = XGBRegressor(base_score=0.5, booster='gblinear', colsample_bylevel=None,
colsample_bynode=None, colsample_bytree=None, gamma=None,
gpu_id=-1, importance_type='gain', interaction_constraints=None,
learning_rate=0.15, max_delta_step=None, max_depth=15,
min_child_weight=3, monotone_constraints=None,
n_estimators=500, n_jobs=16, num_parallel_tree=None,
random_state=0, reg_alpha=0, reg_lambda=0, scale_pos_weight=1,
subsample=None, tree_method=None, validate_parameters=1,
verbosity=None)
regressor.fit(X_train,y_train["speed"])
y_pred = regressor.predict(X_test)
from sklearn.metrics import r2_score
print("R2 score:", r2_score(y_test["speed"],y_pred, multioutput='variance_weighted'))
R2 score: 0.14258774171629718
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,运行随机搜索 3 小时后,准确度实际上下降了。如果我将线性更改为树,该值将上升到 0.65,那么为什么随机搜索不起作用?
我还收到以下警告:
这可能不准确,因为某些参数仅在语言绑定中使用,但传递到 XGBoost 核心。或者有些参数没有被使用但是却漏过了这个验证。如果您发现上述情况,请提出问题。
有人对这种超参数调整方法有建议吗?
小智 19
正如XGBoost 文档中所述
参数调优是机器学习中的一门黑暗艺术,模型的最佳参数可能取决于许多场景。
您询问了针对您的具体情况的建议,因此以下是我的一些建议。
booster从超参数搜索空间中删除维度。您可能想要使用默认的增强器“gbtree”。如果您对线性模型的性能感兴趣,您可以尝试线性或岭回归,但在 XGBoost 参数调整期间不要打扰它。base_score从超参数搜索空间中删除维度。对于足够多的提升迭代,这应该不会产生太大的影响(请参阅XGB 参数文档)。booster和base_score尺寸后,您将下降到hyperparameter_grid = {
'n_estimators': [100, 500, 900, 1100, 1500],
'max_depth': [2, 3, 5, 10, 15],
'learning_rate': [0.05, 0.1, 0.15, 0.20],
'min_child_weight': [1, 2, 3, 4]
}
Run Code Online (Sandbox Code Playgroud)
有 400 种可能的组合。对于第一次拍摄,我会稍微简化一下。例如你可以尝试类似的东西
hyperparameter_grid = {
'n_estimators': [100, 400, 800],
'max_depth': [3, 6, 9],
'learning_rate': [0.05, 0.1, 0.20],
'min_child_weight': [1, 10, 100]
}
Run Code Online (Sandbox Code Playgroud)
只剩下 81 种组合,并且一些非常昂贵的组合(例如深度为 15 的 1500 棵树)被删除。当然我不知道你的数据,所以也许有必要考虑这么大/复杂的模型。对于具有平方损失的回归任务来说,min_child_weight它只是子级中的实例数(再次参见XGB 参数文档)。由于您有 500000 个观测值,因此 1、2、3 或 4 个观测值最终出现在叶子中可能不会产生(很大)差异。因此,我[1, 10, 100]在这里建议。也许随机搜索会发现比该网格中的默认参数更好的东西?
hyperparameter_grid = {
'max_depth': [3, 6, 9],
'min_child_weight': [1, 10, 100]
}
Run Code Online (Sandbox Code Playgroud)
将学习率固定在某个恒定值(不要太低,例如 0.15)。对于每个设置,使用早期停止来确定适当的树木数量。这可以使用xgboost.cvearly_stopping_rounds方法的参数来实现。之后,您知道和的良好组合(例如,对于给定问题,基础学习器需要有多复杂?),并且还知道该组合和固定学习率的大量树。然后,微调可能涉及“接近”当前(max_深度,min_child_weight)解决方案进行另一个超参数搜索和/或在增加树数量的同时降低学习率。max_depthmin_child_weight