LIBSVM与LIBLINEAR(一)

本文转自:http://orangeprince.info/2014/11/22/libs...

由于作者不明,未能附上其姓名,深表歉意。由于原文网站并不稳定,借此机会进行转载,希望优秀的文章能够多留存下来。

本文讲解很有深度,更有趣味性,适合对SVM的应用有一定了解的人。
其后续文章(二)(三)适合对SVM理论有所理解的人。


在过去的十几年里,支持向量机(Support Vector Machines)应该算得上是机器学习领域影响力最大的算法了。而在SVM算法的各种实现工具中,由国立台湾大学林智仁老师开发的工具包LIBSVM,又无疑是影响力最大的。2011年LIBSVM的系统介绍论文"LIBSVM: a library for support vector machines”发表在了期刊ACM TIST(ACM Transactions on Intelligent Systems and Technology)上。

2011年的时候,这个期刊的影响因子还不到1,但到了2014年,它的影响因子居然达到了9.39,把TPAMI都甩出了一大截。这其中贡献最大的当然是关于LIBSVM的这篇论文,在google scholar上,这篇文章的引用量居然已经接近20000,着实吓人。仔细想来其实也并不奇怪,各种研究工作,只要涉及到分类,大部分都会用到SVM算法或者与SVM的算法进行对比,而此时LIBSVM往往是首选工具。其实不但是学术界,在工业界LIBSVM也有非常广泛的应用。这一方面得益于算法实现的稳定与高效,另一方面也是因为LIBSVM提供了丰富的接口与灵活的使用方式。一些非常有名的机器学习工具,如基于java的Weka和基于python的scikit-learn,其提供的SVM算法在底层也是基于LIBSVM的实现。

几年前参加过一个机器学习的学习班,主讲人是CMU的Eric Xing老师。在提问环节,大家都在讨论一些高深的理论问题,突然有一个女生举手提问主讲人如果要用SVM的话有什么工具推荐使用。这个问题在当时的场景似乎有点不合时宜,Eric Xing老师回答说他们CMU从来不用别人的库,所有的算法代码都是自己实现的云云。后来那次讲座上其他的东西我都不太记得了,印象最深的就变成了这个问答。现在想来,如果从算法学习角度,自己实现这些算法对于理论的理解和工程能力的提升都是大有好处。

但是对于绝大部分人来说,自己动手实现的SVM算法在效率和扩展性上,还是会和LIBSVM的算法实现存在不小的差距,毕竟人家的程序是千锤百炼中产生的。如果单纯为了使用的话,一个大家都认可的好工具绝不失为一个很好地选择。但是,有一个好的工具并不等于我们可以对算法与实现一无所知而把所有的事情都交给工具。相反,如果我们能够很好地了解算法与实现中的一些背景知识,可以更好地使用这些工具。此外,LIBSVM与他的姊妹工具LIBLINEAR提供了丰富的优化与参数选项,通过选择适当的方法,也可以大大提高我们的工作效率。因此,下面总结一些在我之前的工作中遇到的一些与LIBSVM和LIBLINEAR相关的重要问题,希望能够为读者对这些工具的使用有所帮助。

LIBSVM与LIBLINEAR的关系

这是很多刚开始使用SVM的人容易弄混淆的问题。简单来说,LIBSVM是一套完整的SVM模型实现。用户可以在LIBSVM中使用核函数来训练非线性的分类器,当然也能使用更基础的线性SVM。而LIBLINEAR是一个针对线性分类场景而设计的工具包,除了支持线性SVM外,还支持线性的Logistic Regression等模型,但是无法通过定义核函数方式实现非线性的分类器。由于支持核函数的扩展,LIBSVM理论上具有比LIBLINEAR更强的分类能力,能够处理更为复杂的问题。

但是,很多人因此就只使用LIBSVM,甚至最简单的线性分类器都是用LIBSVM来训练和预测,这也是不可取的。因为LIBLINEAR设计的初衷就是为了提高线性分类的效率,其优化算法与LIBSVM中的优化算法有着根本的区别。虽然在进行线性分类时LIBSVM和LIBLINEAR都可以达到类似的结果,但是LIBLINEAR无论是在训练上还是在预测上,都比LIBSVM高效得多。此外,受限于算法,LIBSVM往往在样本量过万之后速度就比较慢了,如果样本量再上升一个数量级,那么通常的机器已经无法处理了。但使用LIBLINEAR,则完全不需要有这方面的担忧,即便百万千万级别的数据,LIBLINEAR也可以轻松搞定,因为LIBLINEAR本身就是为了解决较大规模样本的模型训练而设计的。

虽然搞清楚了两者主要的区别,但我在刚刚接触这些工具时,一直很疑惑为什么两个紧密相关算法,却演化出两个彼此独立的工具包。而让我更加不解的是,LIBSVM早在2000年就已经发布了,而LIBLINEAR直到2007年才发布第一个版本。根据常识,应该是先有一个简单的工具,然后再逐渐完善,但是功能更加强大的LIBSVM却早于LIBLINEAR很久发布。要回答这个问题,还得从机器学习以及SVM的历史说起。

早期的机器学习分类算法可以追溯到Perception(感知机)。Perception的基本思想和Logistic Regression类似,只不过是用在线学习的方法训练出一个线性分类器。在UCI数据集 中可以看到很多80年代到90年代初期用于机器学习研究的数据。可以看出,这其中的很多问题都非常复杂,比如图像或者语音的识别。但是另一方面,受限于当时获取数据与计算存储能力的限制,这些数据集的规模通常非常的小,有的只有几千甚至几百个样本。对于这样相对复杂的问题,可以想到将特征直接用简单的线性分类器进行分类,肯定不会取得太好的效果。这个时候,机器学习领域一个里程碑Multi-Layer Neural Networks(多层神经网络)出现了。多层神经网络引入了Hidden Layer (隐含层),模型的表达能力大大增强,可以训练出各种复杂的分类器。然而神经网络也有一个致命的弱点,由于模型本身的局限性,非常容易过拟合,尤其是在训练样本量较少的情况下。

而这时SVM应运而生,完美的解决了这个问题。一方面,SVM的目标函数是一个凸函数,可以保证得到问题的全局最优解,避免了神经网络优化频繁陷入局部最优的困扰。另一方面,SVM的背后有一套结构化风险最小化的理论,给定了训练样本和训练参数,是可以从理论上计算出模型在真实数据上误差的bounds。在SVM中,通过对参数的调节和样本量的选择,可以在模型方差与训练误差之间方便的做出权衡。此外,SVM可以定义不同的核函数来构造非线性分类器,可以得到与神经网络方法大体相当的分类能力,从而适应不同的问题。因此,在上个世纪末到这个是基础,SVM横扫了各种分类的应用场景,成为了当时最炙手可热的机器学习算法。

然而,SVM也存在局限性。首先,基于核函数的SVM求解相对比较复杂,需要存储一个稠密的样本间Kernel矩阵,当样本量很大时,存储量相当可观。而到目前为止,一直没有一个非常有效的并行SVM训练方法能够从根本上提升SVM模型的训练。在十几年前,样本量最多只是上万级别的时候,这个问题并不显得重要。但是在十多年后,随着互联网的爆炸式发展,随便一个模型的训练样本量都可能数以亿计,这时SVM在大数据训练上的不足就凸显无疑了。

SVM之所以效果好,主要是得益于非线性核函数的引入。但是新的问题不断出现,而这些问题又涉及到的不同领域知识与业务场景,很多时候仅仅依靠常见的几种kernel函数并不能解决问题。但是SVM本身过分依赖于核函数,而核函数又存在着很多的限制,其灵活性当然不如人工的特征构造方法。

另一方面,随着数据量的不断增加,即使这些样不能直接被标注用于模型的训练,但是可以很多机器学习方法可以从大量的样本中进行特征的自动学习。比如早年的流形学习,还有文本上的主题模型,图像上的稀疏编码与字典学习等。通过这些非线性的方法学习的样本特征,往往已经是样本的高层语义表达,有数据充足的情况下,只需要使用较为简单的线性分类器,就可以达到比较好的效果。这时的主要矛盾变成了分类器必须有能力处理足够大量的样本,而在方法上,可以是简单地现行方法。也就是在这个时候,LIBLINEAR应运而生。

在LIBSVM诞生的时代,SVM的核函数带来的非线性模型是SVM的主要优势之一,且当时的样本量还不是瓶颈。因此LIBSVM的整体框架都是针对训练Kernel SVM模型来训练的。但是如果只是需要训练一个线性的SVM模型,那么算法可以简单的多,也可以高效的多。因此LIBLINEAR在保持基本接口和调用方式一致的情况下,采用了新的训练算法,支持了线性SVM和Logistic Regression的训练。LIBSVM和LIBLINEAR的作者林智仁老师在后来的很多报告中,都在大力的推广LIBLINEAR,并且给出了很多实际的例子证明,人工构造特征+线性模型的方式可以达到甚至超过kernel SVM的表现,同时大大降低训练的时间和消耗的资源。

其实就在最近几年,情况又有了新的变化。人工构造特征+线性分类器的方式在很多问题上又遇到了瓶颈。与此同时,一方面可供使用数据量更大了,另一方面,计算机的计算能力又有了突飞猛进的增长。此时曾经被SVM狠狠压在地上的神经网络又重新焕发了生机。与SVM相比,神经网络模型的优势在于可以通过控制模型的层数和每一层函数的类型,设计出各种灵活的分类器。同时神经网络的优化算法比kernel SVM更适合并行化。当时影响神经网络发展的主要问题是计算资源的限制和样本量少引起的过拟合。但现在这两项限制都几乎不存在了。

基于GPU的并行计算技术现在已经比较成熟,可以支持高速的并行计算。而造成过拟合的原因从根本上说,是因为训练样本的比真实样本数少的太多,不能够反应真实的数据情况。但是如果把我们拥有的所有样本都作为训练样本,其实机会已经就是真实的样本集了,因此过拟合的事实基础就不存在了。虽然神经网络在理论上还有缺陷,但是通过计算能力和数据的增加,这些缺陷已经不是问题。正是因为上面的原因,这些年机器学习的热点又重新回到了神经网络。

1995年,SVM的发明人Vapnik和他在Bell实验室的老大Larry Jackel打过两个赌,而见证人是当时也在Bell而最近因为Deep Learning而声名鹊起的Yann Lecun。赌局的具体内容见下图:

LIBSVM与LIBLINEAR(一)_第1张图片

不管他们输赢与否,我们都能感觉到这门学科的变化之快。在神经网络大行其道的时候,很难想到半路杀出一个SVM将神经网络算法杀了一个体无完肤。而在SVM一统天下的时候,大部分人也不会相信神经网路居然还能最后等到逆袭的那一天。

仔细看每一次算法的革新,其实真正的推动力都是具体的问题需求与当时的技术条件。因此,脱离具体的应用场景去单纯比较算法的优劣并没有太多意义。对于使用者来说,最适合这个问题场景的算法就是最好的算法。具体到LIBSVM和LIBLINEAR,我尝试总结下面几个原则:

  • 凡是确定使用线性分类器的场景,一定使用LIBLINEAR而不是LIBSVM。

  • 如果样本量较大,比如达到10万以上的规模,这时LIBSVM已经很难处理了。如果线性分类器的效果实在不好,只能采用人工构造特征+LIBLINEAR的方式,或者采用其他的分类器,如神经网络,随机森林等。

  • 对于高维稀疏数据,典型的如文本的向量空间表示,一般都采用线性的分类器。

  • 对于样本量和维度都不算太大的问题,且没有对预测的效率有过分的需求,都可以用LIBSVM尝试一下kernel SVM的分类器,很多情况下用kernel SVM比直接用libear SVM还是能达到更高的精度。

你可能感兴趣的:(机器学习,libsvm,liblinear)