Label Encoder遇未见过标签错误:全类别数据集仍报错求助
问题根源分析与解决方案
核心错误原因
你犯了一个典型的LabelEncoder使用误区:用同一个LabelEncoder实例处理多个特征列。
LabelEncoder是为单变量(比如分类任务的标签列)设计的,每次调用fit都会重置并覆盖编码器内部存储的类别映射。当你执行cv_df[encodable_columns].apply(le.fit_transform)时,apply会对每一列依次执行le.fit_transform:
- 先处理
Education列,此时le拟合了该列的4个类别; - 紧接着处理
EmploymentType列,le会重新执行fit,把之前存储的Education类别完全替换成EmploymentType的类别; - 以此类推,直到处理完最后一列
HasCoSigner,此时le内部只保留了HasCoSigner列的类别映射。
后续执行tr_df[encodable_columns].apply(le.transform)时,实际上是用HasCoSigner的类别去匹配所有列(包括Education),自然会出现"未见过的标签"错误——因为Bachelor's这类教育类别根本不在HasCoSigner的类别集合里。
正确的解决方法
方法1:为每个特征列单独创建LabelEncoder实例
用字典存储每个列对应的编码器,确保每个列的类别映射独立:
from sklearn.preprocessing import LabelEncoder import pandas as pd encodable_columns = ['Education', 'EmploymentType', 'MaritalStatus', 'HasMortgage', 'HasDependents', 'LoanPurpose', 'HasCoSigner'] encoders = {} # 处理训练集:拟合每个列的编码器并转换 for col in encodable_columns: le = LabelEncoder() tr_df[f"{col}_encoded"] = le.fit_transform(tr_df[col]) encoders[col] = le # 保存编码器 tr_df.drop(col, axis=1, inplace=True) # 处理验证集:用训练集的编码器转换 for col in encodable_columns: le = encoders[col] cv_df[f"{col}_encoded"] = le.transform(cv_df[col]) cv_df.drop(col, axis=1, inplace=True)
方法2:用OrdinalEncoder配合ColumnTransformer(更推荐)
OrdinalEncoder是sklearn专门为多特征列设计的有序编码工具,配合ColumnTransformer可以更简洁地处理多列:
from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OrdinalEncoder import pandas as pd encodable_columns = ['Education', 'EmploymentType', 'MaritalStatus', 'HasMortgage', 'HasDependents', 'LoanPurpose', 'HasCoSigner'] # 定义列转换器,仅对指定列执行编码 ct = ColumnTransformer( transformers=[ ('ordinal_enc', OrdinalEncoder(), encodable_columns) ], remainder='passthrough' # 保留其他未指定的列 ) # 拟合训练集并转换 tr_df_encoded = ct.fit_transform(tr_df) # 转换验证集(使用训练集的拟合信息) cv_df_encoded = ct.transform(cv_df) # 可选:转回DataFrame格式 tr_df = pd.DataFrame(tr_df_encoded, columns=ct.get_feature_names_out()) cv_df = pd.DataFrame(cv_df_encoded, columns=ct.get_feature_names_out())
额外说明
LabelEncoder官方文档明确建议仅用于目标变量(y),特征列的编码优先使用OrdinalEncoder或OneHotEncoder;- 无论哪种方法,都必须保证编码器只在训练集上拟合,验证集和测试集仅做转换,避免数据泄露。
内容的提问来源于stack exchange,提问作者Aditya Shandilya
相关产品推荐
相关产品推荐

