DEBUG.WIKI
野草云;香港 200Mbps 峰值;不限月流量 · BGP VPS;查看套餐 →
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS

balanced accuracy 为什么算出 -inf 或 NaN

验证折的真实标签只有一个类别时,adjusted balanced accuracy 的随机基线归一化分母为零。检查交叉验证划分与评分有效性,不要把异常分数替成零继续排名。

调用 balanced_accuracy_score(y_true, y_pred, adjusted=True),得到 -inf;同一批真实标签改成全部预测正确后,又变成 NaN。先看 y_true 有几个类别,尤其是交叉验证的每个验证折,而不是先调整模型学习率。

当验证数据的真实标签只有一个类别,调整后的 balanced accuracy 没有正常的随机基线归一化分母。scikit-learn 1.9.0 和 1.9.1 的这条计算路径都按有效类别数量计算基线。它不是模型“差到无限”,也不意味着这个 NaN 可以安全当成零。

单类别为什么让调整项失效

balanced accuracy 先计算各真实类别的召回率,再求平均。adjusted=True 还要减去随机基线 1 / n_classes,再除以 1 - 1 / n_classes。当实际参与计算的真实类别只有一个,最后的分母就是零。

若预测全部正确,调整项会出现零除零;若还有错误预测,可能出现负值除以零。即使 y_pred 多出一个类别,那个类别在 y_true 中没有样本,也不会凭空给验证集增加一类真实观测。

先对每折的真实标签计数,并保留训练、验证索引。训练集有两类,并不能保证验证集也有两类;时间切分、分组切分、小样本或极端不平衡时尤其要逐折检查。普通随机抽取偶尔没有出错,也不能证明下一次划分有效。

在评分前明确拒绝无效输入

对一维单输出分类标签,可以在该评分器入口增加明确的有效性判断:

import numpy as np
from sklearn.metrics import balanced_accuracy_score

if np.unique(y_true).size < 2:
    raise ValueError("adjusted balanced accuracy needs two observed classes")
score = balanced_accuracy_score(y_true, y_pred, adjusted=True)

这里的 y_true、y_pred 是当前验证折。样本权重使某类有效权重为零时,还要按实际评分定义检查有效观测;仅数标签种类并不足够。多输出标签也不能直接套用这个一维判断。

如果业务允许调整划分,先评估分层是否与时间、用户或组隔离要求兼容。不能为了每折都有两类就打散必须隔离的组,或让未来数据进入训练集。少数类数量不足时,减少折数也要服从同一数据约束。

保留无效分数的含义

不能用 nan_to_num 把 NaN、无穷全部改成零继续选模型。这样会混淆“这个折不能计算指标”和“这个折有效地得到零分”,改变最终排名。nanmean 也不会自动忽略负无穷。

确实无法构造可计算的验证折时,应在评估协议中规定如何报告该折、是否停止比较,以及使用什么额外指标描述表现。改为 adjusted=False 是换指标,不是修正同一个分数;应明确记录,不与历史调整后分数直接拼在一起。

核对结果时覆盖双类别、单类别全对和单类别含错三种情况,确认无效输入在预定位置结束,不再进入汇总排名。后续正式版本即便改变了返回值,也不等于单类别验证集突然具备有效的调整后基线。