DEBUG.WIKI
OnlineSIM:在线接收短信,虚拟号码租用
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →
阿里云;从建站到云上业务;云服务器 · 数据库 · 对象存储;查看产品 →

Pipeline 已 fit 仍报未拟合:检查 skrub DropCols 的状态属性

scikit-learn 1.8.0 与 skrub 0.6.0 组合中,DropCols 的旧拟合属性不符合状态检查约定,外层模型训练后内部转换仍可能报 NotFittedError。

外层模型的 fit(X, y) 已返回,紧接着 predict(X) 却报 This Pipeline instance is not fitted yet。如果内部 Pipeline 最后一步是 skrub 的 DropCols,且组合为 scikit-learn 1.8.0、skrub 0.6.0,应检查转换器的拟合状态约定,而不是反复对外层模型追加 fit()。

这条路径中,DropCols 已完成自己的拟合,但旧属性没有使用尾部下划线。scikit-learn 的通用状态检查没有发现拟合属性,也没有可用的自定义状态判定,于是把内部 Pipeline 判成未拟合。它不意味着所有嵌套 Pipeline 都不能在 1.8 中使用。

在第三方转换器一侧采用正式修正

skrub 0.7.1 的发行记录已经修正 DropCols、SelectCols 的属性命名,使拟合状态能够被识别。后续正式实现的 DropCols 使用 kept_cols_、dropped_cols_。沿项目依赖约束采用包含修正的版本后,需要重新构建并训练相应 Pipeline;只更新包、继续加载旧序列化模型,不能保证旧对象状态随代码迁移。

不要为了消除异常,向模型任意添加一个名为 fitted_ 的字段。通用检查可能因此通过,但列选择状态并没有被正确建立。也不要把整个估计器伪装成不需要 fit:DropCols 的具体行为还依赖已检查的输入列。

诊断时查看真正训练后的内部对象

ColumnTransformer 会在拟合时克隆转换器。构造参数 transformers 中的原始对象未拟合,不足以证明训练失败;应查看训练后公开的 named_transformers_,再进入对应内部 Pipeline。

fitted_preprocessor = model.named_steps["preprocess"]
fitted_dates = fitted_preprocessor.named_transformers_["dates"]

这是对象访问示意,要求模型实际使用这两个自定义名称,并且外层 model.fit(...) 已成功。自动生成的步骤名或其他结构应按自身模型调整,不能把片段中的名称当作固定接口。检查最后一步 DropCols 的真实类型、版本和拟合状态,再决定是否符合本题。

如果是自己编写的转换器,应遵守拟合属性命名约定,或用 __sklearn_is_fitted__() 返回与真实状态一致的布尔值。这个方法不能无条件返回 True;至少要区分尚未训练、已训练以及重新设置参数后需要重训的情况。

同时验证训练与后续转换

更新后用相同列结构完成 fit、transform 和 predict,检查被删列、保留列顺序、特征名与样本行序。把一个原本保留的列误删掉,即使预测能够返回,也不算恢复。

若流程中另有病态矩阵警告,应单独检查数值条件。它与拟合状态识别不是同一个错误,不应通过删除列、换模型或压制异常把两个问题混在一起。保留旧环境和模型,避免不同预处理版本的特征与回归系数交叉使用。