Sklearn 管道保持 ID 列不变

Sklearn pipeline keep in ID column untouched

我正在尝试将我的不同管道全部部署到一个具有联合功能的管道中,除一个问题外一切正常。

在我的 DataFrame 中,我有一个列 ID,我想在所有管道中保持不变。 我必须将它交给管道,因为我应用了一些热编码和其他东西,我不能在最后将它合并回去。

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer

scaler_pipeline = Pipeline([
    ('selector', DataFrameSelector(col_scalar)),
    ('imputer', SimpleImputer(strategy="median")),
    ('std_scaler', StandardScaler())
])
one_hot_pipeline = Pipeline([
    ('selector', DataFrameSelector(col_one_hot)),
    ('imputer', SimpleImputer(strategy="most_frequent")),
    ('one_hot', OneHotEncoder())
])

  full_pipeline = FeatureUnion(transformer_list=[
    ("DataFrameSelector", DataFrameSelector(immutable_col)),
    ("scaler_pipeline", scaler_pipeline),
    ("one_hot_pipeline", one_hot_pipeline),
])

我的 DataFrameSelector 就是这样的:

class DataFrameSelector(BaseEstimator, TransformerMixin):
    def __init__(self, attribute_names):
        self.attribute_names = attribute_names

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        return X[self.attribute_names]

在“full_pipeline”的开头,我想select一些列(这里是ID),只是保留它而不去碰它。

现在我得到这个错误

TypeError: no supported conversion for types: (dtype('O'), dtype('float64'), dtype('float64'))

您可以将 ColumnTransformerremainder='passthrough' 结合使用,使转换器适合选定的列,而其他列保持不变。

scaler_pipeline = Pipeline([
    ('imputer', SimpleImputer(strategy="median")),
    ('std_scaler', StandardScaler())
])

one_hot_pipeline = Pipeline([
    ('imputer', SimpleImputer(strategy="most_frequent")),
    ('one_hot', OneHotEncoder())
])

selector = ColumnTransformer([
    ('scalar', scaler_pipeline, col_scalar),
    ('one_hot', one_hot_pipeline, col_one_hot)
], remainder='passthrough')

请注意,如果 ID 以外的任何列不在 immutable_colcol_scalar 中,您需要在适合之前删除它们。

或者,您可以为 ID 列创建直通转换器并删除其他列:

selector = ColumnTransformer([
    ('scalar', scaler_pipeline, col_scalar),
    ('one_hot', one_hot_pipeline, col_one_hot), 
    ('passthough', FunctionTransformer(lambda x: x, lambda x: x), ['ID'])
], remainder='drop')