这是我的第一个机器学习项目,也是我第一次使用ColumnTransformer。我的目标是执行数据预处理的两个步骤,并对每个步骤都使用ColumnTransformer。
在第一步中,我想将数据框中缺失值替换为字符串“missing_value”,对于其余特征,使用最常见的值。因此,我使用ColumnTransformer结合相应列来组合这两种操作。
在第二步中,我想使用刚刚预处理过的数据并根据特征应用OrdinalEncoder或OneHotEncoder。为此,我再次使用ColumnTransformer。
然后将这两个步骤组合成一个单一流程。
我正在使用Kaggle房价数据集,我有scikit-learn版本0.20,以下是我的简化代码:
cat_columns_fill_miss = ['PoolQC', 'Alley']
cat_columns_fill_freq = ['Street', 'MSZoning', 'LandContour']
cat_columns_ord = ['Street', 'Alley', 'PoolQC']
ord_mapping = [['Pave', 'Grvl'], # Street
['missing_value', 'Pave', 'Grvl'], # Alley
['missing_value', 'Fa', 'TA', 'Gd', 'Ex'] # PoolQC
]
cat_columns_onehot = ['MSZoning', 'LandContour']
imputer_cat_pipeline = ColumnTransformer([
('imp_miss', SimpleImputer(strategy='constant'), cat_columns_fill_miss), # fill_value='missing_value' by default
('imp_freq', SimpleImputer(strategy='most_frequent'), cat_columns_fill_freq),
])
encoder_cat_pipeline = ColumnTransformer([
('ordinal', OrdinalEncoder(categories=ord_mapping), cat_columns_ord),
('pass_ord', OneHotEncoder(), cat_columns_onehot),
])
cat_pipeline = Pipeline([
('imp_cat', imputer_cat_pipeline),
('cat_encoder', encoder_cat_pipeline),
])
不幸的是,当我将其应用于housing_cat时,它只适用于数据框中仅包含分类特征的子集,
cat_pipeline.fit_transform(housing_cat)
我遇到了以下错误:
AttributeError: 'numpy.ndarray' object has no attribute 'columns'
在处理以上异常时,又出现了以下异常:
...
ValueError: 仅支持对pandas DataFrames使用字符串指定列
我尝试了这个简化的管道,它可以正常工作:
new_cat_pipeline = Pipeline([
('imp_cat', imputer_cat_pipeline),
('onehot', OneHotEncoder()),
])
然而,如果我尝试:
enc_one = ColumnTransformer([
('onehot', OneHotEncoder(), cat_columns_onehot),
('pass_ord', 'passthrough', cat_columns_ord)
])
new_cat_pipeline = Pipeline([
('imp_cat', imputer_cat_pipeline),
('onehot_encoder', enc_one),
])
我也开始遇到了同样的错误。
我怀疑这个错误与第二步中使用 ColumnTransformer 有关,但我实际上不理解它来自哪里。在第二步中,我标识列的方式与第一步相同,因此我仍然不清楚为什么只有在第二步中会出现 Attribute Error...
ColumnTransformer
本身,而在于转换器SimpleImputer
的输出是np.array
。因此,在下一步编码中,我无法使用列名来指示列。是这样吗?我必须使用相应的索引,是吗? - Giulia