gpt4 book ai didi

python - 将 ColumnTransformer 用于管道时出现 AttributeError

转载 作者:太空宇宙 更新时间:2023-11-03 14:39:48 24 4
gpt4 key购买 nike

这是我的第一个机器学习项目,也是我第一次使用 ColumnTransformer。我的目标是执行两步数据预处理,并为每一步使用 ColumnTransformer。

在第一步中,我想用字符串 'missing_value' 替换我的数据框中的某些特征的缺失值,以及其余特征的最常见值。因此,我使用 ColumnTransformer 将这两个操作结合起来,并将数据框的相应列传递给它。

在第二步中,我想使用刚刚预处理的数据并根据特征应用 OrdinalEncoder 或 OneHotEncoder。为此,我再次使用 ColumnTransformer。

然后我将这两个步骤合并到一个管道中。

我使用的是 Kaggle Houses 价格数据集,我有 scikit-learn 版本 0.20,这是我的代码的简化版本:

cat_columns_fill_miss = ['PoolQC', 'Alley']
cat_columns_fill_freq = ['Street', 'MSZoning', 'LandContour']
cat_columns_ord = ['Street', 'Alley', 'PoolQC']
ord_mapping = [['Pave', 'Grvl'], # Street
['missing_value', 'Pave', 'Grvl'], # Alley
['missing_value', 'Fa', 'TA', 'Gd', 'Ex'] # PoolQC
]
cat_columns_onehot = ['MSZoning', 'LandContour']


imputer_cat_pipeline = ColumnTransformer([
('imp_miss', SimpleImputer(strategy='constant'), cat_columns_fill_miss), # fill_value='missing_value' by default
('imp_freq', SimpleImputer(strategy='most_frequent'), cat_columns_fill_freq),
])

encoder_cat_pipeline = ColumnTransformer([
('ordinal', OrdinalEncoder(categories=ord_mapping), cat_columns_ord),
('pass_ord', OneHotEncoder(), cat_columns_onehot),
])

cat_pipeline = Pipeline([
('imp_cat', imputer_cat_pipeline),
('cat_encoder', encoder_cat_pipeline),
])

不幸的是,当我将它应用于 housing_cat 时,我的数据框的子集仅包含分类特征,

cat_pipeline.fit_transform(housing_cat)

我得到错误:

AttributeError: 'numpy.ndarray' object has no attribute 'columns'

During handling of the above exception, another exception occurred:

...

ValueError: Specifying the columns using strings is only supported for pandas DataFrames

我已经尝试过这个简化的管道并且它工作正常:

new_cat_pipeline = Pipeline([
('imp_cat', imputer_cat_pipeline),
('onehot', OneHotEncoder()),
])

但是,如果我尝试:

enc_one = ColumnTransformer([
('onehot', OneHotEncoder(), cat_columns_onehot),
('pass_ord', 'passthrough', cat_columns_ord)
])

new_cat_pipeline = Pipeline([
('imp_cat', imputer_cat_pipeline),
('onehot_encoder', enc_one),
])

我开始遇到同样的错误。

然后我怀疑这个错误与第二步中使用ColumnTransformer有关,但我实际上不明白它来自哪里。我在第二步中识别列的方式与第一步中的相同,所以我仍然不清楚为什么只在第二步中我得到属性错误...

最佳答案

ColumnTransformer 返回 numpy.array,因此它不能具有列属性(如您的错误所示)。

如果我可以建议不同的解决方案,请使用 pandas 来完成您的两个任务,这样会更容易。

第 1 步 - 替换缺失值

要用 missing_value 字符串替换列子集中的缺失值,请使用:

dataframe[["PoolQC", "Alley"]].fillna("missing_value", inplace=True)

对于其余部分(用每列的平均值进行估算),这将完美地工作:

dataframe[["Street", "MSZoning", "LandContour"]].fillna(
dataframe[["Street", "MSZoning", "LandContour"]].mean(), inplace=True
)

第 2 步 - 一个热编码和分类变量

pandas 提供了get_dummies,返回pandas Dataframe,不像ColumnTransfomer,代码是:

encoded = pd.get_dummies(dataframe[['MSZoning', 'LandContour']], drop_first=True)
pd.dropna(['MSZoning', 'LandContour'], axis=columns, inplace=True)
dataframe = dataframe.join(encoded)

对于序数变量及其编码,我建议您查看 at this SO answer (不幸的是,在这种情况下需要一些手动映射)。

如果你还是想使用transformer

使用 values 属性从数据框中获取 np.array,通过管道传递它并从数组中重新创建列和索引,如下所示:

pd.DataFrame(data=your_array, index=np.arange(len(your_array)), columns=["A", "B"])

虽然有一个关于这种方法的警告;您不会知道自定义创建的单热编码列的名称(管道不会为您执行此操作)。

此外,您可以从 sklearn 的转换对象中获取列的名称(例如使用 categories_ 属性),但我认为这会破坏管道(如果我错了请纠正我)。

关于python - 将 ColumnTransformer 用于管道时出现 AttributeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54298550/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com