在 Pandas 数据框列的子集上的管道中使用 scikit StandardScaler
Posted
技术标签:
【中文标题】在 Pandas 数据框列的子集上的管道中使用 scikit StandardScaler【英文标题】:Using scikit StandardScaler in Pipeline on a subset of Pandas dataframe columns 【发布时间】: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 创建的所有数字特征列
【问题讨论】:
【参考方案1】:在直接 sklearn 中,您需要将 FunctionTransformer
与 FeatureUnion
一起使用。也就是说,您的管道将如下所示:
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 可以按设计工作并保留未触及的列,但是当连接阶段时它不起作用,您能看看以下问题吗? ***.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
。以上是关于在 Pandas 数据框列的子集上的管道中使用 scikit StandardScaler的主要内容,如果未能解决你的问题,请参考以下文章
Python pandas,使用 .str.contains 搜索数据框列的子字符串时出错