机器学习One Hot Encoding使用求助:类别特征编码后维度不匹配
解决方案:类别型特征转数值型适配sklearn模型
问题原因
你原代码报错的核心是OneHotEncoder会将每个类别特征拆分为多个二进制列,比如原类别列里的State-gov/Private这类特征会被拆成对应类别数量的列,编码后数组的列数远大于原类别列的8列,自然无法直接赋值回原数组的对应位置。
可行方案
方案1:使用ColumnTransformer(sklearn推荐)
这是最规范的做法,能自动区分数值列和类别列,分别处理后合并成最终特征矩阵,无需手动拼接。
import numpy as np from sklearn.preprocessing import OneHotEncoder from sklearn.compose import ColumnTransformer from sklearn.preprocessing import StandardScaler # 数值列可选标准化,按需添加 # 定义类别列和数值列索引 cat_columns = [1, 5, 6, 7, 8, 9, 13, 14] num_columns = [col for col in range(train.shape[1]) if col not in cat_columns] # 构建转换器:数值列可选择标准化,类别列用OneHot编码 preprocessor = ColumnTransformer( transformers=[ ('num', StandardScaler(), num_columns), # 若不需要标准化,替换为'passthrough' ('cat', OneHotEncoder(sparse_output=False, drop='first'), cat_columns) # drop='first'避免多重共线性,可选 ]) # 拟合并转换训练集 train_processed = preprocessor.fit_transform(train)
方案2:手动拆分+拼接
手动分离数值列和类别列,编码类别列后与数值列横向拼接,灵活可控。
import numpy as np from sklearn.preprocessing import OneHotEncoder cat_columns = [1, 5, 6, 7, 8, 9, 13, 14] num_columns = [col for col in range(train.shape[1]) if col not in cat_columns] # 提取数值列和类别列 train_num = train[:, num_columns] train_cat = train[:, cat_columns] # 编码类别列 ohe = OneHotEncoder(sparse_output=False, drop='first') train_cat_encoded = ohe.fit_transform(train_cat) # 拼接数值列和编码后的类别列(注意先转成float类型,避免类型不兼容) train_processed = np.hstack([train_num.astype(np.float64), train_cat_encoded])
方案3:OrdinalEncoder(仅适用于有序类别特征)
如果你的类别特征是有序的(比如学历:小学<初中<高中),可以用OrdinalEncoder将每个类别映射为单一整数,不会增加列数。但注意无序类别(比如职业、国籍)用这个会引入不合理的顺序关系,不推荐。
from sklearn.preprocessing import OrdinalEncoder cat_columns = [1, 5, 6, 7, 8, 9, 13, 14] oe = OrdinalEncoder() train[:, cat_columns] = oe.fit_transform(train[:, cat_columns])
补充说明
- 关于最后一列(预测目标):你提到后续会拆分,建议先把这一列从特征矩阵中分离出来,单独作为标签处理,避免被编码:
# 分离特征和标签(假设最后一列是标签列) X_train = train[:, :-1] y_train = train[:, -1]
然后再对X_train执行上述特征处理流程。
内容的提问来源于stack exchange,提问作者vito
相关产品推荐
相关产品推荐

