我在使用XGBClassifier处理澳大利亚降雨数据集,并尝试预测今天是否会下雨。我希望通过GridSearch调整分类器的超参数,并使用ROC_AUC进行评分。以下是我的代码:
param_grid = { "max_depth": [3, 4, 5, 7], "gamma": [0, 0.25, 1], "reg_lambda": [0, 1, 10], "scale_pos_weight": [1, 3, 5], "subsample": [0.8], # 固定子样本 "colsample_bytree": [0.5], # 固定列采样}from sklearn.model_selection import GridSearchCV# 初始化分类器xgb_cl = xgb.XGBClassifier(objective="binary:logistic", verbose=0)# 初始化估计器grid_cv = GridSearchCV(xgb_cl, param_grid, scoring="roc_auc", n_jobs=-1)# 拟合_ = grid_cv.fit(X, y)
当搜索最终完成时,我通过.best_score_
得到了最佳分数,但不知为何只得到了准确率分数而不是ROC_AUC。我以为这只是GridSearch的情况,所以我尝试了HalvingGridSearchCV
和cross_val_score
,将scoring
设置为roc_auc
,但我也得到了准确率分数。我通过手动计算sklearn.metrics.roc_auc_score
来验证这一点。
我做错了什么,还是这种行为的原因是什么?
回答:
你尝试过自己定义roc_auc评分规则吗?看起来你传递的是标签而不是概率(你原本需要的)用于roc_auc。
问题描述在这里:Different result roc_auc_score and plot_roc_curve
自定义评分器的解决方案:Grid-Search finding Parameters for AUC
更新2
抱歉,今天才发现我的笔记本介绍文本丢失了,哈哈
在计算roc_auc_score时,你有选项(无论是否使用gridsearch,管道与否),可以传递标签如(0/1)或概率如(0.995, 0.6655)。如果只是将概率转换为标签,第一种方式应该很容易实现。然而,这会导致输出图形为(直接反转的L形),有时看起来不好看。另一种选择是使用预测概率传递给roc_auc_score。这会导致输出图形为(阶梯状反转的L形),看起来好得多。所以你首先应该测试的是,能否使用标签获得roc auc分数,无论是否使用网格,如果可以的话。然后你应该尝试获取概率。我认为,你需要编写自己的评分方法,因为grid中的roc-auc_score只服务于标签,这会导致高roc_auc分数。我为你写了一些东西,这样你就可以看到标签方法:
import xgboost as xgbfrom sklearn.metrics import confusion_matrixfrom sklearn.datasets import load_breast_cancerfrom sklearn.metrics import roc_auc_scorecancer = load_breast_cancer()X = cancer.datay = cancer.targetxgb_model = xgb.XGBClassifier(objective="binary:logistic", eval_metric="auc", use_label_encoder=False, colsample_bytree = 0.3, learning_rate = 0.1, max_depth = 5, gamma = 10, n_estimators = 10, verbosity=None)X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42) xgb_model.fit(X_train, y_train)preds = xgb_model.predict(X_test)print(confusion_matrix(preds, y_test))print ('ROC AUC Score',roc_auc_score(y_test,preds))
输出结果为:
[[51 2] [ 3 87]] ROC AUC Score 0.9609862671660424
你可以看到这个分数非常高。
如果你想在网格中使用它,请删除以下代码:
# Fit_ = grid_cv.fit(X, y)
只需grid_cv.fit(x, y)
,fit是一个应用于grid_cv的方法,结果存储在grid_cv中
print(grid_cv.best_score_)
应该会输出你已经定义的auc。但这也应该非常高,因为你可能会传递标签而不是概率。
还要注意:What is the difference between cross_val_score with scoring=’roc_auc’ and roc_auc_score?
没有人阻止你将roc-auc_score函数应用于你的grid_results…