我正在关注 Aurelion Geron 的机器学习书籍。
我正在试验 ColumnTransformer
类。当我包含 SimplerImputer
时,会创建一个额外的列。我知道 SimplerImputer
用于填充 total_bedrooms
列(结果中的列索引 4)中的缺失值,因此我不清楚它为什么要添加新列(列索引: 10) 结果。
当我不包括
ColumnTransformer
中的 SimplerImputer
,但是创建一个实例,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
并行应用其更改器(mutator),而不是顺序应用(另请参阅 [1] 、 [2] ),因此如果一个列被传递给多个更改器(mutator),您最终会在输出。在你的例子中,输出第 4 列来自 total_bedrooms
上的 "adder"
(它什么也没做,所以仍然有缺失值),输出第 10 列来自 "imputer"
(因此不会有缺失值)。
修复
在这种特殊情况下,两种方法似乎是最简单的。
归因于一切
任何没有缺失的数字特征都不会受到影响。但是,如果您希望管道在包含缺失值的 future 数据上出错,则不要这样做。
num_pipe = Pipeline([
("add_feat", AttributeAdder()),
("impute", SimpleImputer(strategy="median")),
])
transformer = ColumnTransformer(
[
('num', num_pipe, num_att),
('cat', OneHotEncoder(), category_att),
],
remainder = 'passthrough',
)
较小的变压器柱组
因为您的 AttributeAdder
实际上不需要您的 total_bedrooms
列,所以您不需要将它传递到该转换器中。具体细节取决于您如何使用 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
以返回仅新功能(不要在 transform
的最后一步连接到 X
),并依靠 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
)
关于python - 为什么 ColumnTransformer 中的 SimpleImputer 会创建额外的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67250392/