sklearn SimpleImputer序列化后调用transform报RuntimeError求助
解决SimpleImputer序列化后transform报错的问题
我来帮你梳理下这个问题的原因和解决办法,这是scikit-learn 0.23.x版本里的一个常见小问题,刚好我之前也碰到过类似情况:
问题根源
在sklearn 0.23.1版本中,SimpleImputer拟合完成后,并不会自动将n_features_in_属性(用来记录训练数据的特征数量)纳入序列化的属性列表。当你用pickle保存再加载后,虽然statistics_(填充用的均值数组)能正常读取,但transform方法执行时会检查n_features_in_来验证测试集的特征数量是否和训练集一致,缺失这个属性就会抛出你看到的错误。
具体解决思路
1. 拟合后手动添加属性再保存(推荐)
在保存imputer之前,手动给它加上n_features_in_属性,值设置为训练集的特征数量:
import numpy as np from sklearn.impute import SimpleImputer import pickle # 拟合imputer imputer = SimpleImputer(missing_values=np.nan, strategy='mean') imputer = imputer.fit(train) # 手动添加n_features_in_属性 imputer.n_features_in_ = train.shape[1] # 保存到文件 pickle.dump(imputer, open('imputer.pkl', 'wb'))
这样加载后调用transform时,就能正常找到这个属性完成特征数量验证。
2. 升级scikit-learn版本(长期解决方案)
这个问题在sklearn 0.24及以后的版本中已经被官方修复了,拟合后的估计器会自动保留n_features_in_属性,序列化后也不会丢失。如果你的项目环境允许,直接升级到更高版本就能彻底解决:
pip install --upgrade scikit-learn>=0.24
3. 加载后手动补充属性(适合已保存旧模型的情况)
如果你已经有了保存好的imputer.pkl,不想重新拟合训练数据,可以在加载后手动补充这个属性(注意要确保测试集和训练集的特征数量一致):
import pickle # 加载模型 imputer = pickle.load(open('imputer.pkl', 'rb')) # 手动设置n_features_in_为训练时的特征数(比如train有8个特征就写8,或者用test.shape[1]确保匹配) imputer.n_features_in_ = test.shape[1] # 现在可以正常调用transform了 test_imputed = imputer.transform(test)
额外验证提示
你可以在加载后打印imputer.__dict__来查看所有属性,确认n_features_in_是否存在,这样能提前排查问题。
内容的提问来源于stack exchange,提问作者M Waz
相关产品推荐
相关产品推荐

