LIBSVM使用指南

来源:互联网 发布:wamp改mysql密码 编辑:程序博客网 时间:2024/06/04 18:51

LIBSVM是较为成熟的支持向量机的函数包(包含C\MATLAB\PYTHON\R等等)
下载网址:http://www.csie.ntu.edu.tw/~cjlin/libsvm/
本文内容基于其官网给出的《A Practical Guide to Support Vector Classication》


建议采用步骤(初学者):

(1)将数据转换为LIBSVM数据格式
LIBSVM数据格式即转换可参考:生成libSVM的数据格式及使用方法总结

事实上,即使不采用这种数据格式,也可以使用libsvm的函数,只是libsvm希望形成一个属于自己的标准,使得数据的使用更加规范化。

例如你使用的数据是500*11(样本属性)和500*1(样本标号)来训练分类器,调用svmtrain()函数也是没问题的。

(2)数据的缩放
数据缩放直白来说就是中心归一化,目的是使不同属性的取值范围接近,否则其对应的w权重相差较多,优化速度较慢。

以梯度下降法举个简单,例子假如样本只有两个属性[x1,x2],其分别对应权重theta1,theta2。如果x1,x2取值范围差距悬殊,theta1,theta2对应的取值范围为一个椭圆(如下图所示),要经历较长时间才达到极小值。
这里写图片描述
当x1,x2取值范围近似时,theta1,theta2取值范围如下,优化速度更快。
这里写图片描述


缩放过程很简单:
对于某一样本来说,该属性的更新值为减去属性均值,再除以标准差。
如下为对X进行缩放的MATLAB处理程序

  X_norm = function(x)   mu = mean(X,1);   sigma = std(X,0,1);   m = size(X,1);   n = size(X,2);   for i = 1:m   center(i,:) = X_norm(i,:) - mu;   end   for j = 1:n   X_norm(:,j) = center(:,j)/sigma;

载入MATLAB中的cancer_dataset;
样本数据 x :699*9 样本标号y∈{-1,+1}
分别在数据缩放前后使用svmtrain训练+svmpredict验证,结果表明:
缩放前:Accuracy = 97.1388% (679/699) (classification)
缩放后:Accuracy = 97.4249% (681/699) (classification)

这么看貌似没啥作用,其实主要是因为MATLAB中的样例数据都是做过一定处理的,取值范围接近,适合直接使用。实际采样数据择很可能没有这么好。

此外,LIBSVM中为数据缩放提供了函数svmscale,只是没有MATLAB接口,但其官网问答中给出了回应:
这里写图片描述

(3)使用高斯核函数
这里写图片描述
总的来说,一般都是先尝试高斯核函数,因为线性核函数是高斯核函数的特殊形式,sigmoid核函数在取某些参数时表现很像高斯核函数。即高斯核函数一般是更通用的。

(4)寻找最优参数C和gama
熟悉SVM方程的应该知道,参数C代表惩罚因子(默认1),越大对训练数据拟合程度越高,gama是高斯核函数参数(默认1/属性数目)。

文中提到,训练数据的高准确率意义不大,因此寻找最优参数的检验方式最好使用交叉检验(cross-validation)。采用网格搜寻(gridsearch)的方式寻找C和gama,即C和gama各取一定离散值,分别使用交叉检验法来计算误差大小。文中给了一些C和gama的取值:
C : 2.^-5,2.^-3,…,2.^15 gama:2.^-15,2.^-13,…,2.^3。

为了节省时间又保证性能,优化过程可以先使用粗网格划分,找到C和gama的大致区间,再进行网格细分,进一步确定C和gama。下图分别为粗网格和细网格。

LIBSVM同样提供了交叉检验 svm_cross_validation,但是同样不具备MATLAB接口(总而言之,MATLAB版本只是让你试试看,真正学习还是得用其他语言,例如C、Python),但也为MATLAB提供了基于网格搜索寻找参数的示例代码:

bestcv = 0;for log2c = -1:3,  for log2g = -4:1,    cmd = ['-v 5 -c ', num2str(2^log2c), ' -g ', num2str(2^log2g)];    cv = svmtrain(heart_scale_label, heart_scale_inst, cmd);    if (cv >= bestcv),      bestcv = cv; bestc = 2^log2c; bestg = 2^log2g;    end    fprintf('%g %g %g (best c=%g, g=%g, rate=%g)\n', log2c, log2g, cv, bestc, bestg, bestcv);  endend

-v应该就是validation,每次训练结束会返回一个交叉检验结果:
这里写图片描述


最后一个问题就是什么时候用线性核函数而非高斯核函数呢?
(1)样本数量<<样本特征数量
(2)样本数量和样本特征数量都很大
(3)样本数量>>样本特征数量
但这三种原因不用高斯核不是因为其表现不好,而是线性核性能足以应付,且速度更快(不用搜索gama了),具体解释可以参考其他资料文档。

最后想说就是LIBSVM的功能真是太多、太强大了,想用好真的要上官网认真看文档,好好学习!下一步打算用LIBSVM+PCA做个人脸识别。

0 0