如何将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
相关产品推荐
相关产品推荐

