StatsModels 的预测功能如何与 scikit-learn 的 roc_auc_score 交互?

How does the predict function of StatsModels interact with roc_auc_score of scikit-learn?

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

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

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

这是我开始感到困惑的时候。

  1. 当我将 Logit 模型的原始预测值(概率)作为第二个参数 y_score 放入 roc_auc_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

为什么会这样?

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

您在计算AUC时没有自己设置阈值;粗略地说,正如我所解释的 ,AUC 测量二进制 classifier 在所有可能的决策阈值 .

上取平均值的性能

这里再解释一下AUC计算的原理和细节未免有些矫枉过正;相反,这些其他 SE 线程(以及其中的链接)将帮助您理解:

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

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

为了形象化,假设您有以下数据:

observation observed_result 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 的阈值。

observation observed_result 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