测试集存在新类别时,如何在Pipeline中使用Ordinal Encoding处理分类特征
错误原因
你在OrdinalEncoder中设置了unknown_value=np.nan,编码遇到测试集未知类别时会输出NaN值,而scikit-learn 1.3版本之前的DecisionTreeRegressor不支持直接输入包含NaN的特征,这是报错的核心原因,和你筛选分类列的操作没有关系,OrdinalEncoder本身的类型转换逻辑是正常的。
可行的解决方法
方法1:升级scikit-learn到1.3及以上版本
该版本开始,决策树、随机森林等原生树模型已经支持缺失值输入,你现有代码不需要做任何修改即可正常运行。
方法2:在Pipeline中补充缺失值处理步骤
如果暂时不想升级依赖,可以在OrdinalEncoder之后增加缺失值填充环节,示例代码如下:
from sklearn.impute import SimpleImputer oe = make_column_transformer( (OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=np.nan), cate_cols), remainder='passthrough' ) dt_reg = DecisionTreeRegressor() # 新增SimpleImputer步骤,可根据业务需求选择均值、中位数、众数等填充策略 model = make_pipeline(oe, SimpleImputer(strategy='most_frequent'), dt_reg) cv_results = cross_val_score(model, X, y, cv=5, scoring=scoring)
方法3:将未知类别映射为特殊常量值
不想引入NaN的话,可以把未知类别的编码值设为超出所有已知类别编码范围的整数,不需要额外处理缺失值:
# 计算所有分类列的最大类别数量,作为未知类别的专属编码 max_cate_count = max(X[col].nunique() for col in cate_cols) oe = make_column_transformer( (OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=max_cate_count), cate_cols), remainder='passthrough' ) model = make_pipeline(oe, DecisionTreeRegressor()) cv_results = cross_val_score(model, X, y, cv=5, scoring=scoring)
内容的提问来源于stack exchange,提问作者haneulkim
相关产品推荐
相关产品推荐

