Python - 什么是sklearn.pipeline.Pipeline?

时间:2015-10-12 22:42:47

标签: python machine-learning scikit-learn

我无法弄清sklearn.pipeline.Pipeline如何正常工作。

doc中有一些解释。例如,他们的意思是:

  

使用最终估算器进行转换的管道。

为了使我的问题更清楚,steps是什么?他们是如何运作的?

修改

感谢答案,我可以让我的问题更清楚:

当我调用管道并传递,作为步骤,两个变换器和一个估算器,例如:

pipln = Pipeline([("trsfm1",transformer_1),
                  ("trsfm2",transformer_2),
                  ("estmtr",estimator)])

当我打电话给你时会发生什么?

pipln.fit()
OR
pipln.fit_transform()

我无法弄清楚估算器如何成为变压器以及如何安装变压器。

3 个答案:

答案 0 :(得分:119)

scikit-learn中的

Transformer - 一些具有拟合和变换方法的类,或fit_transform方法。

预测器 - 一些适合和预测方法的类,或fit_predict方法。

管道只是一个抽象的概念,它不是现有的ml算法。通常在ML任务中,您需要在应用最终估算器之前执行原始数据集的不同转换序列(查找要素集,生成新要素,仅选择一些好的要素)。

Here是管道使用的一个很好的例子。 Pipeline为您提供了所有3个转换步骤和结果估算器的单一界面。它封装了内部的变换器和预测器,现在你可以做类似的事情:

    vect = CountVectorizer()
    tfidf = TfidfTransformer()
    clf = SGDClassifier()

    vX = vect.fit_transform(Xtrain)
    tfidfX = tfidf.fit_transform(vX)
    predicted = clf.fit_predict(tfidfX)

    # Now evaluate all steps on test set
    vX = vect.fit_transform(Xtest)
    tfidfX = tfidf.fit_transform(vX)
    predicted = clf.fit_predict(tfidfX)

只有:

pipeline = Pipeline([
    ('vect', CountVectorizer()),
    ('tfidf', TfidfTransformer()),
    ('clf', SGDClassifier()),
])
predicted = pipeline.fit(Xtrain).predict(Xtrain)
# Now evaluate all steps on test set
predicted = pipeline.predict(Xtest)

使用管道,您可以轻松地对此元估计器的每个步骤的参数集执行网格搜索。如上面的链接所述。除最后一步之外的所有步骤必须是变换,最后一步可以是变换器或预测器。 回答编辑: 当您致电pipln.fit()时 - 管道内的每个变压器都将安装在先前变压器的输出上(第一个变压器是在原始数据集上学习的)。最后一个估算器可能是变换器或预测器,只有当你的最后一个估算器是变换器(实现fit_transform,或者单独转换和拟合方法)时,你才能在管道上调用fit_transform(),你可以只在管道上调用fit_predict()或predict()你的最后一个估算器是预测器。所以你不能调用fit_transform或转换管道,最后一步是预测器。

答案 1 :(得分:12)

我认为M0rkHaV有正确的想法。 Scikit-learn的管道类是一个有用的工具,可以将多个不同的变换器与估算器一起封装到一个对象中,这样您只需要调用一次重要的方法(fit()predict()等)。让我们分解两个主要组成部分:

  1. 变形金刚是同时实施fit()transform()的类。您可能熟悉某些sklearn预处理工具,例如TfidfVectorizerBinarizer。如果您查看这些预处理工具的文档,您会看到它们实现了这两种方法。我觉得非常酷的是,一些估算器也可以用作转换步骤,例如LinearSVC <!/ p>

  2. Estimators 是同时实现fit()predict()的类。您会发现许多分类器和回归模型都实现了这两种方法,因此您可以轻松地测试许多不同的模型。可以使用另一个变换器作为最终估计器(即,它不一定实现predict(),但绝对实现fit())。所有这些意味着您将无法拨打predict()

  3. 至于你的编辑:让我们来看一个基于文本的例子。使用LabelBinarizer,我们希望将标签列表转换为二进制值列表。

    bin = LabelBinarizer()  #first we initialize
    
    vec = ['cat', 'dog', 'dog', 'dog'] #we have our label list we want binarized
    

    现在,当二进制化器适合某些数据时,它将具有一个名为classes_的结构,其中包含变换器“知道”的唯一类。在不调用fit()的情况下,二进制文件不知道数据是什么样的,因此调用transform()没有任何意义。如果在尝试拟合数据之前打印出类列表,则会出现这种情况。

    print bin.classes_  
    

    尝试此操作时出现以下错误:

    AttributeError: 'LabelBinarizer' object has no attribute 'classes_'
    

    但是当您将二进制文件放在vec列表中时

    bin.fit(vec)
    

    再试一次

    print bin.classes_
    

    我得到以下内容:

    ['cat' 'dog']
    
    
    print bin.transform(vec)
    

    现在,在对vec对象调用transform之后,我们得到以下内容:

    [[0]
     [1]
     [1]
     [1]]
    

    对于用作变换器的估算器,让我们使用DecisionTree分类器作为特征提取器的示例。决策树很多原因很多,但出于我们的目的,重要的是它们能够对发现的预测有用的功能进行排名。当您在决策树上致电transform()时,它会获取您的输入数据并找到认为最重要的功能。因此,您可以将其视为将数据矩阵(n行m列)转换为较小的矩阵(n行x列),其中k列是决策树找到的k个最重要的特征。

答案 2 :(得分:9)

ML算法通常处理表格数据。您可能需要在ML算法之前和之后对该数据进行预处理和后处理。管道是链接这些数据处理步骤的一种方式。

What are ML pipelines and how do they work?

管道是转换数据的一系列步骤。它来自旧的“管道和过滤器”设计模式(例如,您可以想到带有管道“ |”的unix bash命令或重定向运算符“>”)。但是,管道是代码中的对象。因此,您可能为每个过滤器都有一个类(也就是每个管道步骤),然后是另一个类来将这些步骤组合到最终管道中。一些管道可能将其他管道串联或并联组合,具有多个输入或输出,依此类推。我们喜欢将Pipelining Machine Learning视为:

  • Pipe and filters。管道的步骤处理数据,并管理它们的内部状态,这些状态可以从数据中学到。
  • Composites。管道可以嵌套:例如,整个管道可以视为另一个管道中的单个管道步骤。流水线步骤不一定是流水线,但按照定义,流水线本身至少是流水线步骤。
  • Directed Acyclic Graphs (DAG)。流水线步骤的输出可以发送到许多其他步骤,然后可以重组结果的输出,依此类推。旁注:尽管管道是非循环的,但它们可以一个接一个地处理多个项目,并且如果它们的状态发生变化(例如:每次使用fit_transform方法),那么它们可以被视为随着时间的流逝不断展开,保持其状态(例如RNN)。这是一种有趣的方式,可用于在生产中进行在线学习并在更多数据上对其进行培训时进行在线学习。

Scikit学习管道的方法

管道(或管道中的步骤)必须具有这两种方法

  • fit”以学习数据并获取状态(例如:神经网络的神经权重就是这种状态)
  • transform”(或“预测”)实际处理数据并生成预测。

也可以调用此方法将两者链接:

  • fit_transform”适合数据然后进行转换,但是要一次通过,这可以在必须直接一个接一个地执行这两种方法时进行潜在的代码优化。

Problems of the sklearn.pipeline.Pipeline class

Scikit-Learn的“管道和过滤器”设计模式非常漂亮。但是如何将其用于深度学习,AutoML和复杂的生产级管道?

Scikit-Learn于2007年首次发布,当时是pre deep learning era。但是,它是最著名和采用最广泛的机器学习库之一,并且仍在不断发展。最重要的是,它使用“管道和过滤器”设计模式作为软件架构样式-这就是Scikit-Learn如此出色的原因,此外,它还提供了可供使用的算法。但是,在执行以下操作时会遇到很多问题,我们应该能够在2020年做到这一点:

  • 自动机器学习(AutoML),
  • 深度学习管道,
  • 更复杂的机器学习管道。

我们为那些Scikit-Learn的问题找到的解决方案

可以肯定,Scikit-Learn非常方便且结构精良。但是,它需要刷新。这是我们使用Neuraxle的解决方案,使Scikit-Learn在现代计算项目中变得新鲜且可用!

通过Neuraxle提供的其他管道方法和功能

注意:如果管道的某个步骤不需要使用fit或transform方法之一,则可以从NonFittableMixinNonTransformableMixin继承以提供其中之一的默认实现什么都不做的方法。

首先,管道或其步骤也可以可选地定义这些方法

  • setup”将在每个步骤中调用“ setup”方法。例如,如果某个步骤包含TensorFlow,PyTorch或Keras神经网络,则这些步骤可以创建它们的神经图,并在适合之前通过“设置”方法将它们注册到GPU。不建议在步骤的构造函数中直接创建图,原因有多种,例如,如果在自动机器学习算法中使用不同的超参数多次运行之前复制了这些步骤,然后为您搜索最佳的超参数。
  • teardown”,与“ setup”方法相反:它清除资源。

默认情况下,提供了以下以下方法以允许管理超参数:

  • get_hyperparams”将为您返回超参数的字典。如果您的管道包含更多管道(嵌套管道),则超参数的键将用双下划线“ __”分隔符链接。
  • set_hyperparams”将允许您以获取新超参数的相同格式设置新超参数。
  • get_hyperparams_space”允许您获取超参数的空间,如果您定义了该空间,则该空间将不为空。因此,此处“ get_hyperparams”的唯一区别在于,您将获得统计分布值,而不是精确值。例如,层数的一个超参数可以是RandInt(1, 3),表示1到3层。您可以在此字典上调用.rvs()以随机选择一个值,然后将其发送到“ set_hyperparams”以尝试对其进行训练。
  • set_hyperparams_space”可用于使用与“ get_hyperparams_space”中相同的超参数分布类来设置新空间。

有关建议的解决方案的更多信息,请阅读上面带有链接的大列表中的条目。