Libsvm学习心得
快,关注这个公众号,一起涨姿势~
最近遇到一些数据分析问题要用到SVM,而之前介绍过的WEKA软件不能满足需求,所以开始研究libsvm程序包。(首先声明,我是刚开始学习,以下内容是学习过程的总结,希望可以和大家分享和探讨,有不对的地方欢迎指出。)
LibSVM是台湾林智仁(Chih-Jen Lin)教授2001年开发的一套支持向量机的库,这套库运算速度还是挺快的,可以很方便的对数据做分类或回归。由于libSVM程序小,运用灵活,输入参数少,并且是开源的,易于扩展,因此成为目前国内应用最多的SVM的库。下载网址:http://www.csie.ntu.edu.tw/~cjlin/
问题一
第一个遇到的问题是在Matlab中安装。Windows系统的话就不用说了,很简单,下载后setpath即可。而对于Mac系统则颇费周折,详细的安装指南可以参考:http://www.jianshu.com/p/e0275a380803
经本人测试可以顺利安装。
问题二
第二个则是libsvm函数与Matlab自带SVM函数冲突。我们知道,Matlab本身是有svmtrain函数的,该函数与libsvm相比存在以下几个差别:
1. 自带函数仅有C-SVC模型,而libsvm工具箱有C-SVC(C-support vector classification),nu-SVC(nu-support vector classification),one-class SVM(distribution estimation),epsilon-SVR(epsilon-support vector regression),nu-SVR(nu-support vector regression)等多种模型可供使用。
2. 自带函数仅支持分类问题,libsvm支持分类和回归问题。
3. 自带函数只是针对二分类问题,多分类问题需按照多分类的相应算法编程实现;而libsvm采用1v1算法支持多分类。
4. 自带函数采用RBF核函数时无法调节核函数的参数gamma,貌似仅能用默认的;而libsvm可以进行该参数的调节。
如果安装好libsvm后直接调用svmtrain(),用的还是MATLAB自带的函数。解决方法如下:
libsvm指南学习
准备就绪后,接下来便是学习libsvm包中的Guide文件,受益匪浅。简单总结几个Tips如下:
1. 操作步骤:一般初学者的操作步骤是:数据转换成SVM包要求的形式;随机尝试一些kernel和参数;测试。而指南推荐的步骤是:数据转换成SVM包要求的形式;进行简单的scale;推荐RBF kernel;通过交叉验证找到最佳参数值(C和gamma);使用得到的最佳参数训练整个训练集;测试。
2. 对于多分类问题,例如三分类,推荐使用(0,0,1),(0,1,0)和(1,0,0)来表示label。文中解释是因为,当一个attribute的值不是很大时,这种coding的方式更稳定。
3. 关于scaling。在做SVM时,数据标准化是必不可少的,指南推荐使用线性scaling将每个attribute归一化至[-1,+1]或[0,1],包括训练集和测试集。需要注意的是,训练集和测试集最好使用相同的scale。
4. 关于RBF kernel。一般情况下是首选。在一些特殊情况时,选择linear kernel,包括:instance数远小于feature数时;instance数与feature数都很大时;instance数远大于feature数时。
5. 关于交叉验证(cross validation, CV)和格点搜索(grid-search)。因为最开始我们并不知道对于给定的问题,什么参数设置最合适,因此应该通过grid-search的方法结合交叉验证找到最优参数。一般是使用指数递增的方法寻找最优参数,例如,C = 2^-5; 2^-3; ... ; 2^15, gamma = 2^-15; 2^-13; ...; 2^3.
关于SVM多分类问题的补充
目前,构造SVM多类分类器的方法主要有两类:一类是直接法,直接在目标函数上进行修改,将多个分类面的参数求解合并到一个最优化问题中,通过求解该最优化问题“一次性”实现多类分类。这种方法看似简单,但其计算复杂度比较高,实现起来比较困难,只适合用于小型问题中;另一类是间接法,主要是通过组合多个二分类器来实现多分类器的构造,常见的方法有one-against-one和one-against-all两种。
a.一对多法(one-versus-rest,简称OVR SVMs)。训练时依次把某个类别的样本归为一类,其他剩余的样本归为另一类,这样k个类别的样本就构造出了k个SVM。分类时将未知样本分类为具有最大分类函数值的那类。
假如我有四类要划分(也就是4个Label),他们是A、B、C、D。于是我在抽取训练集的时候,分别抽取A所对应的向量作为正集,B,C,D所对应的向量作为负集;B所对应的向量作为正集,A,C,D所对应的向量作为负集;C所对应的向量作为正集, A,B,D所对应的向量作为负集;D所对应的向量作为正集,A,B,C所对应的向量作为负集,这四个训练集分别进行训练,然后的得到四个训练结果文件,在测试的时候,把对应的测试向量分别利用这四个训练结果文件进行测试,最后每个测试都有一个结果f1(x),f2(x),f3(x),f4(x).于是最终的结果便是这四个值中最大的一个。
note:这种方法有种缺陷,因为训练集是1:M,这种情况下存在biased.因而不是很实用.
b.一对一法(one-versus-one,简称OVO SVMs或者pairwise)。其做法是在任意两类样本之间设计一个SVM,因此k个类别的样本就需要设计k(k-1)/2个SVM。当对一个未知样本进行分类时,最后得票最多的类别即为该未知样本的类别。Libsvm中的多类分类就是根据这个方法实现的。
还是假设有四类A,B,C,D四类。在训练的时候我选择A,B; A,C; A,D; B,C; B,D;C,D所对应的向量作为训练集,然后得到六个训练结果,在测试的时候,把对应的向量分别对六个结果进行测试,然后采取投票形式,最后得到一组结果。
投票是这样的.
A=B=C=D=0;
(A, B)-classifier 如果是A win,则A=A+1;otherwise,B=B+1;
(A,C)-classifer 如果是A win,则A=A+1;otherwise, C=C+1;
...
(C,D)-classifer 如果是A win,则C=C+1;otherwise,D=D+1;
The decision is the Max(A,B,C,D)
note:这种方法虽然好,但是当类别很多的时候, model的个数是n*(n-1)/2,代价还是相当大的.
c.层次支持向量机(H-SVMs)。层次分类法首先将所有类别分成两个子类,再将子类进一步划分成两个次级子类,如此循环,直到得到一个单独的类别为止。
在此,感谢西安电子科技大学焦志成博士、西北工业大学夏勇教授和谢雨桐博士、第四军医大学张曦讲师、第四军医大学唐都医院张欣博士对我这段时间的指导和帮助。
父母的世界很小,只装满了我们。我们的世界很大,常忽略了他们。他们经常忘了我们已经长大,就像我们经常忘了他们,已经渐渐白发。这个世界上,再也没有任何人,可以像父母一样,爱我们如生命。 愿天下所有的父亲,父亲节日快乐、健康长寿!
长|按|二|维|码|关|注
往期精彩内容: