回归任务中集成RareLabelEncoder的Sklearn Pipeline报错ValueError: could not convert string to float: 'Rare'的解决方案咨询
解决ValueError: could not convert string to float: 'Rare'的问题
错误原因
你踩了sklearn ColumnTransformer的一个常见坑——并行处理逻辑。现在的代码里,brand和model被同时交给了两个转换器:RareLabelEncoder和MeanEncoder。ColumnTransformer的工作方式是对不同列组独立处理,然后把所有结果拼接在一起,这就导致brand和model会以两种形式出现在输出里:
- 经过
RareLabelEncoder处理后的字符串列(包含'Rare'标记) - 直接用原始数据经过
MeanEncoder处理后的数值列
当后续的StandardScaler试图对这些字符串列做标准化时,自然就抛出了无法转成浮点数的错误。
修复方案
正确的思路是对高基数列顺序执行稀有类别归并和均值编码,把这两步做成一个子流水线,而不是并行处理。这样高基数列只会输出最终的数值编码结果,不会留下字符串类型的中间产物。
修改后的完整代码如下:
from sklearn.compose import make_column_transformer from sklearn.preprocessing import StandardScaler from sklearn.pipeline import make_pipeline from sklearn.linear_model import LinearRegression from feature_engine.encoding import RareLabelEncoder, MeanEncoder, OrdinalEncoder from feature_engine.transformation import BoxCoxTransformer, PowerTransformer high_card_cols = ['brand', 'model', 'location'] cat_cols = ['fuel_type', 'transmission', 'is_first_owner'] # 子流水线:先归并稀有类别,再做均值编码 high_card_pipeline = make_pipeline( RareLabelEncoder(n_categories=9), MeanEncoder() ) processor = make_column_transformer( (high_card_pipeline, high_card_cols), # 用子流水线统一处理所有高基数列 (OrdinalEncoder(), cat_cols), (PowerTransformer(), ['milage_kmpl']), (BoxCoxTransformer(), ['kilometers_driven', 'engine', 'power']), remainder="passthrough" ) # 模型流水线保持不变 lr_pipe = make_pipeline( processor, StandardScaler(), LinearRegression() ) lr_pipe.fit(X_train, y_train.price)
额外注意事项
- BoxCoxTransformer的限制:BoxCox要求输入列必须是严格大于0的数值,如果
kilometers_driven、engine或power存在0或负数,需要先做偏移处理(比如加一个小正数),或者换成PowerTransformer的yeo-johnson模式(不需要严格正数)。 - 均值编码过拟合风险:直接用MeanEncoder容易导致过拟合,建议设置
cv参数做交叉验证编码,比如MeanEncoder(cv=5),这样能有效降低训练集上的过拟合问题。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

