使用scikit-learn预处理连续和分类(整数类型)变量的特征

21
主要目标如下:
  1. 对连续变量应用StandardScaler

  2. 对分类变量应用LabelEncoderOnehotEncoder

需要对连续变量进行缩放,但同时也有几个分类变量是整数类型的。应用StandardScaler将产生不良影响。

相反,StandardScaler将缩放基于整数的分类变量,这也不是我们想要的。

由于连续变量和分类变量混合在单个Pandas数据框中,因此应采取什么样的工作流程来解决这种问题?

最好的例子是Kaggle自行车共享需求数据集,其中seasonweather是整数分类变量。


1
由于StandardScalar是按列处理的,我认为它不会对独热编码变量产生任何影响。你尝试过对单个数据框执行上述操作吗?你是否找到了你似乎遇到的问题的原因? - Vivek Kumar
独热编码变量与整数类型的变量完全相同。如果将它们连接在一起,为什么期望它们会有不同的行为呢?如果它们的行为方式相同,那么如果存在一个既非分类变量又是数值型变量,并且其值为1或0,然后对其使用缩放器,你认为会发生什么? - James Wong
2
我尝试过了,显然它会缩放所有值,无论它们取什么值。你能否在那个Bike数据集上应用StandardScaler().fit_transform(df)并告诉我结果如何? - James Wong
2
哦,对不起,我搞混了MinMaxScaler和StandardScaler。MinMaxScaler不会改变1、0,但是StandardScaler会(零均值和单位方差)。再次抱歉。 - Vivek Kumar
你可以使用http://scikit-learn.org/stable/auto_examples/hetero_feature_union.html#sphx-glr-auto-examples-hetero-feature-union-py作为一个示例来合并不同的特征。 - Vivek Kumar
@VivekKumar 没关系。我非常感激你指出这两者之间的差异。FeatureUnion看起来很有前途。我以前不知道,一定会仔细研究。 :) - James Wong
2个回答

27

查看sklearn_pandas.DataFrameMapper元转换器。将其用作管道中的第一步,执行逐列数据工程操作:

mapper = DataFrameMapper(
  [(continuous_col, StandardScaler()) for continuous_col in continuous_cols] +
  [(categorical_col, LabelBinarizer()) for categorical_col in categorical_cols]
)
pipeline = Pipeline(
  [("mapper", mapper),
  ("estimator", estimator)]
)
pipeline.fit_transform(df, df["y"])

另外,你应该使用 sklearn.preprocessing.LabelBinarizer 而不是一个由 [LabelEncoder(), OneHotEncoder()] 组成的列表。


2
sklearn_pandas.DataFrameMapper非常棒,绝对值得一试。感谢您让我知道它。但是根据文档,LabelBinarizer应该在目标变量具有多个值的情况下使用,而不是每个变量都具有一组不同值的情况下使用,对吗?不知道我是否表达清楚了。 - James Wong
LabelBinarizer 是编码字符串列的正确选择 - 它首先将字符串转换为整数,然后将这些整数二进制化为位向量。它一次性完成所有操作。无需在两个转换器步骤(即 LabelEncoderOneHotEncoder)之间分割此“工作流程”。只需使用真实数据尝试一下,您就会喜欢上它。 - user1808924
这里的“estimator”具体是什么意思? - tbone
1
在Scikit-Learn管道的上下文中,管道的最后一步,也称为“final_estimator”,是某种模型 - 回归器或分类器。 - user1808924

3
检查scikit-learn中的ColumnTransformer。
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler,LabelBinarizer

numeric_columns=list(X.select_dtypes('float64').columns)
categorical_columns=list(X.select_dtypes('int64').columns)

pipeline=ColumnTransformer([
    ('num',StandardScaler(),numeric_columns),
    ('cat',LabelBinarizer(),categorical_columns),
])

new_X=pipeline.fit_transform(X)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接