前面跟大家扯了这么多废话,终于到具体的机器学习模型了。大部分机器学习的教程,总要从监督学习开始讲起,而监督学习的众多算法当中,又以分类算法最为基础,原因在于分类问题非常的单纯直接,几乎不需要引入一些其它概念,因此我们就先从分类器开始讲起。
还记得第一节介绍的Spark ML架构吗?从Param起始,Spark ML通过PipelineStage引入了三个基本概念,Transformer,Estimator,Model,其中T和E本质上都是PipelineState,E能够产生M,而M本质上又是一个T,因此M是连接T和E的桥梁。又由于监督学习问题本质上都是为了做出“预测”,因此给出了一个监督学习的模板,Predictor,Predictor家族有三个成员,第一是PredictorParam,包含了这个预测器必须包含的参数,第二是Predictor本身,它是一个混入了PredictorParam的Estimator,第三是PredictorModel,它是一个混入了PredictorParam的Model。因此,通过预测器模板Predictor,我们了解到,一个具体的预测器一定要包含三个部分:Param,Predictor,Model。其中Param用以规定,这个预测器需要包含的特殊参数,Predictor是一个Estimator,用于实际执行算法,PredictorModel是一个数据结构,用于保存算法结果。我们看到,Predictor和PredictorModel都包含了PredictorParam这个结构,说明它们都包含了同样的预测器的参数。
这样我们在介绍分类器的时候,就有一个整体框架了。分类器本身也是一个预测器,它同样包含了三要素,参数、学习器、模型,在我们深入学习分类器的代码时会发现,几乎所有的分类器都明确定义了自己的三个要素。
在classification文件夹下面,包含了两类分类器,第一类是虚拟分类器。虚拟分类器并不执行任何具体的分类任务,它们是为不同的分类器准备模板。这其中最基本的一个模板就是Classifier,它是所有分类器的模板,它直接继承自Predictor,同时也包含了Predictor三要素。我们知道,分类器按照是否能输出分类概率,又可以分为概率性分类器和非概率分类器,概率性的分类器除了能输出分类结果之外,还能输出选择该分类的概率,比如逻辑回归、朴素贝叶斯等,另外一类是非概率分类器,比如线性支持向量机。对于概率类的分类器,这里专门给出了一个抽象,就是ProbabilisticClassifier,提供了输出分类选择概率的功能。另外,针对多分类问题,给出了OneVsRest分类器,它其实相当于一种分类器的策略,并不能算是一个单独的分类器。
第二类就是具体分类器,刚才提到了,这里的具体分类器中,除了LinearSVC线性支持向量机分类器之外,其它都是概率性的分类器。因此这里我们先介绍LinearSVC的实现。
说起支持向量机,很多人会想到SMO算法,但实际上针对线性可分问题,在用线性支持向量机解决时,根本用不着对偶化,因为线性支持向量机,本身就可以被看做是一个有Hinge损失的线性分类问题,因此这里直接使用了optim模块的HingeAggregator。
剩下的就是概率性的分类器,首先要介绍的是决策树分类器,它需要用到另外一个tree模块(多说一句,Spark ML对于决策树的核心算法都包含在tree模块中,其使用的分布式计算思路与广义线性模型非常不同,我们将在后面的随笔中介绍),需要注意的是,Spark ML包中决策树分类器其实就是随机森林分类器的一个特例,当森林中树的数量为1时,就是决策树分类器。因此同随机森林分类器一样,我们在介绍tree模块的时候再详细讨论它们的实现。另外,由于GBTClassifier也需要用到tree模块中的树的实现,因此也放在后面讲。
接下来就是LogisticRegressionClassifier,它包含了二类分类和多类分类两种实现。前面我们在介绍机器学习算法从单机到分布式的转换时,提到了关键是treeAggregator这个函数,而在逻辑回归中,就用到了在optim模块中实现的LogisticAggregator。具体的学习算法,都是使用的breeze库中的优化算法,比如,当正则是L2时,选择LBFGS,当正则是L1是,选择OWLQN,当正则是L2且w参数受限(设置了最大值或/和最小值)时,使用LBFGSB。
接下来是感知机分类器,MultilayerPerceptronClassifier,它的实现需要依赖ann库中的神经网络实现,这里我们也不作探讨。最后是朴素贝叶斯分类器,NaiveBayes,这个分类器本质上是基于统计的,不需要优化计算。
以上就是对分类器模块的介绍,重在理清框架,说的不对的地方,还请各位批评指正。