make_scorer(roc_auc_score) 不等于预定义得分手 'roc_auc'
make_scorer(roc_auc_score) not equal to predefined scorer 'roc_auc'
我一直在使用 GridSearchCV 来优化二元分类器的一些参数。我想在几乎不会产生任何误报但仍然达到很高的真阳性率的情况下操作分类器。所以简而言之:在将 FPR 限制为 0(或接近)的同时优化 TPR。
因此我想稍微调整一下 roc_auc_score 作为 GridSearchCV 中的记分器参数。
clf1= SVC()
# define grid-space (obviously i would use a biger grid for the actual optimization)
grid1 = {'C':[1, 1000], 'kernel': ['poly'], 'degree' : [3], 'class_weight': ['balanced'], 'probability':[True]}
#define scoring function: Since we want to keep FPR = 0 we calculate the roc curve only between FPR = [0, 0.0001] (instead of [0, 1]
roc_spec = make_scorer(roc_auc_score, max_fpr=0.001)#define roc score for the unsave class
grid_clf_acc = GridSearchCV(clf1, param_grid = grid1 , scoring = roc_spec, n_jobs = -1, cv=cross_validation_folds)
grid_clf_acc.fit(X_train, y_train)
如您所见,我通过将 max_fpr 设置为 0.001 来调整 sklearn 的标准 roc_auc_score。
如果我现在 运行 网格搜索,不幸的是该算法不再使用多个置信度阈值来计算 roc_score,而是仅使用一个置信度阈值。
另一方面,如果我不使用 'selfmade' 记分器并使用带有预实现 roc_auc_score 的 Gridsearch,该算法确实使用多个阈值来计算 auc_roc_score。
grid_clf_acc = GridSearchCV(clf1, param_grid = grid1 , scoring = 'roc_auc', n_jobs = -1, cv=cross_validation_folds)
所以不知何故,稍微改编的 roc_auc_score 与原始 roc_auc_score 的功能不同。这是一个错误,还是我在定义自己的得分手时犯了错误?
(备注:
- 在这个例子中,我使用了 max_fpr=0.001。即使我将它设置为 1,它仍然会仅根据一个阈值计算 roc_auc 分数。
- 我也尝试了 make_scorer 函数的两个参数(needs_thresh & 或 needs_proba),但都没有解决问题。
最后我分享一张图片,它显示了我为定位问题而制作的两个 ROC。左侧显示了使用多个阈值生成的分类器的 ROC。顶部的数字是计算出的 ROC 分数。这个分数与我在使用自定义记分器时在 GridSearch 中得到的分数不匹配。但是,当我使用预实现的记分器时,它确实与分数匹配。在右侧,我为仅使用一个阈值生成的分类器绘制了一个 ROC(--> 我使用预测而不是 predict_prob)。使用自定义记分器时,计算出的 ROC 确实与 GridSearchCV 的计算出但“错误”ROC_AUC 分数相匹配。
我发现了我的错误。最终起作用的是如下初始化记分器:
roc_spec = make_scorer(roc_auc_score, max_fpr=0.001, needs_proba=True)
然后我还必须在 SVC 中设置 probabilty=True:
clf1= SVC(probability=True)
这让它起作用了。
我一直在使用 GridSearchCV 来优化二元分类器的一些参数。我想在几乎不会产生任何误报但仍然达到很高的真阳性率的情况下操作分类器。所以简而言之:在将 FPR 限制为 0(或接近)的同时优化 TPR。
因此我想稍微调整一下 roc_auc_score 作为 GridSearchCV 中的记分器参数。
clf1= SVC()
# define grid-space (obviously i would use a biger grid for the actual optimization)
grid1 = {'C':[1, 1000], 'kernel': ['poly'], 'degree' : [3], 'class_weight': ['balanced'], 'probability':[True]}
#define scoring function: Since we want to keep FPR = 0 we calculate the roc curve only between FPR = [0, 0.0001] (instead of [0, 1]
roc_spec = make_scorer(roc_auc_score, max_fpr=0.001)#define roc score for the unsave class
grid_clf_acc = GridSearchCV(clf1, param_grid = grid1 , scoring = roc_spec, n_jobs = -1, cv=cross_validation_folds)
grid_clf_acc.fit(X_train, y_train)
如您所见,我通过将 max_fpr 设置为 0.001 来调整 sklearn 的标准 roc_auc_score。
如果我现在 运行 网格搜索,不幸的是该算法不再使用多个置信度阈值来计算 roc_score,而是仅使用一个置信度阈值。
另一方面,如果我不使用 'selfmade' 记分器并使用带有预实现 roc_auc_score 的 Gridsearch,该算法确实使用多个阈值来计算 auc_roc_score。
grid_clf_acc = GridSearchCV(clf1, param_grid = grid1 , scoring = 'roc_auc', n_jobs = -1, cv=cross_validation_folds)
所以不知何故,稍微改编的 roc_auc_score 与原始 roc_auc_score 的功能不同。这是一个错误,还是我在定义自己的得分手时犯了错误?
(备注:
- 在这个例子中,我使用了 max_fpr=0.001。即使我将它设置为 1,它仍然会仅根据一个阈值计算 roc_auc 分数。
- 我也尝试了 make_scorer 函数的两个参数(needs_thresh & 或 needs_proba),但都没有解决问题。
最后我分享一张图片,它显示了我为定位问题而制作的两个 ROC。左侧显示了使用多个阈值生成的分类器的 ROC。顶部的数字是计算出的 ROC 分数。这个分数与我在使用自定义记分器时在 GridSearch 中得到的分数不匹配。但是,当我使用预实现的记分器时,它确实与分数匹配。在右侧,我为仅使用一个阈值生成的分类器绘制了一个 ROC(--> 我使用预测而不是 predict_prob)。使用自定义记分器时,计算出的 ROC 确实与 GridSearchCV 的计算出但“错误”ROC_AUC 分数相匹配。
我发现了我的错误。最终起作用的是如下初始化记分器:
roc_spec = make_scorer(roc_auc_score, max_fpr=0.001, needs_proba=True)
然后我还必须在 SVC 中设置 probabilty=True:
clf1= SVC(probability=True)
这让它起作用了。