管道概述
管道是保持数据预处理和建模代码井井有条的简单方法。具体而言,管道捆绑了预处理和建模步骤,因此您可以像使用单个步骤一样使用整个捆绑包。
优点
- 简化工作流: 管道(Pipeline)能够将多个预处理步骤和模型训练步骤串联起来,形成一个连贯的工作流程。这样可以使得代码更加整洁、易于理解和维护。
- 自动化: 管道能够自动应用预处理变换到训练和测试数据上,避免了手动对每个数据集重复相同的操作,减少了出错的可能性。
- 可移植性和重用性: 通过封装整个处理流程为一个对象,管道可以在不同的项目或环境中轻松复用,提高了代码的模块化程度。
- 集成交叉验证: Scikit-learn中的Pipeline可以无缝集成交叉验证功能,使得在包含预处理步骤的情况下评估模型性能变得更加简单。
- 并行计算友好: 对于支持并行处理的预处理步骤,Pipeline能够利用这一特性,提高处理大数据集时的效率。
缺点
- 调试难度: 当管道中某个步骤出现问题时,由于多个步骤被封装在一起,定位具体问题的源头可能会比较困难。
- 灵活性受限: 管道要求所有步骤都是可调用的对象(通常是Estimator或Transformer),这限制了在管道中直接使用自定义逻辑或复杂操作的能力。
- 性能考量: 尤其是在包含大量数据转换的管道中,每次执行都需依次通过所有步骤,这可能导致处理速度较慢。特别是当某些步骤并不总是必需时,这种“一刀切”的处理方式可能不是最高效的。
- 内存占用: 管道在处理数据时,尤其是在连续的转换步骤中,可能会产生大量的中间数据结构,从而增加内存消耗。
- 可视化和理解难度: 对于复杂的管道,尤其是包含多层嵌套的情况,理解整体数据流动和每一步的具体作用可能较为困难,不利于团队之间的沟通和协作。
步骤
定义预处理步骤
我们使用该 ColumnTransformer
类将不同的预处理步骤捆绑在一起
#导入模块
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
#对缺失值进行处理
from sklearn.impute import SimpleImputer
#对分类变量进行处理
from sklearn.preprocessing import OneHotEncoder
#strategy可以指定空值填充策略——对数值型变量进行处理
numerical_transformer = SimpleImputer(strategy='constant')
#使用独热编码对分类型数据进行处理
categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))
])
#进行捆绑
preprocessor = ColumnTransformer(
transformers=[
('num', numerical_transformer, numerical_cols),
('cat', categorical_transformer, categorical_cols)
])
定义模型
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor(n_estimators=100, random_state=0)
创建管道
my_pipeline = Pipeline(steps=[('preprocessor', preprocessor),
('model', model)
])
# 拟合
my_pipeline.fit(X_train, y_train)
# 预测
preds = my_pipeline.predict(X_valid)