DEBUG.WIKI
丽萨主机;为跨境业务选好 IP;原生 / 住宅 IP · 按套餐选择;查看 IP →
晚安云;香港 CN2 ¥15/月
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS

auc 将面积 1 算成 255:先检查无符号横坐标

sklearn.metrics.auc 直接接收递减 uint 横坐标时,差分可能回绕,既算错面积又漏过非单调检查。计算前明确可用的浮点坐标范围。

auc([2,1,0], [0,1,0]) 的面积应为 1;把横坐标存成 uint8 后,sklearn.metrics.auc 却可能返回 255,没有警告。若同样的数据转成浮点数便正常,应检查横坐标差分的 dtype,而不是先调整模型。

这条故障有 scikit-learn 1.7.2、1.8.0、1.9.1 的记录。它针对直接调用 auc(x,y);不能据此判定常规 roc_auc_score() 的计算也有相同问题。

递减差分在 uint 中会回绕

auc 支持单调增加或单调减少的横坐标。1.9.1 使用 np.diff(x) 检查方向,再用梯形积分计算面积。对于 uint8,1-2 无法表示为负数,会变成 255,于是本来递减的步长看起来全为正。

这还会漏过非单调输入。例如 [0,2,1] 的最后一步本应为负,却同样回绕;函数可能返回一个数字而未拒绝这条来回折返的曲线。

在计算前选择能表达差值的坐标类型

对规模适合 float64 的普通数值横坐标,可以先转换,再调用接口:

import numpy as np
from sklearn.metrics import auc

x = np.array([2, 1, 0], dtype=np.uint8)
y = np.array([0.0, 1.0, 0.0])
x_work = x.astype(np.float64)
area = auc(x_work, y)

这里预期 area 为 1。只把最终面积转成浮点没有作用,因为差分和积分已经发生过回绕。也不要把所有无符号整数盲目转成同宽有符号整数:较大的值可能在转换时先溢出。

float64 只能精确表示一定范围的整数,超过 2**53 的相邻大整数可能合并。若原横坐标是高精度时间计数或巨大整数,需要先设计保留有意义差值的表示,并核对转换后的间距;不能把上面的转换当成无损规则。

顺序本身也要保留

可以通过相邻值的直接比较检查原始横坐标是否单调,避免在检查阶段先做易溢出的减法。若确实需要反向处理递减曲线,必须让 x、y 同时反转。只排序 x 会破坏点的对应关系;将一条本来不单调的曲线排序后积分,也会改变问题定义。

不要把面积超出 0 到 1 自动裁回去。auc 是通用曲线面积函数,范围取决于坐标与单位;本题的异常值来自输入类型,裁剪无法恢复正确面积。

验收比较原曲线、两轴同步反转、明确浮点输入的面积,另外加入非单调样本,确认它按预期被拒绝。对于真实模型评估,还应核对曲线生成步骤、阈值顺序和所用积分定义,不能把梯形 PR 面积与 average precision 当成同一个量。

正式 1.9.1 仍有上述差分实现。更换版本前保留原依赖与坐标,更新后继续检查数值结果和输入拒绝行为;训练标签二值化中的无符号溢出属于另一条处理路径,不能用修正标签代替修正这里的横坐标。