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
。
这是我开始感到困惑的时候。
- 当我将 Logit 模型的原始预测值(概率)作为第二个参数
y_score
放入 roc_auc_score
时,我得到了大约 80% 的合理 AUC 值。 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
为什么会这样?
你计算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
将执行以下操作:
- 使用 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
。
我正在尝试了解 Python statsmodels 中的 predict
函数用于 Logit 模型。它的文档是 here.
当我构建 Logit 模型并使用 predict
时,它 returns 的值从 0 到 1,而不是 0 或 1。现在我读到这句话说这些是概率,我们需要一个阈值. Python statsmodel.api logistic regression (Logit)
现在,我想生成 AUC 数字,我使用来自 sklearn (docs) 的 roc_auc_score
。
这是我开始感到困惑的时候。
- 当我将 Logit 模型的原始预测值(概率)作为第二个参数
y_score
放入roc_auc_score
时,我得到了大约 80% 的合理 AUC 值。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
为什么会这样?
你计算AUC的第二种方法是错误的;根据定义,AUC 需要 概率 ,而不是硬 class 阈值化后生成的预测 0/1,就像您在此处所做的那样。所以,你的 AUC 是 0.80。
您在计算AUC时没有自己设置阈值;粗略地说,正如我所解释的
这里再解释一下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
将执行以下操作:
- 使用 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
。