单独管理预处理步骤和模型训练可能导致代码重复和潜在错误,尤其是在评估时可能出现的数据泄露问题。Scikit-learn 提供了一种巧妙的解决方案:位于 sklearn.pipeline 模块中的 Pipeline 对象。Pipeline 允许您将多个数据转换步骤 (例如缩放或编码) 和一个最终的预测步骤 (例如分类器或回归器等估计器) 顺序地组合成一个 Scikit-learn 对象。这个复合对象表现得像一个标准的 Scikit-learn 估计器,具有 fit、predict 和可能具有 transform 方法。构建管道您通过提供一个步骤列表来创建 Pipeline。每个步骤都定义为一个元组,包括:步骤的唯一字符串名称 (您自行选择,例如 'scaler'、'classifier')。Scikit-learn 转换器或估计器的实例 (例如 StandardScaler()、LogisticRegression())。除最后一个步骤外,所有步骤 都必须 是转换器 (即它们必须具有 transform 方法)。最后一个步骤可以是任何估计器 (转换器、分类器、回归器等)。让我们用一个常见的工作流程来说明:对数值特征进行缩放,然后训练一个逻辑回归模型。import numpy as np from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.datasets import make_classification # 1. 生成样本数据 X, y = make_classification(n_samples=100, n_features=5, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42) # 2. 为管道定义步骤 steps = [ ('scaler', StandardScaler()), # 步骤 1: 缩放数据 ('classifier', LogisticRegression()) # 步骤 2: 分类 ] # 3. 创建 Pipeline 对象 pipe = Pipeline(steps=steps) # 4. 管道对象现在表现得像一个单独的估计器 print(pipe) # 在训练数据上拟合整个管道 # StandardScaler 进行 fit_transform,LogisticRegression 进行 fit pipe.fit(X_train, y_train) # 在测试数据上进行预测 # StandardScaler 进行 transform,LogisticRegression 进行 predict y_pred = pipe.predict(X_test) # 评估 (为简单起见,此处使用准确率) accuracy = pipe.score(X_test, y_test) print(f"\n管道准确率: {accuracy:.4f}") Pipeline(steps=[('scaler', StandardScaler()), ('classifier', LogisticRegression())]) 管道准确率: 0.9200在此示例中:我们定义了两个步骤:使用 StandardScaler 的 'scaler' 和使用 LogisticRegression 的 'classifier'。我们将此元组列表传递给 Pipeline 构造函数。调用 pipe.fit(X_train, y_train) 会首先使用 X_train 和 y_train 对 StandardScaler 调用 fit_transform。然后,转换后的 X_train 会与 y_train 一起传递给 LogisticRegression 模型的 fit 方法。调用 pipe.predict(X_test) 会首先使用 X_test 对 已经拟合的 StandardScaler 调用 transform。然后,转换后的 X_test 会传递给已拟合的 LogisticRegression 模型的 predict 方法。这可以确保 StandardScaler 只在训练数据上拟合,并且训练数据和测试数据都使用 相同 的已拟合缩放器进行转换,从而避免数据泄漏。使用 make_pipeline 简化创建Scikit-learn 还提供了一个辅助函数 make_pipeline,它通过自动为步骤生成名称来简化创建过程。名称来源于每个组件的类名的小写形式。from sklearn.pipeline import make_pipeline # 使用 make_pipeline 创建相同的管道 # 名称将是 'standardscaler' 和 'logisticregression' simple_pipe = make_pipeline(StandardScaler(), LogisticRegression()) print(simple_pipe) # 您可以像使用之前的管道一样使用它 simple_pipe.fit(X_train, y_train) accuracy_simple = simple_pipe.score(X_test, y_test) print(f"\nmake_pipeline 准确率: {accuracy_simple:.4f}")Pipeline(steps=[('standardscaler', StandardScaler()), ('logisticregression', LogisticRegression())]) make_pipeline 准确率: 0.9200尽管 make_pipeline 对于简单、线性的管道很方便,但当您需要更精细的控制时,通常更倾向于使用 Pipeline 构造函数明确命名步骤,尤其是在稍后访问特定步骤或执行超参数调整时,我们很快就会看到。可视化流程数据按顺序流经管道步骤:digraph G { rankdir=LR; bgcolor="transparent"; node [shape=box, style="filled", fillcolor="#e9ecef", fontname="sans-serif"]; edge [fontname="sans-serif"]; RawData [label="输入数据 (X)"]; Scaler [label="步骤 1: 缩放器\n(fit_transform / transform)", fillcolor="#a5d8ff"]; Estimator [label="步骤 2: 估计器\n(fit / predict)", fillcolor="#b2f2bb"]; Output [label="预测结果 (y_pred)\n或转换后的数据", shape=ellipse, fillcolor="#ffec99"]; RawData -> Scaler; Scaler -> Estimator; Estimator -> Output; }数据流入第一个步骤 (缩放器)。在拟合过程中,它调用 fit_transform。在预测/转换过程中,它调用 transform。其输出会传入下一个步骤 (估计器),估计器相应地调用 fit 或 predict,产生最终输出。创建这些简单的管道将您的预处理和建模逻辑封装到一个对象中。这简化了您的代码,使您的工作流程更具可复现性,并且,它为正确应用交叉验证和超参数调整等技术创造了条件,从而避免了意外的数据泄漏,我们将在接下来讨论。