使用Pickle加载LabelEncoder时出现‘SF为未见过标签’错误的问询
问题排查:ValueError: y contains previously unseen labels: 'SF'
我来帮你拆解这个问题的根源,你遇到的报错其实是因为你的encoder函数里有两个关键逻辑错误,咱们一步步说:
错误原因
1. 重复调用fit_transform覆盖了编码器的标签映射
你在代码里对训练集和测试集都执行了le.fit_transform:
train_cat = cat_train.apply(le.fit_transform) test_cat = cat_test.apply(le.fit_transform)
LabelEncoder的fit方法会重新学习并覆盖当前的标签映射关系。第二次对测试集的fit操作,会把之前从训练集学到的标签(包括SF)完全替换成测试集的标签集合。最后你保存的le是仅在测试集上训练过的版本,自然识别不了训练集里的SF标签。
2. 测试集编码结果的赋值错误
你创建测试集编码后的DataFrame时犯了笔误:
encs_test = pd.DataFrame(train_cat, columns=cols)
这里应该用test_cat而不是train_cat,否则你的测试集编码结果完全是训练集的内容,不仅逻辑错误,还会导致后续测试集的处理完全失效。
修正后的代码
核心原则是:只在训练集上训练(fit)编码器,测试集仅使用训练好的编码器做转换(transform)。修正后的encoder函数如下:
def encoder(sc_train, sc_test): le = LabelEncoder() cols = sc_train.select_dtypes(include=['object']).columns # 提取训练集和测试集的分类属性 cat_train = sc_train.select_dtypes(include=['object']).copy() cat_test = sc_test.select_dtypes(include=['object']).copy() # 仅在训练集上完成fit+transform,测试集直接用训练好的编码器转换 train_cat = cat_train.apply(lambda x: le.fit_transform(x)) # 注意:测试集只能用transform,不能再fit! test_cat = cat_test.apply(lambda x: le.transform(x)) # 修正测试集DataFrame的赋值 encs_train = pd.DataFrame(train_cat, columns=cols) encs_test = pd.DataFrame(test_cat, columns=cols) # 保存基于训练集训练完成的编码器 pickle_filename = open("encoder2.pkl","wb") pickle.dump(le, pickle_filename) pickle_filename.close() return encs_train, encs_test
补充说明
如果你的数据集里不同分类列的标签集合不一样,建议为每个分类列单独创建一个LabelEncoder(可以用字典存储每个列对应的编码器),避免不同列的标签互相干扰。不过如果所有分类列的标签集合一致,上面的代码就可以正常工作。
内容的提问来源于stack exchange,提问作者Abdulla Ahli
相关产品推荐
相关产品推荐

