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 函数在内部是如何工作的?
使用 ywunbiased 时,statsmodels.tsa.stattools 中的 PACF 函数给出大于 1 的数字?
python使用statsmodels包中的robust.mad函数计算数组(Array)的中位数绝对偏差(MADMedian Absolute Deviation)