训练集缺失第46类时,如何让OneHotEncoder适配46类训练需求?
解决OneHotEncoder仅识别训练集中存在类别的问题
你的核心问题是OneHotEncoder默认只从拟合数据里识别类别,导致训练集缺失的第46类没有对应的编码位。下面给你两种直接可行的解决方法:
方法1:手动指定所有46个类别
不让编码器自动推断类别,直接把所有46个类别传给它,这样不管训练集里有没有某类,都会预留对应的编码位。
from sklearn.preprocessing import OneHotEncoder import numpy as np num_labels = 46 # 替换成你数据集里实际的46个类别标签,比如是字符串就改成['class1', 'class2', ..., 'class46'] all_categories = np.arange(num_labels) # 创建编码器时指定categories参数,handle_unknown保留ignore避免测试集报错 encoder = OneHotEncoder(categories=[all_categories], handle_unknown='ignore') # 用训练集拟合(即使缺第46类,编码器也会保留该类的编码位) encoder.fit(e_sh_train[['Label']]) # 分别对训练集和测试集编码 e_sh_train['one_hot_labels'] = list(encoder.transform(e_sh_train[['Label']]).toarray()) e_sh_test['one_hot_labels'] = list(encoder.transform(e_sh_test[['Label']]).toarray())
方法2:先在完整数据集上拟合编码器,再划分数据集
调整处理顺序,先让编码器学习完整的46个类别,再按你的规则划分训练集和测试集,这样编码维度自然是46维。
from sklearn.preprocessing import OneHotEncoder num_labels = 46 # 先在整个数据集上拟合编码器,获取所有46类的编码规则 encoder = OneHotEncoder(handle_unknown='ignore') encoder.fit(e_sh[['Label']]) # 按你的规则划分训练集和测试集(确保第46类全进测试集) # 这里假设第46类的标签值是45,替换成你实际的标签 test_mask = e_sh['Label'] == 45 e_sh_train = e_sh[~test_mask] e_sh_test = e_sh[test_mask] # 对划分后的数据集做编码 e_sh_train['one_hot_labels'] = list(encoder.transform(e_sh_train[['Label']]).toarray()) e_sh_test['one_hot_labels'] = list(encoder.transform(e_sh_test[['Label']]).toarray())
额外提醒
这两种方法都能保证编码后是46维向量,训练集中第46类对应的编码位会全为0。不过要注意,因为训练时没见过第46类样本,模型对这类的预测效果可能会很差,你可能需要后续考虑数据增强、合并相似类别或者调整划分策略来优化。
内容的提问来源于stack exchange,提问作者Niloufar Modir
相关产品推荐
相关产品推荐

