如何在 scikit learn 中为 cross_validate 制作自定义评分指标?

Posted

技术标签:

【中文标题】如何在 scikit learn 中为 cross_validate 制作自定义评分指标?【英文标题】:How to make custom scoring metric for cross_validate in scikit learn? 【发布时间】:2020-06-11 05:07:48 【问题描述】:

我想开发 pr_auc 作为 cross_validate() 的评分指标。所以我遵循了 Scikit Learn 的用户指南:https://scikit-learn.org/stable/modules/model_evaluation.html#scoring

我的代码如下所示:

from sklearn.datasets import make_classification
from sklearn.model_selection import cross_validate
from xgboost import XGBClassifier
from sklearn.metrics import auc, make_scorer

def cus_pr_auc(x, y):
    score=auc(x, y)
    return score

X, y = make_classification(n_samples=1000, n_features=2, n_redundant=0,
    n_clusters_per_class=2, weights=[0.9], flip_y=0, random_state=7)

model = XGBClassifier(scale_pos_weight=9)

scores = cross_validate(model, X, y, scoring=make_scorer(cus_pr_auc, greater_is_better=True), cv=3, n_jobs=-1)

但是,我收到以下错误消息:

ValueError: x 既不增加也不减少:[1 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1]。

如何修复代码?

【问题讨论】:

auc 在这里似乎是一个奇怪的选择。为什么不使用 f1_score 之类的东西? Precision-Recall AUC 是针对罕见事件的算法性能的一个很好的测试。 Precision-Recall 曲线下的区域很好地近似了算法对稀有事件分类的技能。 【参考方案1】:

将您的指标从auc 更改为roc_auc_score,如下所示,您可以继续:

from sklearn.datasets import make_classification
from sklearn.model_selection import cross_validate
from xgboost import XGBClassifier
from sklearn.metrics import roc_auc_score, make_scorer

def cus_pr_auc(x, y):
    score=roc_auc_score(x, y)
    return score

X, y = make_classification(n_samples=1000, n_features=2, n_redundant=0,
    n_clusters_per_class=2, weights=[0.9], flip_y=0, random_state=7)

model = XGBClassifier(scale_pos_weight=9)

scores = cross_validate(model, X, y, scoring=make_scorer(cus_pr_auc, greater_is_better=True), cv=3, n_jobs=-1)

scores
'fit_time': array([0.0627017, 0.0569284, 0.046772 ]),
 'score_time': array([0.00534487, 0.00616908, 0.00347471]),
 'test_score': array([0.90244639, 0.90242424, 0.94969697])

您的auc 不起作用,因为根据docs:

x 坐标。这些必须是单调递增或单调递减。

因此您的错误(也请参阅here,了解错误消息的具体来源)。

通常auc 是一个低级评分指标,用作auc(fpr,tpr)

【讨论】:

使用 roc_auc_score() 是为了平衡数据集。对于不平衡的数据集,roc auc 并不是衡量算法性能的好方法。 @David293836 您需要查看文档以了解 aucroc_auc_score 的定义。另外,你们的 cmets 互相矛盾。 我已经找到了我的代码不起作用的原因。原因是自定义 make_scorer() 函数的第一个参数需要有 (y_actual, and y_predict) 的输入。所以自定义 auc 函数不起作用,因为它需要 (x, y) 的输入。您能解释一下为什么我的 cmets 会收缩吗? auc 用于严格增加或减少数据,如auc(fpr,tpr)。您需要使用roc_auc_score 来实现您的目标。 >>> So custom auc function does not work because it takes the input of (x, y)。这不是真的。查看您的错误消息为什么它不起作用。

以上是关于如何在 scikit learn 中为 cross_validate 制作自定义评分指标?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 scikit-learn 中为 OneVsRestClassifier 设置类权重?

如何从 scikit-learn 中与 predict_proba 一起使用的 cross_val_predict 获取类标签

如何在 scikit-learn 的分类问题中为 F1 分数做 GridSearchCV?

scikit-learn中的cross_val_score函数scoring参数设置

如何在 scikit learn 中为多元回归绘制最佳拟合平面?

交叉验证:来自 scikit-learn 参数的 cross_val_score 函数