Hyperopt与XGBRegressor搭配时结果非确定性问题排查
问题根源与解决方案
核心错误:语法错误导致参数未正确传递
你的objective函数里存在一个低级语法错误,直接导致了Loss差异:
# 错误代码行(多了一个逗号) 'learning_rate': params['learning_rate',]
这里的params['learning_rate',]会取键为**元组('learning_rate',)**的值,而Hyperopt搜索空间里的键是字符串'learning_rate',所以这行代码实际无法获取到搜索到的学习率,XGBRegressor会使用默认的learning_rate=0.3训练模型。
而你手动代入的最优参数里,learning_rate=0.9867,这是一个非常大的学习率,和默认值0.3训练出来的模型性能必然天差地别——这就是Loss A(26,用默认学习率)和Loss B(43,用0.9867学习率)差异巨大的根本原因,和浮点数异常无关。
修复步骤
- 修正语法错误
将objective函数中的错误行改为:
'learning_rate': params['learning_rate']
- 重新运行超参搜索
修正后,Hyperopt搜索时会正确传递所有参数,此时搜索得到的最优参数对应的Loss,和手动代入该参数训练模型得到的Loss会完全一致(因为random_state=42保证了确定性)。
额外验证点
- 检查
max_depth的处理:hp.choice('max_depth', range(1, 20, 2))返回的是列表的索引值,比如你得到的max_depth=9对应索引4(因为range(1,20,2)的第5个元素是9),这部分处理是正确的,无需修改。
修复后的完整objective函数
def objective(params): params = { 'n_estimators': int(params['n_estimators']), 'max_depth': int(params['max_depth']), 'min_child_weight': params['min_child_weight'], 'gamma': params['gamma'], 'subsample': params['subsample'], 'colsample_bytree': params['colsample_bytree'], 'learning_rate': params['learning_rate'], # 修正了逗号错误 'reg_alpha': params['reg_alpha'], 'reg_lambda': params['reg_lambda'] } model = xgb.XGBRegressor(objective='reg:absoluteerror', enable_categorical=True, booster='gbtree', random_state=42, verbose=2,**params) model.fit(X_train, Y_train) Y_pred = model.predict(X_test) loss = abs(Y_test - Y_pred).mean() # mean absolute error return {'loss': loss, 'status': STATUS_OK}
内容的提问来源于stack exchange,提问作者FAD
相关产品推荐
相关产品推荐

