Spark机器学习管道

机器学习流程在本质上是一个由一系列以顺序方式运行的步骤所组成,相同的步骤经常以相同的顺序重复出现,通常需要重复几次才能到达一个最佳的模型。实现机器学习模型的步骤以及每个阶段的操作和输入/输出如下图所示:

Spark 1.2引入了机器学习管道API,包括Transformer、Estimator和Evaluators。Spark使用Transformer来实现将一个数据集转换成另一个数据集的机器学习组件。Estimators通过在数据集上进行拟合来生成Transformer。Evaluator用来评估模型的性能。它们可以组合成管道(pipeline)。机器学习管道API简化了数据分析和机器学习应用程序的实现。

1. 机器学习管道

在Spark中,使用Transformer来实现将一个数据集转换成另一个数据集。Spark ML中的机器学习模型就是一个Transformer,它们通过添加预测来转换数据集。实现这种转换的主要方法是transform(),它接受一个DataFrame和一个可选的参数集。

Estimator通过在数据集上进行拟合来生成Transformer。例如,线性回归算法产生了一个线性回归模型,该模型具有拟合的权重和截距,它就是一个Transformer。使用Estimator的主要方法是fit(),该方法也需要一个DataFrame和一组可选的参数。

Evaluator根据一个度量来评估模型的性能。例如,RegressionEvaluator(回归模型的Evaluator)可以使用RMSE和MSE等作为模型的评价指标。

下图显示了Transformer、Estimator和Evaluator的操作方法以及它们的输入和输出。

在Spark ML中,机器学习工作流被实现为由一系列阶段组成的管道。每个管道阶段由按指定顺序执行的Transformer或Estimator组成。下图描述了机器学习过程中的核心步骤和Spark MLlib提供的主要组件之间的相似性。

在机器学习中,通常运行一系列步骤来清理和转换数据,然后训练一个或多个ML算法来从数据中学习,最后调整模型以获得最佳的性能。Spark ML中的管道(pipeline)抽象设计是为了使这个工作流更易于开发和维护。

从技术的角度来看,Spark ML有一个名为Pipeline的类,它被设计用来管理一系列的阶段,每一个阶段都由PipelineStage来表示。一个PipelineStage既可以是Transformer,也可以是Estimator。抽象Pipeline是一种Estimator。管道以指定的顺序连接多个Transformer和Estimator,形成机器学习工作流。从概念上讲,它将机器学习工作流中的数据预处理、特征提取和模型训练步骤链接在一起。

2. Transformer

Transformer是一个算法,用来将一个输入DataFrame转换到另一个DataFrame,并向其添加一个或多个特征。Transformers的设计目的是通过在特征工程步骤和模型评估步骤中操作一个或多个列来转换DataFrame中的数据。转换过程是在构建特征的上下文中,这些特征将被ML算法用于学习。这个过程通常涉及添加或删除列(特征),将列值从文本转换为数值,或者规范化某一列的值。

从技术的角度来看,Transformer有一个transform()方法,它在的原始数据的输入列上执行转换,结果存储在输出列中。在Transformer的构造过程中可以指定输入列和输出列名称。如果没有指定,则使用默认列名("inputCol","outputCol")。

Spark ML提供两种类型的Transformers:特征Transformer和机器学习模型Transformer。

一个特征Transformer通过对输入数据集中的一个列应用转换来创建一个或多个新列,并返回一个附加了新列的新DataFrame。例如,如果输入数据集有一个包含句子的列,则可以使用特征Transformer将句子拆分为单词,并创建一个新的列,该列将单词存储在数组中。

一个模型Transformer代表一个机器学习模型。它接受一个DataFrame作为输入,并输出带有每个输入特征向量的预测标签的新DataFrame。输入数据集必须具有包含特征向量的列。模型读取包含特征向量的列,为每个特征向量预测一个标签,并返回一个新的DataFrame,其中预测标签作为新列附加。

下图描述了Transformer的工作模式,DF1中的阴影部分表示输入列,DF2的阴影部分表示输出列。

Transformer以某种方式转换原始数据。这可能是创建一个新的交互变量,或者规范化一列,或者简单地将一个整数转换为Double类型,以便输入到模型中。

Transformer主要用于机器学习流程中的数据预处理和特征工程阶段。

3. Estimator

一个Estimator代表了一种机器学习算法,用来在训练数据集上训练或拟合机器学习模型。它实现了一个名为fit()的方法,该方法接受一个DataFrame作为参数并返回一个机器学习模型。

Estimator所代表的算法可分为两类,一类是用于机器学习的算法,另一类是一种用数据初始化的Transformer。例如,称为LinearRegression的线性回归算法就属于第一种类型,它的fit()方法返回一个LinearRegressionModel类的实例,可用于诸如预测房价等回归任务。而StringIndexer就属于第二种类型,它用来将一列的分类值编码成索引,这样每个分类值的索引值都是基于它出现在DataFrame的整个输入列中的频率。

从技术的角度来看,一个Estimator有一个名为fit()的方法,它在输入列上应用一个算法,结果被封装在一个叫做Model的对象类型中,它是一个Transformer类型。输入列和输出列名称可以在Estimator的构造过程中指定。下图描述了一个Estimator及其输入和输出。

4. 模型评估

人们需要评价各种机器学习算法和模型的好坏,以进行比较,因此,需要定义衡量模型精度的指标。

比较算法的优劣需要使用算法的评价指标。对于分类问题,常用的评价指标是准确率,它定义为测试样本集中被正确分类的样本数与测试样本总数的比值;对于回归问题,常用的评价指标是回归误差,定义为预测函数输出值与样本标签值之间的均方误差。二分类问题由于其特殊性,我们为它定义了精度与召回率指标,在此基础上可以得到ROC曲线。对于多分类问题,常用的评价指标是混淆矩阵。

泛化能力是衡量有监督学习算法的核心标准。与模型泛化能力相关的概念有过拟合与欠拟合,对泛化误差进行分解可以得到方差与偏差的概念。正则化技术是解决过拟合问题的一种常见方法,例如岭回归算法。

对于二分类问题,我们可以调整分类器的阈值(即灵敏度)从而得到不同的分类结果(计算各种假阳率下对应的真阳率)。将各种灵敏度下的准确率指标连成一条曲线,就是ROC曲线(Receiver Operator Characteristic Curve,接收机操作曲线)。

随着阈值的增大,被判定为正样本的样本数会增加,因此,真阳率会提高;但同时负样本被判定为正样本的数量也会增加,假阳率也会上升。

除了上面定义的这些通用指标,对于某此特定的问题还有特定的精度指标,例如,机器翻译、图像分割等问题都有自己的评价指标,在此就不展开了。

5. 模型调优

在训练集上学习得到的模型能否有效地用于测试集,衡量指标为泛化能力(泛化能力是指模型从训练集推广到测试集的能力)。泛化能力差的情况下又分为欠拟合和过拟合两种情况。

过拟合是有监督学习算法长期以来需要解决的一个问题。

有监督学习训练模型的目标模型是在训练集上误差最小化。模型的泛化误差可以分解成偏差(bias)和方差(variance)。模型的总体误差可以分解为偏差的平方与方差之和。

偏差是模型本身导致的误差,即错误的模型假设所导致的误差,它是模型的预测值的数学期望和真实值之间的差距。高偏差意味着模型本身的输出值与期望值差距很大,因此会导致欠拟合问题。

方差是由于对训练样本集的小波动敏感而导致的误差。它可以理解为模型预测值的变化范围,即模型预测值的波动程度。高方差意味着算法对训练样本集中的随机噪声进行建模,从而出现过拟合问题。

如果模型过于简单,一般会有大的偏差和小的方差;反之,如果模型复杂则会有大的方差但偏差很小。这是一对矛盾,因此需要在偏差和方差之间做一个折中。

正则化

通常用损失函数(也叫误差函数)来表示目标模型在训练集上的误差。有监督机器学习算法训练的目标是最小化损失函数。在损失函数的类型选定之后,人们能控制的只有函数的参数。为了防止过拟合,可以为损失函数加上一个惩罚项,对复杂的模型进行惩罚,强制让模型的参数值尽可能小以使得模型更简单。

惩罚项部分被称为正则化项。正则化项可以使用L2范数(即平方和),也可以使用其他范数(如L1范数,即绝对值之和)。L2范数在求解最优化问题时计算简单,而且有更好的数学性质。与L2相比,L1正则化能更有效地让参数趋向于0,产生的结果更稀疏。例如,岭回归算法就是带L2正则化项的线性回归算法,而LASSO回归算法就是带L1正则化项的线性回归算法。

除了直接加上正则化项之外 ,还有其他强制让模型变简单的方法,如决策树的剪枝算法、神经网络训练中的dropout技术、提前终止技术等。


《Spark原理深入与编程实战》