You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Scikit-Learn 1.1.2训练序列化的ColumnTransformer迁移至1.5.1?

Scikit-Learn 1.1.2 到1.5.1 ColumnTransformer 迁移方案(保留已学习信息)

核心问题

你的迁移难点集中在OneHotEncoder:Scikit-Learn 1.1.2到1.5.1版本间,OneHotEncoder的内部拟合参数存储结构有变化,直接加载旧版本pickle文件会触发兼容性错误;而passthrough和自定义转换器因逻辑简单,版本兼容性较好。

迁移步骤(分环境操作)

步骤1:在Scikit-Learn 1.1.2环境提取关键参数

先加载已训练的ColumnTransformer,提取OneHotEncoder的所有已学习参数,以及ColumnTransformer的结构元数据:

import pickle
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder

# 加载旧模型
with open("trained_transformer.pkl", "rb") as f:
    old_transformer = pickle.load(f)

# 提取ColumnTransformer全局配置
ct_meta = {
    "transformers": old_transformer.transformers,
    "remainder": old_transformer.remainder,
    "sparse_output": old_transformer.sparse_output,
    "feature_names_in_": old_transformer.feature_names_in_,
    "n_features_in_": old_transformer.n_features_in_
}

# 定位并提取OneHotEncoder的拟合参数
ohe_data = {}
for name, trans, cols in ct_meta["transformers"]:
    if isinstance(trans, OneHotEncoder):
        ohe_data.update({
            "name": name,
            "columns": cols,
            "categories_": trans.categories_,
            "drop_idx_": trans.drop_idx_ if hasattr(trans, "drop_idx_") else None,
            "drop": trans.drop,
            "handle_unknown": trans.handle_unknown,
            "sparse": trans.sparse  # 1.1.2参数名,对应1.5.1的sparse_output
        })
        break

# 保存提取的参数(用pickle或json,注意numpy数组需用pickle)
with open("ct_migration_data.pkl", "wb") as f:
    pickle.dump({"ct_meta": ct_meta, "ohe_data": ohe_data}, f)

步骤2:在Scikit-Learn 1.5.1环境重建模型

在新环境中,基于提取的参数重新构建ColumnTransformer,手动还原OneHotEncoder的拟合状态:

import pickle
import numpy as np
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder

# 加载迁移数据
with open("ct_migration_data.pkl", "rb") as f:
    migration_data = pickle.load(f)
ct_meta = migration_data["ct_meta"]
ohe_data = migration_data["ohe_data"]

# 重建OneHotEncoder并还原拟合状态
new_ohe = OneHotEncoder(
    drop=ohe_data["drop"],
    handle_unknown=ohe_data["handle_unknown"],
    sparse_output=ohe_data["sparse"]  # 适配1.5.1的参数名
)
# 手动赋值已学习参数
new_ohe.categories_ = ohe_data["categories_"]
new_ohe.feature_names_in_ = ct_meta["feature_names_in_"]
if ohe_data["drop_idx_"] is not None:
    new_ohe.drop_idx_ = ohe_data["drop_idx_"]
# 标记为已拟合状态
new_ohe._fitted = True

# 重建ColumnTransformer的转换器列表
new_transformers = []
for name, trans, cols in ct_meta["transformers"]:
    if name == ohe_data["name"]:
        new_transformers.append((name, new_ohe, ohe_data["columns"]))
    else:
        # passthrough直接保留,自定义转换器需确保代码与旧环境完全一致
        new_transformers.append((name, trans, cols))

# 构建最终的ColumnTransformer
new_transformer = ColumnTransformer(
    transformers=new_transformers,
    remainder=ct_meta["remainder"],
    sparse_output=ct_meta["sparse_output"]
)
# 还原全局拟合标记与参数
new_transformer._fitted = True
new_transformer.feature_names_in_ = ct_meta["feature_names_in_"]
new_transformer.n_features_in_ = ct_meta["n_features_in_"]
if hasattr(old_transformer, "transformer_output_"):
    new_transformer.transformer_output_ = old_transformer.transformer_output_

步骤3:验证迁移正确性

用相同测试数据对比新旧模型的输出,确保信息无丢失:

# 假设X_test为测试数据集
# 旧环境输出(需在1.1.2环境提前导出)
old_output = old_transformer.transform(X_test)
# 新环境输出
new_output = new_transformer.transform(X_test)

# 对比结果(稀疏矩阵需转为数组后对比)
if hasattr(old_output, "toarray"):
    np.testing.assert_array_equal(old_output.toarray(), new_output.toarray())
else:
    np.testing.assert_array_equal(old_output, new_output)

关键注意事项

  • 自定义转换器的代码必须在新旧环境中完全一致(包括类名、方法实现、参数定义),否则无法正常复用。
  • 若OneHotEncoder使用了drop参数,必须确保drop_idx_参数正确复制,否则会导致类别排除逻辑错误。
  • Scikit-Learn 1.5.1中OneHotEncoder的sparse参数已更名为sparse_output,迁移时需注意参数名映射。

内容的提问来源于stack exchange,提问作者Hendrik Wiese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 07:22:15