【发布时间】:2019-06-15 08:23:33
【问题描述】:
这是我的第一个机器学习项目,也是我第一次使用 ColumnTransformer。我的目标是执行两个数据预处理步骤,并为每个步骤使用 ColumnTransformer。
在第一步中,我想用字符串 'missing_value' 替换我的数据框中的缺失值,以替换某些特征,并用最常见的值替换其余特征。因此,我使用 ColumnTransformer 将这两个操作结合起来,并将我的数据帧的相应列传递给它。
在第二步中,我想使用刚刚预处理的数据,并根据功能应用 OrdinalEncoder 或 OneHotEncoder。为此,我再次使用 ColumnTransformer。
然后我将这两个步骤合并到一个管道中。
我正在使用 Kaggle Houses Price 数据集,我有 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' 对象没有属性 '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有关,但我实际上不明白它来自哪里。我在第二步中识别列的方式与第一步相同,所以我仍然不清楚为什么只在第二步中我得到属性错误...
【问题讨论】:
标签: python pandas scikit-learn pipeline transformer