11.5.3 分类与回归
分类与回归是监督式学习的两种主要形式。
监督式学习指算法尝试使用有标签的训练数据(也就是已知结果的数据点)根据对象的特征预测结果。
分类和回归的区别在于预测的变量的类型:
- 在分类中,预测出的变量是离散的(也就是一个在有限集中的值,叫作类别);
比如,分类可能是将邮件分为垃圾邮件和非垃圾邮件,也有可能是文本所使用的语言。 - 在回归中,预测出的变量是连续的(例如根据年龄和体重预测一个人的身高)。
分类和回归都会使用 MLlib 中的 LabeledPoint 类。这个类在 mllib.regression 包中。
一个 LabeledPoint 其实就是由一个 label ( label 总是一个 Double 值,不过可以为分类算法设为离散整数)和一个 features 向量组成。
线性回归
线性回归是回归中最常用的方法之一,是指用特征的线性组合来预测输出值。
MLlib 也支持 L1和 L2的正则的回归,通常称为 Lasso 和 ridge 回归。
线性回归算法可以使用的类包括 mllib.regression.LinearRegressionWithSGD 、 LassoWithSGD 以及 RidgeRegressionWithSGD 。
- 这遵循了 MLlib 中常用的命名模式,即对于涉及多个算法的问题,在类名中使用“With”来表明所使用的算法。
这里,SGD 代表的是随机梯度下降法。
这些类都有几个可以用来对算法进行调优的参数。
- numIterations
要运行的迭代次数(默认值: 100 )。 - stepSize
梯度下降的步长(默认值: 1.0 )。 - intercept
是否给数据加上一个干扰特征或者偏差特征——也就是一个值始终为 1 的特征(默认值: false )。 - regParam
Lasso 和 ridge 的正规化参数(默认值: 1.0 )。
调用算法
- 在Java和Scala中, 你需要创建一个LinearRegressionWithSGD 对象,调用它的 setter 方法来设置参数,然后调用 run() 来训练模型。
- 在 Python 中,你需要使用类的方法 LinearRegressionWithSGD.train() ,并对其传递键值对参数。
在这两种情况中,你都需要传递一个由 LabeledPoint 组成的 RDD。
代码示例
逻辑回归
逻辑回归是一种二元分类方法,用来寻找一个分隔阴性和阳性示例的线性分割平面。
在 MLlib 中,它接收一组标签为 0 或 1 的 LabeledPoint ,返回可以预测新点的分类的 LogisticRegressionModel 对象。
代码示例
支持向量机
支持向量机(简称 SVM)算法是另一种使用线性分割平面的二元分类算法,同样只预期 0 或者 1 的标签。
通过 SVMWithSGD 类,我们可以访问这种算法,它的参数与线性回归和逻辑回归的参数差不多。
返回的 SVMModel 与 LogisticRegressionModel 一样使用阈值的方式进行预测。
代码示例
朴素贝叶斯
朴素贝叶斯(Naive Bayes)算法是一种多元分类算法,它使用基于特征的线性函数计算将一个点分到各类中的得分。
这种算法通常用于使用 TF-IDF 特征的文本分类,以及其他一些应用。
MLlib 实现了多项朴素贝叶斯算法,需要非负的频次(比如词频)作为输入特征。
在 MLlib 中,你可以通过 mllib.classification.NaiveBayes 类来使用朴素贝叶斯算法。
它支持一个参数 lambda (Python 中是 lambda_ ),用来进行平滑化。
你可以对一个由 LabeledPoint 组成的 RDD 调用朴素贝叶斯算法,对于 C 个分类,标签值范围在 0 至 C-1 之间。
代码示例
决策树
决策树是一个灵活的模型,可以用来进行分类,也可以用来进行回归。
决策树以节点树的形式表示,每个节点基于数据的特征作出一个二元决定,而树的每个叶节点则包含一种预测结果。
决策树的吸引力在于模型本身容易检查,而且决策树既支持分类的特征,也支持连续的特征。
在 MLlib 中,你可以使用 mllib.tree.DecisionTree 类中的静态方法 trainClassifier() 和 trainRegressor() 来训练决策树。
该训练方法接收如下所列参数。
-
data
由 LabeledPoint 组成的 RDD。 - numClasses (仅用于分类时)
要使用的类别数量。 - impurity
节点的不纯净度测量;对于分类可以为 gini 或 entropy ,对于回归则必须为 variance 。 - maxDepth
树的最大深度(默认值: 5 )。 - maxBins
在构建各节点时将数据分到多少个箱子中(推荐值: 32 )。 - categoricalFeaturesInfo
一个映射表,用来指定哪些特征是分类的,以及它们各有多少个分类。
MLlib 的在线文档 中包含了对此处所使用算法的详细解释。
算法的开销会随训练样本数目、特征数量以及 maxBins 参数值进行线性增长。
对于大规模数据集,你可能需要使用较低的 maxBins 值来更快地训练模型,尽管这也会降低算法的质量。
代码示例
随机森林
MLlib 在 Java 和 Scala 中添加了试验性的 RandomForest 类,可以用来构建一组树的组合,也被称为随机森林。
它可以通过 RandomForest.trainClassifier 和 trainRegressor 使用。
除了刚才列出的每棵树对应的参数外, RandomForest 还接收如下参数。
-
numTrees
要构建的树的数量。提高 numTrees 可以降低对训练数据过度拟合的可能性。 - featureSubsetStrategy
在每个节点上作决定时需要考虑的特征数量。可以是 auto (让库来自动选择)、 all 、 sqrt 、 log2 以及 onethird ;越大的值所花费的代价越大。 - seed
所使用的随机数种子。
随机森林算法返回一个 WeightedEnsembleModel 对象,其中包含几个决策树(在 weakHypotheses字段中,权重由 weakHypothesisWeights 决定),可以对 RDD 或 vector 调用 predict() 。
它还有一个 toDebugString 方法,可以打印出其中所有的树。