Spark ML Pipelines
ML管道
管道的主要概念
MLlib对用于机器学习算法的API进行了标准化,从而使将多种算法组合到单个管道或工作流中变得更加容易。
-DataFrame
:此ML API使用DataFrameSpark SQL作为ML数据集,可以保存各种数据类型。例如,一个DataFrame可能有不同的列,用于存储文本,特征向量,真实标签和预测。
-
Transformer
:一个Transformer是一种算法,其可以将一个DataFrame到另一个DataFrame。例如,ML模型是一种Transformer将DataFrame具有特征的a转换为DataFrame具有预测的a的模型。 -
Estimator
:An Estimator是一种算法,可以适合DataFrame产生Transformer。例如,学习算法是在上Estimator进行训练DataFrame并生成模型的算法。 -
Pipeline
:将Pipeline多个Transformer和链接Estimator在一起以指定ML工作流程。 -
Parameter
:所有Transformer和Estimator现在共享一个用于指定参数的通用API。
DataFrame
Machine learning可以应用于多种数据类型,例如矢量,文本,图像和结构化数据。该API采用Spark SQL中的DataFrame,以支持多种数据类型。
DataFrame支持许多基本类型和结构化类型。请参考Spark SQL数据类型参。除了Spark SQL指南中列出的类型之外,DataFrame还可使用ML Vector类型。
可以从常规RDD隐式或显式创建DataFrame。
命名DataFrame中的列。下面的代码示例使用诸如“文本”,“功能”和“标签”之类的名称。
Pipeline components(管道组件)
Transformers(转换器)
Transformers
是一种抽象,其中包括特征转换器和学习的模型。从技术上讲,Transformer实现了transform()
方法,该方法通常通过附加一个或多个列将一个DataFrame转换为另一个DataFrame。例如:
-
特征转换器可以获取一个DataFrame,读取一列(例如:文本),将其映射到一个新列(例如:特征向量),然后输出一个新的DataFrame并附加映射的列。
-
学习模型可能需要一个DataFrame,读取包含特征向量的列,预测每个特征向量的标签,然后输出带有预测标签的新DataFrame作为列添加。
Estimators(估算器)
一个Estimator抽象学习算法的概念或算法适合或数据串。从技术上讲,Estimator实现是一种方法fit(),该方法接收一个DataFrame并产生一个 Model,即一个Transformer。例如,学习算法(例如为LogisticRegression)Estimator和调用 fit()训练一个LogisticRegressionModel,即为Model,因此为Transformer。
Properties of pipeline components(管道组件属性)
Transformer.transform()和Estimator.fit()都是无状态的。将来,可通过替代概念来支持有状态算法。
每个Transformer或Estimator实例都有一个唯一的ID,该ID在指定参数中很有用。
Pipeline(管道)
在machine learning中,通常需要运行一系列算法来处理数据并从中学习。例如,简单的文本文档处理工作流程可能包括几个阶段:
- 将每个文档的文本拆分为单词。
- 将每个文档的单词转换成数字特征向量。
- 使用特征向量和标签学习预测模型。
MLlib将这样的工作流表示为“Pipeline”,它由要按特定顺序运行的一系列PipelineStages
(Transformer和Estimator
)组成。
工作流程
Pipeline被指定为阶段序列,每个阶段可以是一个Transformer
或Estimator
。这些阶段按顺序运行,并且输入DataFrame在通过每个阶段时都会进行转换。对于Transformer
阶段,在DataFrame上调用transform()方法
。对于Estimator
阶段,调用fit()
方法以生成一个Transformer(它将成为PipelineModel
或已拟合Pipeline
的一部分),并且在DataFrame上调用该Transformer的transform()
方法。
下图为简单的文本文档工作流程管道的培训时间使用情况。
上图的第一行代表Pipeline的三个阶段。前面两个蓝色区域(Tokenizer
和HashingTF
)为Transformers
,第三个(LogisticRegression
)是Estimator
。第二行表示流经管道的数据,其中第一个表示DataFrames。Pipeline.fit()
在原始DataFrame文件上调用此方法,原始文件包含原始文本文档和标签。该Tokenizer.transform()
方法将原始文本文档拆分为单词,然后向添加带有单词的新列DataFrame。该HashingTF.transform()
方法将words列转换为特征向量,并将带有这些向量的新列添加到DataFrame。现在,由于LogisticRegression为Estimator,因此Pipeline第一个调用LogisticRegression.fit()
产生一个LogisticRegressionModel
。如果管道中有更多Estimator,则在将DataFrame传递到下一阶段之前,将在DataFrame上调用LogisticRegressionModel的transform()
方法。
当Pipeline只有Estimator,因此,运行Pipeline的fit()方法后,它会生成PipelineModel,它是一个Transformer。该PipelineModel在测试时使用,用法如下图。
在上图中,PipelineModel具有与原始Pipeline相同的阶段数,但是原始Pipeline中的所有Estimator都已变为Transformers。在测试数据集上调用PipelineModel的transform()
方法时,数据将按顺序通过拟合的管道。每个阶段的transform()
方法都会更新数据集,并将其传递到下一个阶段。
Pipelines 和 PipelineModels有助于确保训练和测试数据经过相同的特征处理步骤。
详细
-
DAG Pipeline
:Pipeline的阶段被指定为有序数组。此处给出的所有示例均适用于线性管道,即每个阶段使用前一阶段产生的数据的管道。只要数据流图形成有向无环图
(DAG),就可以创建非线性管道。当前基于每个阶段的输入和输出列名称(通常指定为参数)隐式指定该图。如果管道形成DAG,则必须按拓扑顺序指定阶段。 -
运行时检查
:由于管道可以在具有各种类型的DataFrame上运行,因此它们不能使用编译时类型检查。Pipelines和PipelineModels会在实际运行Pipeline之前进行运行时检查。此类型检查使用DataFrame架构完成,该架构是对DataFrame中列的数据类型的描述。 -
唯一的Pipeline阶段
:管道的阶段应该是唯一的实例。例如,同一实例myHashingTF不应两次插入到管道中,因为管道阶段必须具有唯一的ID。但是,可以将不同的实例myHashingTF1和myHashingTF2(均为HashingTF类型)放置到同一管道中,因为将使用不同的ID创建不同的实例。
参数
MLlib Estimators和Transformers使用统一的API来指定参数。
参数是具有独立文件的命名参数。 ParamMap是一组(参数, 值)对。
将参数传递给算法的主要方法有两种:
- 设置实例的参数。例如,如果lr是LogisticRegression的实例,则可以调用
lr.setMaxIter(10)
以使lr.fit()
最多使用10次迭代。该API与spark.mllib
软件包中使用的API相似。 - 将ParamMap传递给
fit()
或transform()
。 ParamMap中的任何参数都将覆盖以前通过setter
方法指定的参数。
参数属于Estimators和Transformers的特定实例。例如,如果我们有两个LogisticRegression实例lr1和lr2,则可以使用指定的两个maxIter参数构建ParamMap:ParamMap(lr1.maxIter-> 10, lr2.maxIter-> 20)
。如果Pipeline中有两个算法的maxIter
参数,这种方法就很适用。