StatsModels 的预测函数如何与 scikit-learn 的 roc_auc_score 交互?

问题描述

我正在尝试了解 Logit 模型的 Python statsmodels 中的 predict 函数。它的文档是 here

当我构建 Logit 模型并使用 predict 时,它返回从 0 到 1 而不是 0 或 1 的值。现在我读到这篇文章说这些是概率,我们需要一个阈值。 Python statsmodel.api logistic regression (Logit)

现在,我想生成 AUC 数字,并使用 sklearn (docs) 中的 roc_auc_score

这就是我开始困惑的时候。

  1. 当我将 Logit 模型中的原始预测值(概率)放入 roc_auc_score 作为第二个参数 y_score 时,我得到了大约 80% 的合理 AUC 值。 roc_auc_score 函数如何知道我的哪些概率等于 1,哪些等于 0?我没有机会设置门槛。
  2. 当我使用 0.5 的阈值手动将概率转换为 0 或 1 时,我得到的 AUC 约为 50%。为什么会发生这种情况?

这是一些代码

m1_result = m1.fit(disp = False)

roc_auc_score(y,m1_result.predict(X1))

AUC: 0.80

roc_auc_score(y,[1 if X >=0.5 else 0 for X in m1_result.predict(X1)])

AUC: 0.50

为什么会这样?

解决方法

predict 根据您的拟合模型产生事件的估计概率。也就是说,每个元素对应于您的模型为每个观察计算的预测概率。

构建 ROC 曲线背后的过程包括选择每个预测概率作为阈值,测量其误报率和真阳性率,并将这些结果绘制为折线图。该曲线下方的面积是 AUC。

为了可视化这一点,假设您有以下数据:

观察 观察结果 predicted_prob
1 0 0.1
2 0 0.5
3 1 0.9

函数 roc_auc_score 将执行以下操作:

  1. 使用 0.1 作为阈值,使得 predicted_prob ≤ 0.1 的所有观察都归为 0,而 predicted_prob > 0.1 的观察将归为 1
  2. 使用 0.5 作为阈值,使得 predicted_prob ≤ 0.5 的所有观察都归为 0,而 predicted_prob > 0.5 的观察将归为 1
  3. 使用 0.9 作为阈值,使得 predicted_prob ≤ 0.9 的所有观察都归为 0,而 predicted_prob > 0.9 的观察将归为 1

三个不同的阈值(0.1、0.5 和 0.9)中的每一个都会导致各自的误报率和真阳性率。沿 x 轴绘制假阳性率,而沿 y 轴绘制真阳性率。

如您所料,您需要测试许多阈值才能绘制平滑曲线。如果您使用 0.5 作为阈值并将其传递给 roc_auc_curve,则您正在测试单个阈值的假阳性率和真阳性率。这是不正确的,也是 roc_auc_curve 返回的 AUC 比以前更低的原因。

您可能想通过计算其相应的准确率、真阳性率或假阳性率来测试单个阈值(即 0.5)的性能,而不是这样做。

例如,假设我们在上面的数据中设置了 0.5 的阈值。

观察 观察到的结果 predicted_prob predicted_class
1 0 0.1 0
2 0 0.5 0
3 1 0.9 1

这是一个愚蠢的例子,但通过使用 0.5 作为截止值,我们做出了完美的预测,因为 observed_result 在所有情况下都匹配 predicted_class

,

您计算 AUC 的第二种方法是错误的;根据定义,AUC 需要概率,而不是阈值化后生成的硬类预测 0/1,就像您在此处所做的那样。所以,你的 AUC 是 0.80。

你在AUC计算中没有自己设置阈值;粗略地说,正如我已经解释过的那样elsewhere,AUC 衡量的是一个二元分类器的性能在所有可能的决策阈值上平均

在这里再次解释 AUC 计算的基本原理和细节是多余的;相反,这些其他 SE 线程(以及其中的链接)将帮助您了解这个想法: