混合类型的列变换器

Beginner

This tutorial is from open-source community. Access the source code

简介

本实验展示了如何使用 ColumnTransformer 将不同的预处理和特征提取管道应用于不同的特征子集。对于包含异构数据类型的数据集来说,这特别方便,因为我们可能想要缩放数值特征并对分类特征进行独热编码。

在本实验中,我们将使用来自 OpenML 的泰坦尼克号数据集来构建一个管道,该管道使用 ColumnTransformer 对分类数据和数值数据进行预处理,并使用该管道训练逻辑回归模型。

虚拟机使用提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,可以随时向 Labby 提问。课程结束后提供反馈,我们会及时为你解决问题。

导入库

在这一步中,我们将导入构建管道所需的库。

import numpy as np
from sklearn.compose import ColumnTransformer
from sklearn.datasets import fetch_openml
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, RandomizedSearchCV
from sklearn.feature_selection import SelectPercentile, chi2

加载数据集

在这一步中,我们将使用 fetch_openml 从 OpenML 加载泰坦尼克号数据集。

X, y = fetch_openml(
    "titanic", version=1, as_frame=True, return_X_y=True, parser="pandas"
)

定义数值型和类别型特征

在这一步中,我们将定义在管道中会用到的数值型和类别型特征。我们还将为数值型和类别型数据定义预处理管道。

numeric_features = ["age", "fare"]
numeric_transformer = Pipeline(
    steps=[("imputer", SimpleImputer(strategy="median")), ("scaler", StandardScaler())]
)

categorical_features = ["embarked", "sex", "pclass"]
categorical_transformer = Pipeline(
    steps=[
        ("encoder", OneHotEncoder(handle_unknown="ignore")),
        ("selector", SelectPercentile(chi2, percentile=50)),
    ]
)

定义数据预处理步骤

在这一步中,我们将定义用于预处理数据的 ColumnTransformer

preprocessor = ColumnTransformer(
    transformers=[
        ("num", numeric_transformer, numeric_features),
        ("cat", categorical_transformer, categorical_features),
    ]
)

将分类器添加到预处理管道

在这一步中,我们将使用 Pipeline 将逻辑回归分类器添加到我们的预处理管道中。

clf = Pipeline(
    steps=[("preprocessor", preprocessor), ("classifier", LogisticRegression())]
)

划分数据

在这一步中,我们将使用 train_test_split 把数据划分为训练集和测试集。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

拟合管道

在这一步中,我们将把管道拟合到训练数据上。

clf.fit(X_train, y_train)

评估管道

在这一步中,我们将通过计算模型得分来评估管道的性能。

print("model score: %.3f" % clf.score(X_test, y_test))

通过数据类型选择列来使用 ColumnTransformer

在这一步中,我们将通过按数据类型选择列来使用 ColumnTransformer。我们将使用 make_column_selector 根据数据类型选择列。

from sklearn.compose import make_column_selector as selector

subset_feature = ["embarked", "sex", "pclass", "age", "fare"]
X_train, X_test = X_train[subset_feature], X_test[subset_feature]

preprocessor = ColumnTransformer(
    transformers=[
        ("num", numeric_transformer, selector(dtype_exclude="category")),
        ("cat", categorical_transformer, selector(dtype_include="category")),
    ]
)
clf = Pipeline(
    steps=[("preprocessor", preprocessor), ("classifier", LogisticRegression())]
)

使用网格搜索调整超参数

在这一步中,我们将使用网格搜索来调整管道的超参数。

param_grid = {
    "preprocessor__num__imputer__strategy": ["mean", "median"],
    "preprocessor__cat__selector__percentile": [10, 30, 50, 70],
    "classifier__C": [0.1, 1.0, 10, 100],
}

search_cv = RandomizedSearchCV(clf, param_grid, n_iter=10, random_state=0)
search_cv.fit(X_train, y_train)

print("Best params:")
print(search_cv.best_params_)
print(f"Internal CV score: {search_cv.best_score_:.3f}")

总结

在这个实验中,我们学习了如何使用 ColumnTransformer 在管道中预处理分类数据和数值数据,以及如何使用网格搜索来调整管道的超参数。