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

Posted

技术标签:

【中文标题】StatsModels 的 predict 函数如何与 scikit-learn 的 roc_auc_score 交互?【英文标题】:How does the predict function of StatsModels interact with roc_auc_score of scikit-learn? 【发布时间】:2021-06-15 03:53:25 【问题描述】:

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

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

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

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

    当我将来自我的 Logit 模型的原始预测值(概率)作为第二个参数 y_score 放入 roc_auc_score 时,我得到了一个合理的 AUC 值,约为 80%。 roc_auc_score 函数如何知道我的哪些概率等于 1,哪些等于 0?我没有机会设定门槛。 当我使用 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

为什么会这样?

【问题讨论】:

【参考方案1】:

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

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

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

In Classification, what is the difference between the test accuracy and the AUC score? Advantages of AUC vs standard accuracy Getting a low ROC AUC score but a high accuracy Comparing AUC, log loss and accuracy scores between models

【讨论】:

【参考方案2】:

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

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

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

observation observed_result predicted_prob
1 0 0.1
2 0 0.5
3 1 0.9

函数roc_auc_score 将执行以下操作:

    使用 0.1 作为阈值,使得所有 predicted_prob ≤ 0.1 的观测值归类为 0,predicted_prob > 0.1 的观测值归类为 1 使用 0.5 作为阈值,使所有 predicted_prob ≤ 0.5 的观测值归类为 0,predicted_prob > 0.5 的观测值归类为 1 使用 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 匹配。

【讨论】:

以上是关于StatsModels 的 predict 函数如何与 scikit-learn 的 roc_auc_score 交互?的主要内容,如果未能解决你的问题,请参考以下文章

Statsmodels ARIMA - 使用预测()和预测()的不同结果

为啥在使用 statsmodels 预测测试值时会收到此 numpy 错误?

sklearn 的 MLP predict_proba 函数在内部是如何工作的?

12-少年,玩模型吗?手把手教你statsmodels建模

使用 ywunbiased 时,statsmodels.tsa.stattools 中的 PACF 函数给出大于 1 的数字?

python使用statsmodels包中的robust.mad函数计算数组(Array)的中位数绝对偏差(MADMedian Absolute Deviation)