机器学习最好用的scikit-learn中的pipeline操作区别彻底搞清

scikit-learn 中的pipeline是什么

scikit-learn 中的pipeline是一个实用程序类,可帮助将 ML 工作流的多个步骤组装到单个 scikit-learn estimator中。 pipeline由一系列转换或预处理步骤组成,然后是根据转换后的数据进行预测的estimator。 pipeline通过自动化转换数据和训练模型所涉及的步骤来帮助简化 ML 过程。 pipeline还确保数据在整个工作流程中得到一致处理,并有助于防止pipeline不同阶段之间的数据泄漏。 流水线类是封装整个机器学习流程的便捷工具,可以更方便地管理和共享代码,降低实现中出错的风险。

带或不带estimator的pipeline

由于各种原因,流水线不一定需要在最后一步中使用机器学习模型作为estimator。 例如,我们只想创建一个用于预处理数据的数据pipeline,以在预处理和建模之间划分任务。

在这两种情况下,我们将在下面讨论的运算符的工作方式相同。

sklearn 中的transformer(转换器)是什么

Transformer是实现 fit()、transform() 和/或 fit_transform() 方法的estimator。 TransformerMixin 是默认实现和一个 Mixin 类,它在 sklearn 的转换器之间提供一致的接口。

在 fit() 函数中,我们获取输入数据并对我们随后将应用的特定转换函数执行所需的计算。 例如,它可以计算输入数据的平均值和标准偏差,并为以后使用做好准备。

在 transform() 中,我们将输入数据转换为一些新格式。 输出通常是一个数组或一个稀疏矩阵,其样本数 (n_samples) 与输入数据相同。 从 fit() 函数获得的参数将在这一步中使用。
例如,如果我们想将输入数据转换为标准化版本,我们将用均值减去每个数据点并除以从 fit() 步骤获得的标准差。

fit_transform() 只是一起调用 fit() 和 transform() 的更有效方式。 它是默认实现的。

pipeline中 fit()、transform()、fit_transform()、predict() 和 predict_proba() 之间的区别

在pipeline中,我们有多个转换器,每个转换器都有自己的 fit() 和 transform() 方法,
所以通常会混淆几个类似的pipeline函数之间的确切差异,以及何时使用它们。
这里首先讨论差异,然后展示一些例子来证明这一点。

fit()

一个接一个地安装所有的变压器并转换数据。 最后,使用最终estimator拟合转换后的数据。 请注意,它不会调用最后一个转换器的 transform() 方法。 这是有道理的,因为在典型的pipeline中,最后一步只是模型estimator,而 transform() 可能不是正确的概念。 相反,predict() 操作会更有意义。

fit() 的返回值是安装了所有步骤的pipeline对象本身。

transform()

pipeline的 transform() 将只调用所有转换器的 transform 方法,包括最后一个。

fit_transform()

pipeline的 fit_transform() 将调用所有转换器的 fit 和 transform 方法,包括最后一个。

predict()

流水线的 predict() 仅在流水线的最后一步定义了 predict() 方法时才有效,如果最后一步是模型estimator,则通常为真。 predict() 将在最后一步之前调用pipeline中每个转换器的转换。 然后,转换后的数据最终传递给调用 predict 方法的最终estimator。

predict_proba()

例如,有时我们想得到一个预测概率而不是分类中的类,所以我们调用 predict_proba()
而不是预测()。 仅当最后一步的estimator定义了 predict_proba() 时,它才会起作用。 否则,程序与 predict() 相同。

演示

首先定义两个自定义转换器,并将它们放入pipeline中

import numpy as np
from sklearn.base import TransformerMixin, BaseEstimator
from sklearn.pipeline import Pipeline

# Custom transformer 1: Log Transformer
class LogTransformer(BaseEstimator, TransformerMixin):
    def __init__(self, log_base=np.e):
        self.flag = 'N'
        self.log_base = log_base

    def fit(self, X, y=None):
        self.flag = 'Y'
        print('hello from transformer 1 fit')
        return self

    def transform(self, X, y=None):
        print('hello from transformer 1 transform')
        print(f'check fit value from transformer 1:{self.flag}')
        return np.log(X) / np.log(self.log_base)

# Custom transformer 2: Square Root Transformer
class SqrtTransformer(BaseEstimator, TransformerMixin):
    
    def __init__(self):
        self.flag = 'N'
        
    
    def fit(self, X, y=None):
        self.flag = 'Y'
        print('hello from transformer 2 fit')
        return self

    def transform(self, X, y=None):
        print('hello from transformer 2 transform')
        print(f'check fit value from transformer 2:{self.flag}')
        return np.sqrt(X)

# Creating the pipeline
pipe = Pipeline([
    ('log', LogTransformer()),
    ('sqrt', SqrtTransformer()),
])

使用 fit() 方法,不会调用最后一个转换器的 transform() 方法

import numpy as np

X = np.array([1,2,3,4,5])

pipe_new = pipe.fit(X)

print(pipe_new)

hello from transformer 1 fit
hello from transformer 1 transform
check fit value from transformer 1:Y
hello from transformer 2 fit
Pipeline(steps=[('log', LogTransformer()), ('sqrt', SqrtTransformer())])

使用 transform() 方法,调用所有 transfom() 方法; 并且缓存了先前 fit() 的参数

X = np.array([1,2,3,4,5])

X_transformed = pipe.transform(X)

print(X_transformed)
hello from transformer 1 transform
check fit value from transformer 1:Y
hello from transformer 2 transform
check fit value from transformer 2:Y
[0.         0.83255461 1.04814707 1.17741002 1.26863624]

如果之前没有应用 fit(),使用 transform() 方法,仍然会调用所有 transform() 方法,但是之前的 fit() 的参数不存在

# redefine a new pipe 

pipe = Pipeline([
    ('log', LogTransformer()),
    ('sqrt', SqrtTransformer()),
])

X = np.array([1,2,3,4,5])

X_transformed = pipe.transform(X)

print(X_transformed)

hello from transformer 1 transform
check fit value from transformer 1:N
hello from transformer 2 transform
check fit value from transformer 2:N
[0.         0.83255461 1.04814707 1.17741002 1.26863624]

使用 fit_transform(),所有的 fit() 和 transform() 方法都会被调用,返回值是转换后的数据,而不是pipeline

X = np.array([1,2,3,4,5])

X_transformed = pipe.fit_transform(X)

print(X_transformed)
hello from transformer 1 fit
hello from transformer 1 transform
check fit value from transformer 1:Y
hello from transformer 2 fit
hello from transformer 2 transform
check fit value from transformer 2:Y
[0.         0.83255461 1.04814707 1.17741002 1.26863624]

英文链接

链接

最后的话

AI日新月异,但是万丈高楼拔地起,离不开良好的基础。您是否有兴趣了解人工智能的原理和实践? 不要再观望! 我们关于 AI 原则和实践的书是任何想要深入了解 AI 世界的人的完美资源。 由该领域的领先专家撰写,这本综合指南涵盖了从机器学习的基础知识到构建智能系统的高级技术的所有内容。 无论您是初学者还是经验丰富的 AI 从业者,本书都能满足您的需求。 那为什么还要等? 立即下单,开始以一种易于访问、引人入胜且实用的方式学习 AI。

人工智能原理与实践 全面涵盖人工智能和数据科学各个重要体系经典

北大出版社,人工智能原理与实践 人工智能和数据科学从入门到精通 详解机器学习深度学习算法原理

你可能感兴趣的:(机器学习算法和原理,数据挖掘,scikit-learn,python)