机器学习:构建Pipeline(一)

0/前言

一个完整的机器学习过程: ETL 数据预处理 特征工程 模型训练和评估

pipeline可以理解为'一条龙服务',或者‘总和解决方法’。

机器学习项目中有可以自动化的标准工作流程。
在 Python scikit-learn 扩展包中,管道有助于明确定义和自动化这些工作流程。
在这系列文章中,您将了解 scikit-learn 扩展包中的流水线以及如何自动化常见的机器学习工作流程以及构建自定义的流水线处理。


在讲管道pipeline之前我们先了解一下scikit-learn中的两个概念Transformer和Estimator.
<1>Transformer:
      转换器是指具有 fit() 和 transform() 方法的对象,
      用于清理、减少、扩展或生成特征。
      简而言之,转换器可帮助您将数据转换为机器学习模型所需的数据格式。 
      LabelEncoder,OneHotEncoder 和 MinMaxScaler 是转换器的示例。
      Transformer主要用于在特征工程上。如特征编码,归一化等等。

<2>Estimator:
     估计器是指机器学习模型。它是一个带有 fit() 和 predict() 方法的对象。
     我们将在本文中交替使用估算器和模型。如RandomFroest(),SVM()。
复制代码

1/Pipeline

我门首先将使用一个数据集逐步的讲解如何使用scikit-learn扩展包构建一个简单的pipeline。
让我们导入所需的扩展包和相关的数据集。
复制代码
# 导入相应的包和模块
import pandas as pd
from seaborn import load_dataset
from sklearn.model_selection import train_test_split
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.preprocessing import OneHotEncoder, MinMaxScaler
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.compose import ColumnTransformer
from sklearn.linear_model import LinearRegression

# =加载数据集,我们无放回随机选取了5组数据进行测试
# 设置随机种子
seed = 123
df = load_dataset('tips').drop(columns=['tip', 'sex']).sample(n=5, random_state=seed)

# 增加一些缺失值用于测试
df.iloc[[1, 2, 4], [2, 4]] = np.nan
df
复制代码

image.png

上面我们随机选取五组数据进行测试,可以方便的看到在pipeline中到底发生了怎样的操作。
在创建pipeline之前我们首先要做的一步就是划分训练集和测试集,此处我们使用'total_bill'列作为需要预测的y,使用'smoker','day',time'作为特征。可以看到此时这三个特征全部类别特征。
复制代码
x = df.drop( columns=['total_bill', 'size'] )
y = df['total_bill']
X_train, X_test, y_train, y_test = train_test_split(x,y,test_size=.2,random_state=seed)
复制代码
对于特征我们首先要做的就是将其转换成机器学习模型所能接受的形式,因此我们首先需要做两部分工作
1.  对特征进行缺失值填充,关于缺失值填充其实是有很多技巧和复杂的。好的缺失值处理对模型有很大的提升。本文会用简单的方式填充。
2.  对类别型特征进行编码

在我们没有构建pipeline之前我们的操作如下: 逐步的对训练数据和测试数据进行上面两步操作
复制代码
#使用scikit-learn中自带的模块处理缺失值,strategy='constant'表示使用常量填充缺失值
#即将缺失值作为该特征的一个值
imputer = SimpleImputer(strategy='constant', fill_value='missing')
X_train_imputed = imputer.fit_transform(X_train)

# 编码训练数据
encoder = OneHotEncoder(handle_unknown='ignore', sparse=False)
X_train_encoded = encoder.fit_transform(X_train_imputed)

# 查看训练数据处理前后结果
print("******************** Training data ********************")
display(X_train)
display(pd.DataFrame(X_train_imputed, columns=X_train.columns))
display(pd.DataFrame(X_train_encoded, columns=encoder.get_feature_names(X_train.columns)))
#由于scikit-learn返回的都是numpy,因此我们通过encoder.get_feature_names可以得到编码之后的列名
#由其自动生成的

# 转换测试数据
X_test_imputed = imputer.transform(X_test)
X_test_encoded = encoder.transform(X_test_imputed)

# 查看测试数据前后的结果
print("******************** Test data ********************")
display(X_test)
display(pd.DataFrame(X_test_imputed, columns=X_train.columns))
display(pd.DataFrame(X_test_encoded, columns=encoder.get_feature_names(X_train.columns)))
复制代码
非pipeline处理结果如下:
复制代码

image.png

image.png

猜你喜欢

转载自juejin.im/post/7018364698135871495