注意
Go to the end to download the full example code or to run this example in your browser via JupyterLite or Binder.
检测错误权衡(DET)曲线#
在这个示例中,我们比较了两个二元分类多阈值指标:接收者操作特征(ROC)和检测错误权衡(DET)。为此,我们针对相同的分类任务评估了两个不同的分类器。
ROC 曲线在 Y 轴上显示真阳性率(TPR),在 X 轴上显示假阳性率(FPR)。这意味着图表的左上角是“理想”点 - FPR 为零,TPR 为一。
DET 曲线是 ROC 曲线的一种变体,其中 Y 轴绘制的是假阴性率(FNR)而不是 TPR。在这种情况下,原点(左下角)是“理想”点。
注意
有关 ROC 曲线的更多信息,请参阅
sklearn.metrics.roc_curve。有关 DET 曲线的更多信息,请参阅
sklearn.metrics.det_curve。此示例大致基于 分类器比较 示例。
有关估计 ROC 曲线和 ROC-AUC 方差的示例,请参阅 带有交叉验证的接收者操作特征(ROC)。
# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause
生成合成数据#
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
X, y = make_classification(
n_samples=1_000,
n_features=2,
n_redundant=0,
n_informative=2,
random_state=1,
n_clusters_per_class=1,
)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4, random_state=0)
定义分类器#
在这里我们定义了两个不同的分类器。目标是使用 ROC 和 DET 曲线,通过阈值直观地比较它们的统计性能。
from sklearn.dummy import DummyClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import make_pipeline
from sklearn.svm import LinearSVC
classifiers = {
"Linear SVM": make_pipeline(StandardScaler(), LinearSVC(C=0.025)),
"Random Forest": RandomForestClassifier(
max_depth=5, n_estimators=10, max_features=1, random_state=0
),
"Non-informative baseline": DummyClassifier(),
}
比较 ROC 和 DET 曲线#
DET 曲线通常以正态偏差刻度绘制。为了实现这一点,DET 显示器将 det_curve 返回的错误率和轴刻度使用 scipy.stats.norm 进行转换。
import matplotlib.pyplot as plt
from sklearn.dummy import DummyClassifier
from sklearn.metrics import DetCurveDisplay, RocCurveDisplay
fig, [ax_roc, ax_det] = plt.subplots(1, 2, figsize=(11, 5))
ax_roc.set_title("Receiver Operating Characteristic (ROC) curves")
ax_det.set_title("Detection Error Tradeoff (DET) curves")
ax_roc.grid(linestyle="--")
ax_det.grid(linestyle="--")
for name, clf in classifiers.items():
(color, linestyle) = (
("black", "--") if name == "Non-informative baseline" else (None, None)
)
clf.fit(X_train, y_train)
RocCurveDisplay.from_estimator(
clf,
X_test,
y_test,
ax=ax_roc,
name=name,
curve_kwargs=dict(color=color, linestyle=linestyle),
)
DetCurveDisplay.from_estimator(
clf, X_test, y_test, ax=ax_det, name=name, color=color, linestyle=linestyle
)
plt.legend()
plt.show()

请注意,使用 DET 曲线比使用 ROC 曲线更容易直观地评估不同分类算法的整体性能。由于 ROC 曲线以线性刻度绘制,因此在图表的大部分区域,不同分类器通常看起来相似,而在图表的左上角差异最大。另一方面,由于 DET 曲线在正态偏差刻度下表示为直线,它们往往作为一个整体可区分,并且感兴趣的区域占据了图表的大部分。
DET 曲线提供有关检测错误权衡的直接反馈,有助于操作点分析。用户可以决定他们愿意接受的 FNR,以换取 FPR(反之亦然)。
ROC 和 DET 曲线的非信息性分类器基线#
上面图表中的对角线黑点线对应于使用默认“先验”策略的 DummyClassifier,作为与其他分类器进行比较的基线。这个分类器做出恒定的预测,独立于 X 中的输入特征,使其成为一个非信息性分类器。
为了进一步理解 ROC 和 DET 曲线的非信息性基线,我们回顾以下数学定义
\(\text{FPR} = \frac{\text{FP}}{\text{FP} + \text{TN}}\)
\(\text{FNR} = \frac{\text{FN}}{\text{TP} + \text{FN}}\)
\(\text{TPR} = \frac{\text{TP}}{\text{TP} + \text{FN}}\)
一个总是预测正类的分类器将没有真阴性(TN)和假阴性(FN),从而给出 \(\text{FPR} = \text{TPR} = 1\) 和 \(\text{FNR} = 0\),即
ROC 平面右上角的一个点,
DET 平面右下角的一个点。
同样,一个总是预测负类的分类器将没有真阳性(TP)和假阳性(FP),因此 \(\text{FPR} = \text{TPR} = 0\) 和 \(\text{FNR} = 1\),即
ROC 平面左下角的一个点,
DET 平面左上角的一个点。
脚本总运行时间: (0 minutes 0.168 seconds)
相关示例