【问题标题】:Using scikit StandardScaler in Pipeline on a subset of Pandas dataframe columns在 Pandas 数据框列的子集上的管道中使用 scikit StandardScaler
【发布时间】:2018-10-23 02:56:05
【问题描述】:

我想在 pandas 数据框列的子集上使用 sklearn.preprocessing.StandardScaler。在管道之外,这是微不足道的:

df[['A', 'B']] = scaler.fit_transform(df[['A', 'B']])

但现在假设我在 df 中具有字符串类型的列“C”和以下管道定义

from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

pipeline =  Pipeline([
                ('standard', StandardScaler())
            ])

df_scaled = pipeline.fit_transform(df)

如何告诉 StandardScaler 仅缩放 A 列和 B 列?

我习惯了 SparkML 管道,可以将要缩放的特征传递给缩放器组件的构造函数:

normalizer = Normalizer(inputCol="features", outputCol="features_norm", p=1.0)

注意:特征列包含一个稀疏向量,其中包含由 Spark 的 VectorAssembler 创建的所有数字特征列

【问题讨论】:

    标签: python pandas scikit-learn


    【解决方案1】:

    在直接 sklearn 中,您需要将 FunctionTransformerFeatureUnion 一起使用。也就是说,您的管道将如下所示:

    pipeline =  Pipeline([
                ('scale_sum', feature_union(...))
            ])
    

    在特征联合中,一个函数会将标准缩放器应用于某些列,而另一个函数将通过其他列保持不变。


    使用Ibex(我合写的正是为了让 sklearn 和 pandas 更好地工作),你可以这样写:

    from ibex.sklearn.preprocessing import StandardScaler
    from ibex import trans
    
    pipeline = (trans(StandardScaler(), in_cols=['A', 'B']) + trans(None, ['c', 'd'])) | <other pipeline steps>
    

    【讨论】:

    • 我可以确认单阶段 IBEX 可以按设计工作并保留未触及的列,但是当连接阶段时它不起作用,您能看看以下问题吗? stackoverflow.com/questions/50329184/…
    • @RomeoKienzler 谢谢,我在那里回答了你的问题。
    【解决方案2】:

    您可以查看sklearn-pandas,它提供了 Pandas DataFrame 和 sklearn 的集成,例如使用 DataFrameMapper:

    mapper = DataFrameMapper([
    ...     (list_of_columnnames, StandardScaler())
    ... ])
    

    如果你不需要外部依赖,你可以使用一个简单的自己的转换器,正如我回答的here

    class Columns(BaseEstimator, TransformerMixin):
        def __init__(self, names=None):
            self.names = names
    
        def fit(self, X, y=None, **fit_params):
            return self
    
        def transform(self, X):
            return X[self.names]
    
    pipe =  make_pipeline(Columns(names=list_of_columnnames),StandardScaler())
    

    【讨论】:

    • 我真的很难决定最终接受哪个答案。我选择了@ami Tavory 的答案,因为使用 ibex 时,语义完全符合需要(我可以指定要应用转换器的列以及在管道元素级别返回的列
    • 很公平:)。最后,这都是可行的答案和品味问题/或我猜的具体情况!
    • @MarcusV。标准缩放数据后,已发送到StandardScaler 的列将返回到管道中的下一步。如何只将一些列发送到StandardScaler,但下一步,发送剩余的列和缩放的列。
    • DataFrameMapper 可以使用参数default 设置为None,那么它们将被转发而不进行转换。对于管道,您还可以使用sklearn.compose.ColumnTransformer 或编写您自己的简单转换器,如上所示,只需在transform 中编写return X
    猜你喜欢
    • 2021-05-31
    • 2014-07-30
    • 1970-01-01
    • 2017-11-14
    • 2019-12-14
    • 2021-01-20
    • 2019-05-21
    • 2022-01-20
    • 2020-09-18
    相关资源
    最近更新 更多