python - 为什么 ColumnTransformer 中的 SimpleImputer 会创建额外的列?
问题描述
我正在关注 Aurelion Geron 的机器学习书。
我正在尝试ColumnTransformer
上课。当我包含SimplerImputer
时,创建了一个额外的列。我知道这SimplerImputer
是为了填充列中的缺失值total_bedrooms
(结果中的列索引 4),因此我不清楚它为什么要在结果中添加新列(列索引:10)。
当我不包括SimplerImputer
from ColumnTransformer
,但创建一个实例和fit_transform
的输出时ColumnTransformer
,我不会得到额外的列。请指教。
category_att = X.select_dtypes(include='object').columns
num_att = X.select_dtypes(include='number').columns
transformer = ColumnTransformer(
[
('adder', AttributeAdder(), num_att ),
('imputer', SimpleImputer(strategy='median'), ['total_bedrooms']),
('ohe', OneHotEncoder(), category_att)
],
remainder = 'passthrough'
)
用于添加两个新功能/列的自定义类
class AttributeAdder(BaseEstimator, TransformerMixin):
def __init__(self, add_bed_room = False):
self.add_bed_room = add_bed_room
def fit(self,y=None):
return self
def transform(self,X,y=None):
room_per_household = X.iloc[: , t_room ] / X.iloc[: , t_household ]
population_per_household = X.iloc[: , t_population ] / X.iloc[: , t_household ]
return np.c_[X,room_per_household,population_per_household]
解决方案
为什么
不SimpleImputer
完全是;它ColumnTransformer
本身。 ColumnTransformer
并行应用其转换器,而不是顺序应用(另请参见[1],[2]),因此如果一列被传递给多个转换器,您将在输出中多次使用该列。在您的情况下,输出第 4 列来自"adder"
on total_bedrooms
(它什么也没做,所以仍然有缺失值),输出第 10 列来自"imputer"
(因此没有缺失值)。
修复
在这种特殊情况下,两种方法似乎是最简单的。
归咎于一切
任何没有缺失的数字特征都不会受到影响。但是,如果您希望管道对具有缺失值的未来数据出错,请不要这样做。
num_pipe = Pipeline([
("add_feat", AttributeAdder()),
("impute", SimpleImputer(strategy="median")),
])
transformer = ColumnTransformer(
[
('num', num_pipe, num_att),
('cat', OneHotEncoder(), category_att),
],
remainder = 'passthrough',
)
较小的变压器柱组
由于您实际上并不需要您的total_bedrooms
列,AttributeAdder
因此您无需将其传递到该变压器中。具体情况取决于您如何使用t_rooms
,t_households
等,但通常:
transformer = ColumnTransformer(
[
('adder', AttributeAdder(), [["total_rooms", "households", "population"]]),
('imputer', SimpleImputer(strategy='median'), ['total_bedrooms']),
('ohe', OneHotEncoder(), category_att)
],
remainder = 'passthrough' # now you're relying on this one much more
)
在相关方法中,您可以更灵活地计算添加的特征。更改您以仅AttributeAdder
返回新功能(不要在 的最后一步中连接),并依靠来传递这些功能。(请注意,我们不能依赖这些,但我们可以将其用作变压器之一。)X
transform
ColumnTransformer
remainder
"passthrough"
class AttributeAdder(BaseEstimator, TransformerMixin):
...
def transform(self,X,y=None):
...
return np.c_[room_per_household,population_per_household]
transformer = ColumnTransformer(
[
('adder', AttributeAdder(), num_att),
('num', "passthrough", num_att.drop(['total_bedrooms'])),
('imputer', SimpleImputer(strategy='median'), ['total_bedrooms']),
('ohe', OneHotEncoder(), category_att)
],
passthrough=True, # if you have columns in neither of num_att and category_att that you want kept
)
推荐阅读
- c# - 如何在 jsonb 上作为 jsondocument 进行全文搜索
- apache - Mod_rewrite:在重定向到新 URL 时丢弃 URL 中的第一个字符串,同时保留所有其他字符串
- java - 如何使用 --patch-module java 选项在 JDK9+ 上使 Eclipse RUN 修补过的 JRE 模块
- azure - 在 KQL 中解析 Json 数组
- reactjs - 反应错误显示在控制台而不是窗口中
- javascript - DT::datatable - 选择要删除的行并写入没有闪亮的 csv
- javascript - 如何在没有表单且不出现错误 400 的情况下发出发布请求
- python - 在 Netty 中解码 PUT 请求
- docker - 通过 crontab 运行“docker run”命令不起作用
- xml - 尝试将 StaxSource 转换为 StreamResult 时,Xml Transformer 给我一个错误