使用 ColumnTransformer 和 OneHotEncoder 进行预测

2025 年 6 月 13 日 | 阅读 8 分钟

在本教程中,我们将构建一个二元分类模型,该模型将根据客户的年龄、性别、收入和城市来预测客户是否会购买汽车。我们将展示如何使用 ColumnTransformer 和 OneHotEncoder 分别处理数值和分类数据,以及如何使用 Pipeline 简化预处理和建模。

我们将研究数据准备、模型训练、评估以及在实际场景中的应用。此外,我们还将演示如何存储管道并在未来使用它。这种方式可以使 机器学习 工作流保持整洁、模块化,并为实际部署做好准备。

概述

通常,在 scikit-learn 中进行数据预处理时,经常会用到 ColumnTransformer 和 OneHotEncoder。使用这些工具,您可以同时处理数值和分类特征,从而使预处理变得容易。

  • ColumnTransformer 可以为不同类型的特征实现不同的转换。
  • OneHotEncoder 将分类特征转换为二元列,以便模型进行解释。

我们将它们在一个管道中堆叠使用,以确保训练和预测的流程具有导向性、可重复性和组织性。

样本数据集

我们将使用一个小数据集来完成这个二元分类任务。

  • 这里,“购买”是我们的目标变量。
  • 客户购买汽车 = 1
  • 客户未购买 = 0

使用 OneHotEncoder 进行分类编码

在使用模型之前,我们确保将这些分类变量(例如性别和城市)转换为数值形式。这些工具使用 OneHotEncoder 将它们转换为二元的虚拟集合。

例如

示例输出

 
[[0. 1. 0.]
 [1. 0. 0.]
 [1. 0. 0.]
]

在图示中,每个城市都由一个包含 1/0 值的列表示。

使用 ColumnTransformer 进行预处理

通过 ColumnTransformer,我们可以为每一列指定其独特的预处理步骤。

我们将

  • 拟合 OneHotEncoder 对象到性别和城市特征。
  • 使用 StandardScaler 来缩放年龄和收入的值。

构建管道

我们使用 Pipeline 类将预处理与模型链接起来。这意味着我们的代码将更清晰、更高效。

划分和训练部分

数据集将被划分为训练数据和测试数据,我们将使用训练数据来训练模型。

进行预测

学习完成后,我们就可以预测测试样本的结果了。

示例输出

 
Predictions: [1 0]

模型评估

通过准确率和分类报告查看结果。

示例输出

 
Accuracy: 1.0

Classification Report:
              precision    recall  f1-score   support

           0       1.00      1.00      1.00         1
           1       1.00      1.00      1.00         1

    accuracy                           1.00         2
   macro avg       1.00      1.00      1.00         2
weighted avg       1.00      1.00      1.00         2

处理缺失值

我们也可以在管道处理过程中替换缺失值。

这确保了所有缺失值在编码或缩放之前都被处理。

使用保存和加载管道

您可以使用 joblib 保存管道并稍后重用它。

Scikit-learn 中 ColumnTransformer 的使用指南

使用 scikit-learn 的 ColumnTransformer,您可以只预处理数据集中特定的列。当您决定分别处理数值型和分类型特征时,它非常方便。

基本语法

ColumnTransformer 组合了多个转换器,其中每一个都是一个三元组。

对于 ColumnTransformer 中的每个转换器,都使用一个包含三个元素的元组。首先需要定义一个名称作为转换器的标签。转换器指的是您将使用的预处理函数,例如 OneHotEncoder 或 SimpleImputer。Columns 指示转换器要在哪个列(按索引或名称)上执行操作。

示例 1:对数据中的类别使用 OneHotEncoder

对于这个示例,第 0 列和第 1 列由 OneHotEncoder 处理。

示例 2:尝试对包含数字和文本的列使用不同的 Imputer

第 0 列和第 1 列中的数字用中位数填充,而分类列 2 和 3 则用最常见的值替换。

处理剩余的列

默认情况下,未在转换器中列出的所有列都将从数据中删除。要让它们保持不变,请使用

该方法实际上会对第 2 列和第 3 列进行编码,而将其他所有内容保持不变。

利用 Transformer

您可以立即在您的数据上使用 Transformer。

与 Pipeline 协同工作

ColumnTransformer 应该作为 Pipeline 的一部分,以便在训练和预测中进行所有数据预处理。 这样可以确保数据预处理在训练和预测中保持一致。

这种组织方式使得在后续模型使用中包含预处理和建模变得方便。

Python 中的独热编码

为了在机器学习中使用类别数据,将其转换为独热编码非常重要。您可以使用 Pandas 或 Scikit-learn 轻松完成此转换。

例如,您可以使用 Pandas 对值进行独热编码。

通过调用 get_dummies() 函数,可以快速在 Pandas 中实现独热编码。它将每个类别列转换为单独的列,每列只有一个类别选项。

示例

如果 Gender 的值为“M”或“F”,则该列将被拆分为两个新列,分别称为 Gender_M 和 Gender_F。如果您不希望出现多重共线性,请使用 drop_first=True(仅保留 Gender_F),因为 Gender_F 已经覆盖了 Gender_M。

输出

 
One-Hot Encoded Data using Pandas:
   Employee id  Gender_M  Remarks_Great  Remarks_Nice
0           10      True          False         False
1           20     False          False          True
2           15     False          False         False
3           25      True           True         False
4           30     False          False          True

在 Remarks 中有三个平均值,在 Gender 中有两个。仅编码 n-1 列就足够了,因为我们可以推断出缺失的类别。这样我们就可以移除一些输入特征,同时仍然保留关键信息。

Scikit-learn 也可以实现独热编码

OneHotEncoder 类包含在 Scikit-learn 中,可以在机器学习管道或需要控制编码功能的情况下帮助进行独热编码。

要识别分类列,请使用以下方法

然后应用编码

输出

 
Encoded Employee data:
   Employee id  Gender_F  Gender_M  Remarks_Good  Remarks_Great  Remarks_Nice
0           10       0.0       1.0           1.0            0.0           0.0
1           20       1.0       0.0           0.0            0.0           1.0
2           15       1.0       0.0           1.0            0.0           0.0
3           25       0.0       1.0           0.0            1.0           0.0
4           30       1.0       0.0           0.0            0.0           1.0

将 OneHotEncoder 包含在我们的 ML 管道和 ColumnTransformer 中

在大多数情况下,构建机器学习管道的人会转向 sklearn.preprocessing 的 OneHotEncoder 和 ColumnTransformer。通过这种方式,您可以获得灵活性,并在 Scikit-learn 中使用管道来设置和应用预处理,而无需太多干预。

输出

 
     0    1    2    3    4    5
0  0.0  0.0  1.0  1.0  0.0  0.0
1  1.0  0.0  0.0  0.0  1.0  0.0
2  0.0  1.0  0.0  0.0  0.0  1.0

ColumnTransformer 的优缺点

优点

  • 更进一步,使得能够在一个对象中对不同的列应用不同类型的预处理(例如,缩放和编码)。
  • 与标准的 Scikit-learn 相比,在使用 Estimators 时,可以确保管道步骤保持一致且易于重现。
  • 通过清晰地展示工作步骤、减少代码量以及按列类型分离类似的操作来提供帮助。

缺点

  • 当某些转换在管道内而其他不在管道内时,调试可能会很困难。
  • 当表列事先固定时,转换器会直接使用它们;对于动态变化的数据,转换器有时需要修改。
  • 对特殊逻辑的支持有限:涉及列交互的简单步骤与 ColumnTransformer 配合良好,但自定义和复杂的预处理需要使用自定义编程。

独热编码的优缺点

优点

  • 允许在只能处理数字的算法中使用具有类别名称的变量。
  • 通过清晰地表明类别的存在来提高模型性能,但又不建议它们之间存在任何层次结构。
  • 它防止了无意的有序关系,这对于使用“红色”、“蓝色”和“绿色”或“小”、“中”和“大”进行分类非常有用。

缺点

  • 增加了列的数量,导致训练速度变慢,并创建更复杂的模型。
  • 在稀疏数据中,当许多列的有效数字很少时,性能会下降。
  • 当存在许多分类特征而样本数量很少时,模型可能会偶然学到噪声而不是有用的特征。

结论

本课程展示了如何在为二元分类创建的完整管道中使用 ColumnTransformer 和 OneHotEncoder。如果我们将编码、缩放和建模包含在单个 Pipeline 中,我们就可以确保数据预处理保持一致、整洁且可重复。特征(无论是名义型还是数值型)都可以轻松管理,并且包含插补可以改进模型以处理缺失数据。

我们确保研究了管道的保存和重用,这是将其投入实际应用的重要步骤。无论您的数据大小或类型如何,这种方法都可以提高可维护性,减少潜在错误,并使模型的训练和使用更加容易。使用 Scikit-learn 中的这些方法是获得可用于生产环境的最终结果的关键。