sklearn.pipeline 详解 | 构造规则、运行机制、连接不同pipeline

一、Pipeline构造器规则:

需要一个定义步骤顺序的 (名字, 估计器)对的列表。除了最后一个是估计器(estimator),其余都要是转换器(transformer,即要有fit_transform()方法),名字可以随意取。

名词解释:可参考【Scikit-Learn | 自定义转换器(transformer)】【 fit()、transform()、fit_transform() 三者联系与区别】

所有的转换器都是估计器,但估计器不一定是转换器

二、运行机制

一般,当你调用Pipeline的fit()方法时,就会对所有转换器按顺序调用fit_transform()方法,将每次调用的输出作为参数传递给下一个调用,一直到最后一个估计器,它只执行fit()方法。

code 1 :探索执行方法

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
import pandas as pd

data_num = pd.read_csv("filename.csv")

num_pipeline = Pipeline([
		('imputer', Imputer(strategy="median")),
		('std_scaler', StandardScaler()),
])

data_num_tr = num_pipeline.fit_transform(housing_num)

code 1中,最后的估计器是一个StandardScaler,它是一个转换器,因此这个pipeline有一个transform()方法,可以按顺序对数据做转换。由于它还有一个fit_transform()方法可以使用,就不必先调用fit()再进行transform()

构建的pipeline可以以一个选择转换器开始,其作用是选择该数据集中要处理的属性(可以是数值变量或分类变量),丢弃其他无用的属性,进而进行下一步操作。尤其是构建处理数值属性和类别属性的pipeline。

我们需要将选择转换器输出值的类别由DataFrame转变为一个NumPy数组。而Scikit-Learn库没有module来处理Pandas的DataFrame,因此我们需要写一个简单的自定义转换器来做这项工作。

code 2:搭建一个选择转换器

from sklearn.base import BaseEstimator, TransformerMixin

class DataFrameSelector(BaseEstimator, TransformerMixin):
	def __init__(self, attribute_name):
		self.attribute_names = attribute_names
	def fit(self, X, y=None):
		return self
	def transform(self, X):
		return X[self.attribute_names].values 

code 3: 构建pipeline

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer

# 建立一个处理数据值中含数值变量(处理残缺值和特征标准化)的列的pipeline 
num_pipeline = Pipeline([
		('selector', DataFrameSelector(num_attribs)),
		('imputer', Imputer(strategy="median")),
		('std_scaler', StandardScaler())
])

# 建立一个处理数据集中含类别变量(标签编码)的列的pipeline
cat_pipeline = Pipeline([
		('selector', DataFrameSelector(cat_attribs)),
		('onehot', OneHotEncoder(handle_unknown='ignore')),
])

名词解释: 可参考【处理残缺值(Missing value)python-sklearn实现| 三种常用方法】【处理类别变量(categorical variable)python-sklearn实现 | 三种常用方法】

三、连接pipeline

Scikit-Learnti提供一个类FeatureUnion来将不同的pipeline连接在一起。当调用合并后的pipeline的transform()方法时,每个转换器transform()会被并行执行,等待输出,然后将输出合并起来,并返回结果(当然,调用它的fit()方法就会调用每个转换器fit()方法)。

code 4: 连接pipeline

from sklearn.pipeline import FeatureUnion

# 一个能处理数据集中含数值属性和类别属性的列的pipeline
full_pipeline = FeatureUnion(transformer_list=[
		('num_pipeline', num_pipeline),
		('cat_pipeline', cat_pipeline),
])

code 5: 运行pipeline

import pandas as pd

# 读取数据
data = pd.read_csv('filename.csv')

# 数据预处理,处理数据集中含有数值属性和类别属性的列
data_prepared = full_pipeline.fit_transform(data) 

四、快速构造pipeline

在Scikit-Learn 0.20中,ColumnTransformer类同时具有DataFrameSelector类和FeatureUnion类的功能。

Code 6

try:
	from sklearn.compose import ColumnTransformer
except ImportError:
	from future_encoders import ColumnTransformer # Scikit-Learn < 0.20

# 分别获得数据集data中数值属性和类别属性的列名
num_attribs = ['num_1', 'num_2']
cat_attribs = ['cat_1', 'cat_2']

full_pipeline = ColumnTransformer([
		("num", num_pipeline, num_attribs),
		("cat", OneHotEncoder(), cat_attribs),
	])

data_prepared = full_pipeline.fit_transform(data)

参考资料:
《Hands-on Machine Learning with Scikit-Learn and TensorFlow》

你可能感兴趣的:(数据挖掘)