研究机器学习之MLlib实践经验
本文主要讨论是用MLlib进行Classification工作。典型的应用场景就是AD CTR Prediction,也就是大部分互联网公司的利润来源。据业余了解,广告CTR预估使用最多的基础算法还是L1正则化的Logistic Regression。
机器学习任务主要分为两种:Supervised Machine Learning 和 Unsupervised Machine Learning。其中Supervised Machine Learning主要包括Classification和Regression,Unsupervised Machine Learning主要包括Clustering。除了这些核心的算法以外,还有一些辅助处理的模块,例如Preprocessing, Dimensionality Reduction, Model Selection等。
目前最新的Spark 1.1.0版本中MLlib主要还是对核心算法的支持,辅助处理模块还很不完善。源代码包和其功能的对应关系如下:
Classification/Clustering/Regression/Tree | 分类算法、回归算法、决策树、聚类算法 |
Optimization | 核心算法的优化方法实现 |
STAT | 基础统计 |
Feature | 预处理 |
Evaluation | 算法效果衡量 |
Linalg | 基础线性代数运算支持 |
Recommendation | 推荐算法 |
本文主要讨论是用MLlib进行 Classification工作。分类是机器学习最基础的工作,典型的应用场景就是AD CTR Prediction,也就是大部分互联网公司的利润来源。据业余了解,广告CTR预估使用最多的基础算法还是L1正则化的Logistic Regression。
下面一步一步来看看使用MLlib进行Classification机器学习。
1、分类算法原理与MLlib的实现
首先需要了解机器学习和MLlib的基础知识和原理,大家可以参考 http://spark.apache.org/docs/latest/mllib-Linear-Methods.html 。本文主要从工程实践的角度讨论如何使用和调优。
分类问题主要包括Binary Classification 和 Multiclass Classification。目前的MLlib只支持Linear Classification问题,这里讨论的也都是线性分类问题,不涉及到Kernel Method等。目前MLlib里面的Classification算法最常用的就是LR,SVM和Tree/RF。其中LR和SVM目前只支持 Binary Classification,Tree/RF支持Multiclass Classification。本文主要讨论使用LR和SVM进行线性Binary Classification问题的实践中遇到的一些问题。
抽象来看LR和SVM算法都是通过指定Loss Function和Gradient/SUB-Gradient,然后通过Optimization算法(SGD或LBFGS)求使得Loss Function最小的凸优化问题,最后得出的解是一个Weights向量。从代码中也可以看出,LR和SVM算法仅仅是指定的Loss Function和Gradient是不同的,其求解最小值的过程是通用的,所以求解最小值的过程抽象出了Optimization模块,目前主要有 SGD和LBFGS两种实现。
为了防止过拟合,需要在Loss Function后面加入一个正则化项一起求最小值。正则化项相当于对Weights向量的惩罚,期望求出一个更简单的模型。 MLlib目前支持两种正则化方法L1和L2。 L2正则化假设模型参数服从高斯分布,L2正则化函数比L1更光滑,所以更容易计算;L1假设模型参数服从拉普拉斯分布,L1正则化具备产生稀疏解的功能,从而具备Feature Selection的能力。
2、两种Optimization方法SGD和LBFGS
有了上面的数学基础,现在就是求取一个函数的最小值问题了。MLlib里面目前提供两种方法SGD和LBFGS。关于这两种算法的原理,大家可以参考 http://spark.apache.org/docs/latest/mllib-Optimization.html 。这两种优化方法的核心都是RDD的aggregate操作,这个从Spark Job运行时的UI中可以看出,SGD/LBFGS每迭代一次,aggregate执行一次,Spark UI中出现一个stage。下面分别看看两种优化算法具体怎么实现的。
SGD:
核心实现在GradientDescent.runMiniBatchSGD函数中