准确率已死-校准-区分度以及其他你真正需要的指标
准确率已死:校准、区分度以及其他你真正需要的指标
很久以前我们就发现,模型的发展不仅仅是为了做出预测。我们创建模型是为了做出决策,这需要信任。而仅仅依赖准确率是远远不够的。
在这篇文章中,我们将看到为什么,并检查其他更先进且符合我们需求的替代方案。一如既往,我们将采取实用方法,最终目标是深入挖掘标准指标之外的评估。
这是今天阅读的目录:
-
设置模型
-
分类:超越准确率
-
回归:高级评估
-
结论
设置模型
准确率对于分类算法比回归任务更有意义……因此,并不是所有问题都是同等衡量的。
这就是为什么我决定分别处理两种场景——回归和分类——通过创建两个不同的模型。
因为它们的性能和应用并不是今天关注的重点,所以它们将会非常简单:
-
分类:下一个比赛中前锋会进球吗?
-
回归:球员会进多少球?
如果你是一个经常阅读的读者,我确信足球示例的使用不会让你感到惊讶。
注意:尽管我们不会在我们的回归问题中使用准确率,而且这篇文章被认为更关注这个指标,但我不想遗漏这些案例。所以这就是为什么我们也会探索回归指标。
再次,因为我们不关心数据也不关心性能,让我跳过所有预处理部分,直接进入模型本身:
# Classification model
model = LogisticRegression()
model.fit(X_train_scaled, y_train)
# Gradient boosting regressor
model = GradientBoostingRegressor()
model.fit(X_train_scaled, y_train)
如您所见,我们坚持使用简单的模型:逻辑回归用于二元分类,梯度提升用于回归。
让我们检查我们通常会检查的指标:
# Classification
y_pred = model.predict(X_test_scaled)
accuracy = accuracy_score(y_test, y_pred)
print(f"Test accuracy: {accuracy:.2%}")
打印的准确率是 92.43%,老实说,这比我预期的要高得多。模型真的那么好吗?
# Regression
y_pred = model.predict(X_test_scaled)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
print(f"Test RMSE: {rmse:.4f}")
我得到了 0.3059 的 RMSE。并不好。但这足以摒弃我们的回归模型吗?
我们需要做得更好。
分类:超越准确率
太多的数据科学项目只停留在准确率上,这往往是误导性的,尤其是在不平衡的目标(例如,进球是罕见的)的情况下。
为了评估我们的模型是否真的能预测“这位球员会表现吗?”,这里有其他我们应该考虑的指标:
-
ROC-AUC:衡量将正例排在负例之上的能力。对阈值不敏感,但不关心校准。
-
PR-AUC:精确-召回曲线对于稀有事件(例如,评分概率)至关重要。它专注于正类,当正类数量稀少时这一点很重要。
-
Log Loss:惩罚过于自信的错误预测。非常适合比较校准的概率输出。
-
Brier 分数:衡量预测概率与实际结果之间的平均平方误差。越低越好,它可以解释为整体概率校准。
-
校准曲线:视觉诊断工具,用于查看预测概率是否与观察到的频率相匹配。
我们现在不会测试所有这些,但让我们简要地谈谈 ROC-AUC 和 Log Loss,这可能是除准确度之外最常用的指标。
ROC-AUC
ROC-AUC,或接收者操作特征 – 曲线下面积,是一个流行的指标,它包括测量 ROC 曲线下的面积,ROC 曲线是绘制真阳性率(TPR)与假阳性率(FPR)的曲线。
简而言之,ROC-AUC 分数(范围从 0 到 1)总结了模型在所有分类阈值下,如何产生相对分数以区分正例和负例的能力。
分数为 0.5 表示随机猜测,而 1 表示完美表现。
在 Python 中计算它很容易:
from sklearn.metrics import roc_auc_score
roc_auc = roc_auc_score(y_test, y_proba)
在这里,y_true 包含真实标签,而 y_proba 包含我们模型的预测概率。在我的情况下,分数是 0.7585,与准确度相比相对较低。但这是怎么可能的,如果我们得到的准确度超过了 90%?
背景:我们试图预测球员是否会在比赛中得分。问题是这是一个高度不平衡的数据:大多数球员不会得分,因此我们的模型学习到预测 0 是最可能的,而没有真正了解数据本身。
它无法正确捕捉少数类,而准确度也无法显示这一点。
Log Loss
对数损失、交叉熵,或者简单地说,对数损失,用于评估具有概率输出的性能。它衡量预测概率与实际(真实)值之间的差异,以对数形式计算。
再次,我们可以用一行 Python 代码来完成这个任务:
from sklearn.metrics import log_loss
logloss = log_loss(y_test, y_proba)
如你可能猜到的,值越低越好。0 将是完美的模型。在我的情况下,我得到了 0.2345。
这一个也受到类别不平衡的影响:对数损失对自信的错误预测惩罚非常严厉,而且由于我们的模型大多数时候预测 0,那些确实有进球的情况会影响最终得分。
回归:高级评估
在回归中,准确度没有意义,但我们有一系列有趣的指标来评估球员在给定比赛中将进球多少的问题。
当预测连续结果(例如,预期分钟数、比赛评分、幻想得分)时,简单的 RMSE/MAE 是一个起点——但我们可以走得更远。
其他指标和检查:
-
R²:表示模型解释目标变量变差的比例。
-
RMSLE:对低估的惩罚更轻,如果值呈指数变化(例如,幻想得分),则很有用。
-
MAPE / SMAPE:百分比误差,但要注意除以零的问题。
-
分位数损失:训练模型预测区间(例如,第 10、50、90 百分位数的输出)。
-
残差与预测值(plot):检查异方差性。
再次,让我们关注其中的一小部分。
R²得分
也称为决定系数,它比较模型误差与基线误差。得分为 1 表示完美拟合,得分为 0 表示仅预测均值,得分低于 0 表示比均值预测更差。
from sklearn.metrics import r2_score
r2 = r2_score(y_test, y_pred)
我的得分是 0.0557,这非常接近 0… 这并不好。
RMSLE
均方根对数误差(Root Mean Squared Logarithmic Error,或 RMSLE),衡量的是预测值和实际值对数变换后平均平方差的平方根。当以下情况时,这个指标很有用:
-
我们希望更温和地惩罚低估。
-
我们的目标变量是偏斜的(它减少了大型异常值的影响)。
from sklearn.metrics import mean_squared_log_error
rmsle = np.sqrt(mean_squared_log_error(y_test, y_pred))
我的得分是 0.19684,这意味着我的平均预测误差大约是 0.2 个目标。这并不大,但考虑到我们的目标变量介于 0 到 4 之间,且高度偏向 0…
分位数损失
也称为弹珠损失,它可以用于分位数回归模型来评估我们的预测分位数表现如何。如果我们构建一个分位数模型(使用分位数损失的 GradientBoostingRegressor),我们可以这样测试:
from sklearn.metrics import mean_pinball_loss
alpha = 0.9
q_loss = mean_pinball_loss(y_test, y_pred_quantile, alpha=alpha)
在这里,我们使用 alpha 0.9 试图预测第 90 百分位数。我的分位数损失是 0.0644,这在相对意义上非常小(~目标变量范围的 1.6%)。
然而,分布很重要:我们的大部分y_test值都是 0,我们需要将其解释为“平均而言,我们的模型在捕捉上尾误差方面非常低”。
考虑到目标变量中 0 的占比很高,这一点尤其令人印象深刻。
但是,因为大多数输出都是 0,所以我们应该使用我们之前看到和提到的其他指标来评估我们的模型是否真的表现良好。
结论
构建预测模型远不止简单地实现“良好的准确性”。
对于分类任务,你需要考虑不平衡数据、概率校准和现实世界的用例,如定价或风险管理。
对于回归任务,目标不仅仅是最小化误差,还要理解不确定性——如果你的预测涉及策略或交易决策,这一点至关重要。
最终,真正的价值在于:
-
精心挑选,时间上有效的特征。
-
针对问题的先进评估指标。
-
透明,可视化良好的比较。
如果你做对了这些,你就不再是在构建“仅仅另一个模型”。你正在提供稳健、决策就绪的工具。而我们在这里探讨的指标只是入门点。

浙公网安备 33010602011771号