Pipeline(管道)正如名字一样,直观上理解是用于对数据处理各个流程进行规范化统一管理的工具。
Pipeline 可以把多个评估器链接成一个。这个是很有用的,因为处理数据的步骤一般都是固定的,例如特征选择、标准化和分类。
特点:
【1】便捷性和封装性
你只要对数据调用 fit
和 predict
一次来适配所有的一系列评估器。
【2】联合的参数选择
你可以一次 :ref:grid search
管道中所有评估器的参数。
【3】安全性
训练转换器和预测器使用的是相同样本,管道有助于防止来自测试数据的统计数据泄露到交叉验证的训练模型中。
2.1怎么用??
(1)手动命名评估器:
Pipeline 使用一系列 (key, value) 键值对来构建,其中 key 是你给这个步骤起的名字, value 是一个评估器对象:
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
from sklearn.decomposition import PCA
estimators = [('reduce_dim', PCA()), ('clf', SVC())]
pipe = Pipeline(estimators)
>>> pipe
Pipeline(memory=None,
steps=[('reduce_dim', PCA(copy=True,...)),
('clf', SVC(C=1.0,...))])
(2)自动命名评估器:
上面是手动指定评估器名称的方法。还有一种自动填充评估器名称的方法。
自动功能函数 make_pipeline 是构建管道的缩写; 它接收多个评估器并返回一个管道,自动填充评估器名:
from sklearn.pipeline import make_pipeline
from sklearn.naive_bayes import MultinomialNB
from sklearn.preprocessing import Binarizer
>>> make_pipeline(Binarizer(), MultinomialNB())
Pipeline(memory=None,
steps=[('binarizer', Binarizer(copy=True, threshold=0.0)),
('multinomialnb', MultinomialNB(alpha=1.0,
class_prior=None,
fit_prior=True))])
这个例子相较于上一个就是没有指定评估器名称,但是其自动指定了。
2.2怎么查找??
方法一:管道中的评估器作为一个列表保存在 steps 属性内(其实很直观啊,用step这个词强调过程步骤性):
>>> pipe.steps[0]
('reduce_dim', PCA(copy=True, iterated_power='auto', n_components=None, random_state=None,
svd_solver='auto', tol=0.0, whiten=False))
方法二:管道中的评估器也作为 dict 保存在 named_steps 内(也比较直观,比如采用自己命名初始化时,就可以直接按名称查找):
>>> pipe.named_steps['reduce_dim']
PCA(copy=True, iterated_power='auto', n_components=None, random_state=None,
svd_solver='auto', tol=0.0, whiten=False)
2.3评估器的参数怎么访问修改??
管道中的评估器参数可以通过 <estimator>__<parameter> 语义来访问:
>>> pipe.set_params(clf__C=10)
Pipeline(memory=None,
steps=[('reduce_dim', PCA(copy=True, iterated_power='auto',...)),
('clf', SVC(C=10, cache_size=200, class_weight=None,...))])
named_steps 的属性映射到多个值,在交互环境支持 tab 补全:
>>> pipe.named_steps.reduce_dim is pipe.named_steps['reduce_dim']
True
这对网格搜索尤其重要:
from sklearn.model_selection import GridSearchCV
param_grid = dict(reduce_dim__n_components=[2, 5, 10], clf__C=[0.1, 10, 100]) 指定参数
grid_search = GridSearchCV(pipe, param_grid=param_grid) 进行网格搜索
这里是使用时的一个技巧:
单独的步骤可以用多个参数替换,除了最后步骤,其他步骤都可以设置为 None 来跳过
>>> from sklearn.linear_model import LogisticRegression
>>> param_grid = dict(reduce_dim=[None, PCA(5), PCA(10)],
... clf=[SVC(), LogisticRegression()],
... clf__C=[0.1, 10, 100])
>>> grid_search = GridSearchCV(pipe, param_grid=param_grid)
附注:
对管道调用 fit 方法的效果跟依次对每个评估器调用 fit 方法一样, 都是transform
输入并传递给下个步骤。 管道中最后一个评估器的所有方法,管道都有。例如,如果最后的评估器是一个分类器, Pipeline 可以当做分类器来用。如果最后一个评估器是转换器,管道也一样可以。
占个位,缓存转换器???
FeatureUnion 合并了多个转换器对象形成一个新的转换器,该转换器合并了他们的输出。一个 FeatureUnion 可以接收多个转换器对象。在适配期间,每个转换器都单独的和数据适配。 对于转换数据,转换器可以并发使用,且输出的样本向量被连接成更大的向量。
FeatureUnion 功能与 Pipeline 一样- 便捷性和联合参数的估计和验证。
可以结合:class:FeatureUnion 和 Pipeline 来创造出复杂模型。
(直观上理解,可以理解为多个流水线同时并行对数据操作,各个流水线工作互不影响)
(FeatureUnion无法检查两个转换器是否可能产生相同的特征,当特征集不相交时,它只产生一个并集,并确保它们是调用者的责任。)
3.1用法??
FeatureUnion使用(key,value)对的列表构建,其中key是您要给予给定变换的名称(任意字符串;它仅用作标识符),value是一个估计器对象:
>>> from sklearn.pipeline import FeatureUnion
>>> from sklearn.decomposition import PCA
>>> from sklearn.decomposition import KernelPCA
>>> estimators = [('linear_pca', PCA()), ('kernel_pca', KernelPCA())]
>>> combined = FeatureUnion(estimators)
>>> combined
FeatureUnion(n_jobs=1, transformer_list=[('linear_pca', PCA(copy=True,
iterated_power='auto', n_components=None, random_state=None,
svd_solver='auto', tol=0.0, whiten=False)), ('kernel_pca',
KernelPCA(alpha=1.0, coef0=1, copy_X=True, degree=3,
eigen_solver='auto', fit_inverse_transform=False, gamma=None,
kernel='linear', kernel_params=None, max_iter=None, n_components=None,
n_jobs=1, random_state=None, remove_zero_eig=False, tol=0))],
transformer_weights=None)
像管道一样,特征联合体有一个称为make_union的简化构造函数,不需要显式命名组件。像管道一样,单个步骤可以使用set_params替换,并通过设置为None来忽略:
>>> combined.set_params(kernel_pca=None)
FeatureUnion(n_jobs=1, transformer_list=[('linear_pca', PCA(copy=True,
iterated_power='auto', n_components=None, random_state=None,
svd_solver='auto', tol=0.0, whiten=False)), ('kernel_pca', None)],
transformer_weights=None)