二元分类器过于自信,无法用 sklearn 绘制 ROC 曲线?
Posted
技术标签:
【中文标题】二元分类器过于自信,无法用 sklearn 绘制 ROC 曲线?【英文标题】:Binary classifier too confident to plot ROC curve with sklearn? 【发布时间】:2018-09-11 05:36:36 【问题描述】:我在 Tensorflow 中创建了一个二进制分类器,它将输出一个包含预测的生成器对象。我从对象中提取预测(例如 [0.98, 0.02])到一个列表中,然后将其转换为一个 numpy 数组。我有这些预测的相应标签数组。使用这两个数组,我相信我应该能够通过以下方式绘制 roc 曲线:
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve
fpr, tpr, thr = roc_curve(labels, predictions[:,1])
plt.plot(fpr, tpr)
plt.show()
print(fpr)
print(tpr)
print(thr)
其中 predictions[:,1] 给出正预测分数。但是,运行此代码只会导致一条直线,并且每个 fpr、tpr 和 thr 只有三个值: Flat line roc plot and limited function outputs.
关于为什么会发生这种情况,我唯一的理论是因为我的分类器太确定它的预测。许多(如果不是全部)正预测分数是 1.0,或者非常接近于零:
[[9.9999976e-01 2.8635742e-07]
[3.3693312e-11 1.0000000e+00]
[1.0000000e+00 9.8642090e-09]
...
[1.0106111e-15 1.0000000e+00]
[1.0000000e+00 1.0030269e-09]
[8.6156778e-15 1.0000000e+00]]
根据包括this *** 线程和this *** 线程在内的一些消息来源,我的预测的极端值可能会为 roc_curve() 造成问题。
我的直觉正确吗?如果是这样,我可以做些什么来绘制我的 roc_curve?
我已尝试包含我认为与此问题相关的所有信息,但如果您想了解有关我的程序的更多信息,请询问。
【问题讨论】:
【参考方案1】:ROC 是通过更改预测的阈值并找到每个阈值的敏感性和特异性来生成的。这通常意味着当您增加阈值时,您的敏感性会降低,但您的特异性会增加,并且它会描绘出您预测概率的整体质量。在您的情况下,由于一切都是 0 或 1(或非常接近),因此没有有意义的阈值可供使用。这就是为什么 thr 值基本上是 [ 1, 1, 1 ]。
您可以尝试将值任意拉近 0.5,或者实施您自己的 ROC 曲线计算,对微小差异有更大的容忍度。
另一方面,您可能想要检查您的网络,因为这样的结果值通常意味着那里存在问题,可能标签以某种方式泄漏到网络中,因此会产生完美的结果。
【讨论】:
我在 tensorboard 中获得了平滑(ish)的训练精度和损失曲线,这是否表明标签不参与预测结果?我在 tensorflow 网站上使用了 tensorflow estimator API 和卷积 mnist 教程作为我的代码框架。假设做这些事情让我能够将最佳实践与构建我的网络结合起来,如果你不介意给我你的直觉,我还能如何解决这些结果值的问题? 不幸的是,平滑的曲线或看起来正常的精度提高并不能保证任何事情。如果标签泄漏到网络中,它仍然会显示学习曲线。我不确定你的分类是什么,但我要做的是获得一些网络以前从未见过的新测试数据,然后不带标签运行。然后在一个 numpy 数组中获取结果,并手动将这些结果与几行 numpy.这大约需要半个小时,如果有问题会立即显示。以上是关于二元分类器过于自信,无法用 sklearn 绘制 ROC 曲线?的主要内容,如果未能解决你的问题,请参考以下文章
使用 sklearn 中的 OneVsRestClassifier 将自定义的二元分类调整为多类分类
如何从具有 2 个输出神经元的 softmax 二元分类器绘制 ROC 曲线?
第二章 | 分类问题 | F1-score | ROC曲线 | 精准率召回率 | tensorflow2.6+sklearn | 学习笔记