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

partial_fit 遇到全 NaN 列后,MinMaxScaler 丢了历史范围

MinMaxScaler、MaxAbsScaler 增量拟合可能把全缺失批统计合并进有效历史。更新前拦截无观测列,受污染状态从保留历史数据重建。

前一批数据已经学到有效范围,后一批只有某一列全是 NaN,partial_fit() 没抛异常,却把这一列的 data_min_、data_max_ 或 max_abs_ 变成 NaN。随后即使传入有限数值,transform() 也可能继续输出 NaN。

这个问题有 scikit-learn 1.6.1 的明确环境,1.9.1 正式源码仍保留相关合并规则。MinMaxScaler、MaxAbsScaler 在批内跳过 NaN,但全缺失的一列没有有效批统计;再用普通 minimum、maximum 与历史值合并,会传播 NaN。不能把“拟合忽略 NaN”理解成所有增量边界都会自动保留历史值。

在调用前检查每一列有没有观测

对二维、以 NaN 表达缺失的浮点输入,可以在更新入口检查:

import numpy as np

empty_features = np.isnan(batch).all(axis=0)
if empty_features.any():
    raise ValueError("batch has a feature with no observed value")
scaler.partial_fit(batch)

batch、scaler 使用原流水线对象。检查应在调用前发生,并接入应用的待处理或失败流程;它不会替你自动补数据。如果缺失用的是别的哨兵值、稀疏结构或对象类型,需要按实际数据约定判断,不能直接照搬 np.isnan。

只看整批是否全 NaN 会漏掉本题:第二列可能有新值,第一列仍然全缺失。跳过整批可以保护旧统计,却也会丢掉其他列的有效更新,不能不加说明就这样做。

缓冲批次或重建,而非把 NaN 填成零

如果允许调整流处理粒度,可将待处理数据缓冲到每列都有有效观测后再更新,同时限制缓冲内存和等待时间。某列长期全缺失时,应按业务决定拒绝、延后或建立独立特征政策,不应无限等待。

将 NaN 填成 0 会让这个零参加极值计算,可能改变真实范围;给缺失列塞一个旧极值也会改变样本统计和处理记录。这些不是“忽略缺失”的等价实现。

状态已经污染后,停止使用受影响 scaler 输出。保留全部应参与拟合的历史数据时,可新建同参数 scaler,对完整历史重新 fit(),再与一次性拟合结果核对。不能只对最新批次调用 fit():它会重置此前学到的范围。

手工修一个 data_min_ 也不完整,scale_、min_、data_range_ 等派生状态可能已经不一致。没有原始数据或可信状态快照时,应明确无法自动恢复哪些统计,不要用任意默认值补齐。

检查已输出数据与下游模型

验收安排“先有效、后全缺失”“先全缺失、后有效”及部分列缺失的顺序,比较可恢复方案与同一份完整数据的一次性拟合结果。全程从未见到有效值的列仍然缺失,与丢掉已有有效统计是两回事。

缩放器变化还会影响下游模型所见特征尺度。重建后应按原训练与部署流程复核依赖对象,不能只恢复 scaler 就继续混用旧尺度的中间数据。保留批次顺序、原始输入和最后可信状态,才能确定需要重新转换或重算的范围。

这项处理不承诺修复所有增量预处理器。正式 1.9.1 仍采用上述极值合并逻辑,后续升级应核对具体实现并继续覆盖全缺失批次,不能只看普通批次拟合成功。