ColumnTransformer 产生不同的结果
ColumnTransformer produces different results
我正在浏览 Hand-On ML with scikit-learn 一书中的 jupyter notebooks。我正在尝试挑战泰坦尼克号,但使用的是 ColumnTransformer。
我正在尝试创建预处理管道,对于数值,ColumnTransformer 会生成正确的输出。但是,在使用分类值时,我得到了一个奇怪的输出。
代码如下:
from sklearn.preprocessing import OneHotEncoder
cat_attr = ['Sex', 'Embarked', 'Pclass']
cat_pipeline = ColumnTransformer([
('cat_fill_missing', SimpleImputer(strategy='most_frequent'), cat_attr),
('cat_encoder', OneHotEncoder(sparse=False), cat_attr),
])
cat_pipeline.fit_transform(train_data)
这会产生:
array([['male', 'S', 3, ..., 0.0, 0.0, 1.0],
['female', 'C', 1, ..., 1.0, 0.0, 0.0],
['female', 'S', 3, ..., 0.0, 0.0, 1.0],
...,
['female', 'S', 3, ..., 0.0, 0.0, 1.0],
['male', 'C', 1, ..., 1.0, 0.0, 0.0],
['male', 'Q', 3, ..., 0.0, 0.0, 1.0]], dtype=object)
但是,如果我 运行 Imputer 和 OneHotEncoder 一一:
imputer = SimpleImputer(strategy='most_frequent')
filled_df = imputer.fit_transform(train_data[cat_attr])
onehot = OneHotEncoder(sparse=False)
onehot.fit_transform(filled_df)
我得到正确的编码:
array([[0., 1., 0., ..., 0., 0., 1.],
[1., 0., 1., ..., 1., 0., 0.],
[1., 0., 0., ..., 0., 0., 1.],
...,
[1., 0., 0., ..., 0., 0., 1.],
[0., 1., 1., ..., 1., 0., 0.],
[0., 1., 0., ..., 0., 0., 1.]])
这种行为背后的原因是什么?我还以为 ColumnTransformer 一一修改每一列呢
扩展评论,您作为第三个元组元素提供给 ColumnTransformer
的列应该划分数据框中的整个列集。
如果某些列重复,如您所见,结果会乱七八糟。
如果省略某些列,它们将被排除在 ColumnTransformer
.
的输出之外
例如,假设您的数据框有分类列 cat_attr
和数字列 num_attr
。
您想要对分类列应用两个转换(SimpleImputer
和 OneHotEncoder
),而不对数字列应用任何转换。
在这种情况下正确的做法是:
transformer = ColumnTransformer(transformers=[
('categorical', make_pipeline(
SimpleImputer(strategy='most_frequent'),
OneHotEncoder(sparse=False)
), cat_attr),
('numerical', 'passthrough', num_attr)
])
为作用于同一组列的所有转换创建管道,并使用特殊字符串 'passthrough'
指示不应转换另一组列。
我正在浏览 Hand-On ML with scikit-learn 一书中的 jupyter notebooks。我正在尝试挑战泰坦尼克号,但使用的是 ColumnTransformer。
我正在尝试创建预处理管道,对于数值,ColumnTransformer 会生成正确的输出。但是,在使用分类值时,我得到了一个奇怪的输出。
代码如下:
from sklearn.preprocessing import OneHotEncoder
cat_attr = ['Sex', 'Embarked', 'Pclass']
cat_pipeline = ColumnTransformer([
('cat_fill_missing', SimpleImputer(strategy='most_frequent'), cat_attr),
('cat_encoder', OneHotEncoder(sparse=False), cat_attr),
])
cat_pipeline.fit_transform(train_data)
这会产生:
array([['male', 'S', 3, ..., 0.0, 0.0, 1.0],
['female', 'C', 1, ..., 1.0, 0.0, 0.0],
['female', 'S', 3, ..., 0.0, 0.0, 1.0],
...,
['female', 'S', 3, ..., 0.0, 0.0, 1.0],
['male', 'C', 1, ..., 1.0, 0.0, 0.0],
['male', 'Q', 3, ..., 0.0, 0.0, 1.0]], dtype=object)
但是,如果我 运行 Imputer 和 OneHotEncoder 一一:
imputer = SimpleImputer(strategy='most_frequent')
filled_df = imputer.fit_transform(train_data[cat_attr])
onehot = OneHotEncoder(sparse=False)
onehot.fit_transform(filled_df)
我得到正确的编码:
array([[0., 1., 0., ..., 0., 0., 1.],
[1., 0., 1., ..., 1., 0., 0.],
[1., 0., 0., ..., 0., 0., 1.],
...,
[1., 0., 0., ..., 0., 0., 1.],
[0., 1., 1., ..., 1., 0., 0.],
[0., 1., 0., ..., 0., 0., 1.]])
这种行为背后的原因是什么?我还以为 ColumnTransformer 一一修改每一列呢
扩展评论,您作为第三个元组元素提供给 ColumnTransformer
的列应该划分数据框中的整个列集。
如果某些列重复,如您所见,结果会乱七八糟。
如果省略某些列,它们将被排除在 ColumnTransformer
.
例如,假设您的数据框有分类列 cat_attr
和数字列 num_attr
。
您想要对分类列应用两个转换(SimpleImputer
和 OneHotEncoder
),而不对数字列应用任何转换。
在这种情况下正确的做法是:
transformer = ColumnTransformer(transformers=[
('categorical', make_pipeline(
SimpleImputer(strategy='most_frequent'),
OneHotEncoder(sparse=False)
), cat_attr),
('numerical', 'passthrough', num_attr)
])
为作用于同一组列的所有转换创建管道,并使用特殊字符串 'passthrough'
指示不应转换另一组列。