问题描述

在使用sklearn.metrics.roc_curve过程中可能会遇见以下两种问题:

1.混淆矩阵与ROC曲线严重不符

如你的混淆矩阵长这样(图左),而你的ROC曲线长这样(图右)

2.报错No positive samples in y_true

UndefinedMetricWarning: No positive samples in y_true, true positive value should be meaningless warnings.warn("No positive samples in y_true, "。同时AUC值为nan,绘制曲线为空白等等。

解决思路

1.查看sklearn库中相关描述

sklearn.metrics.roc_curve(y_true, y_score, *, pos_label=None, sample_weight=None, drop_intermediate=True)

y_true

大多数文章仅指出,y_true代表真实的样本标签,对其后续限定条件并未列出。即,1.必须是二分标签。2.如果标签不是{-1,1}或{0,1}则pos_label必须给出。也就是说,如果你的标签是{0,1}或{-1,1}你的pos_label是不用额外设置的.如果你的标签是{1,2}这种,你的pos_label就需要设置为2

y_score

该参数要求输入的是你正类的目标分数可以是正类的概率估计、置信值,也可以是决策的非阈值度量(由某些分类器上的“决策函数”返回)。注意!一定是正类!

2.解决方法

知道上面两个函数的具体含义后,解决方法自然就来了,问题1对应的是你的y_score给出的概率值是否为正类概率值。同时检查你的y_true给出的是否为真实标签。

问题二则是检查你的真实标签值是否为{-1,1}或{0,1}若是,则无需设置pos_label,若不是,则需设置pos_label。

额外的问题:y_true和y_sorce的类型需为ndarray of shape (n_samples,)。用以下转换即可

true_label_list = np.asarray(true_label_list)

3.相关代码

绘图代码网上其实挺多,我这里给出我自己的绘图代码与结果

#读取正例预测概率,这里的pred的shape为[n,2],第0列代表负例概率,第二列代表正例概率。
#真实情况需要根据自己模型预测结果进行调整
pre_cancer = []
for i in range(len(pred)):
    pre_cancer.append(pred[i][1])

#list转换为ndarrary
pre_cancer = np.asarray(pre_cancer)
true_label_list = np.asarray(true_label_list)


fpr,tpr,thre = roc_curve(true_label_list,pre_cancer)
auc = auc(fpr, tpr)
print(auc)

plt.plot(fpr, tpr, color='darkred', label='roc area:(%0.2f)' % auc)
plt.plot([0, 1], [0, 1], linestyle='--')
plt.xlim([0, 1])
plt.ylim([0, 1])
plt.xlabel('fpr')
plt.ylabel('tpr')
plt.title('roc_curve')
plt.legend(loc='lower right')
plt.show()

以上。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐