libsvm简介和函数调用参数说明
1. libSVM简介
libSVM是台湾林智仁(Chih-Jen Lin) 教授2001年开发的一套支持向量机库,这套库运算速度挺快,可以很方便的对数据做分类或回归。由于libSVM程序小,运用灵活,输入参数少,并且是开源的,易于扩展,因此成为目前国内应用最多的SVM的库。
本实验使用libSVM3.18版本。
2. libSVM 3.18包含的内容
(1)Java文件夹 ,主要应用于java平台;
(2)Python文件夹,是用来参数优选的工具,稍后介绍;
(3)tools文件夹,主要包含四个python文件,用来数据集抽样(subset),参数优选(grid),集成测试(easy), 数据查(checkdata);
(4)windows文件夹 —— 包含libSVM四个exe程序包,我们所用的库就是他们,里面还有个heart_scale,是一 个样本文件,可以用 记事本打开,用来测试用的。
(5)svm-toy文件,一个可视化的工具,用来展示训练数据和分类界面,里面是源码,其编译后的程序在windows文件夹下;
(6)heart_scale文件,是测试用的训练文件
(7)其他.h和.cpp文件都是程序的源码,可以编译出相应的.exe文件。其中,最重要的是svm.h和svm.cpp文件,svm-predict.c、svm-scale.c和svm-train.c(还有一个svm-toy.c在svm-toy文件夹中)都是调用的这个文件中的接口函数,编译后就是windows下相应的四个exe程序。另外,里面的 README 跟 FAQ 是很好的帮助文件。
3. 最简单的SVM实验
(1)首先解压工具包,切记工具包解压到英文的目录,因为很多DOS无法输入中文;
(2)由于SVM的执行必须有参数,所以必须在DOS下输入执行文件,并输入参数才能运行,所以先打开MS-DOS,Win+R;
(3) 定位到SVM中的windows目录下,DOS命令见附录1,我的目录是:D:\MyTests\SVM\libSVM-3.18\windows;
(4)进行训练,输入命令:svm-train heart_scale train.model,其中heart_scale是训练文本(如图1)、train.Model是训练后的输 出文本,输出权系数及各支持向量。
(5)运行后,可以在DOS界面看到如下结果:
*
optimization finished, #iter = 162
nu = 0.431029
obj = -100.877288, rho = 0.424462
nSV = 132, nBSV = 107
Total nSV = 132
其中,#iter为迭代次数,nu 是你选择的核函数类型的参数,obj为SVM文件转换为的二次规划求解得到的最小值,rho为判决函数的偏置项b,nSV 为标准支持向量个数(0<a<c),nBSV为边界上的支持向量个数(a=c),Total nSV为支持向量总个数(对于两类来说,因为只有一个分类模型Total nSV = nSV,但是对于多类,这个是各个分类模型的nSV之和)。
(6) 在train.Model中,生成了许多相关系数(如图3),如下:
svm_type c_svc //所选择的svm类型,默认为c_svc
kernel_type rbf //训练采用的核函数类型,此处为RBF核
gamma 0.0769231 //RBF核的参数γ
nr_class 2 //类别数,此处为两分类问题 、
total_sv 132 //支持向量总个数
rho 0.424462 //判决函数的偏置项b
label 1 -1 //原始文件中的类别标识
nr_sv 64 68 //每个类的支持向量机的个数
SV //以下为各个类的权系数及相应的支持向量
(7) 至此,SVM最基本的训练已经完成。
下面进行实际的数据训练:
4. libSVM的训练文本的格式
首先必须了解libSVM数据格式,格式如下:
Label 1:value 2:value ….
Label:是类别的标识,比如上节train.model中提到的1 -1,可以自己随意定,比如-10,0,15。当然,如果是回归,这是目标值,就要实事求是了。Value:就是要训练的数据,从分类的角度来说就是特征值,数据之间用空格隔开。如果特征值为0,特征冒号前面的(姑且称做序号)可以不连续。从编程的角度来说,这样做可以减少内存的使用,并提高做矩阵内积时的运算速度。
5. 数据缩放svm-scale
svm-scale是用来对原始样本进行缩放的,范围可以自己定,一般是[0,1]或[-1,1]。缩放的目的主要是 (1)防止某个特征过大或过小,从而在训练中起的作用不平衡; (2)为了计算速度,因为在核计算中,会用到内积运算或exp运算,不平衡的数据可能造成计算困难。
用法:svm-scale [-l lower] [-u upper]
[-y y_lower y_upper]
[-s save_filename]
[-r restore_filename] filename
其中,[]中都是可选项:-l:设定数据下限;lower:设定的数据下限值,缺省为-1 ;-u设定数据上限;upper:设定的数据上限值,缺省为 1;-y:是否对目标值同时进行缩放;y_lower为下限值,y_upper为上限值; -s save_filename:表示将缩放的规则保存为文件save_filename; -r restore_filename:表示将按照已经存在的规则文件restore_filename进行缩放; filename:待缩放的数据文件,文件格式按照libSVM格式。 默认情况下,只需要输入要缩放的文件名就可以了:比如(已经存在的文件为)heart_scale。比如:svmscale –l 0 –u 1 –s test.rangeheart_scale > out.txt,其中-l是数据下限,-u是数据上限,-s是保存文件,规则信息保存的文件名为test.range,需要缩放的文件时heart_scale,数据缩放的结果文件保存为out.txt。
6. 训练数据svm-train
svm-train主要实现对训练数据集的训练,并可以获得SVM模型。用法: svm-train [options] training_set_file [model_file],其中options为操作参数,可用的选项即表示的涵义如下所示:
-s 设置svm类型:
0 – C-SVC ;1 – v-SVC ; 2 – one-class-SVM ; 3 – ε-SVR ; 4 – n - SVR
-t 设置核函数类型,默认值为2
0 -- 线性核:u'*v ; 1 -- 多项式核: (g*u'*v+ coef 0)degree
2 -- RBF 核:exp(-γ*||u-v||2) 3 -- sigmoid 核:tanh(γ*u'*v+ coef 0)
-d degree: 设置多项式核中degree的值,默认为3
-gγ: 设置核函数中γ的值,默认为1/k,k为特征(或者说是属性)数;
-r coef 0:设置核函数中的coef 0,默认值为0;
-c cost:设置C-SVC、ε-SVR、n - SVR中从惩罚系数C,默认值为1;
-n v :设置v-SVC、one-class-SVM 与n - SVR 中参数n ,默认值0.5;
-p ε :设置v-SVR的损失函数中的e ,默认值为0.1;
-m cachesize:设置cache内存大小,以MB为单位,默认值为40;
-e ε :设置终止准则中的可容忍偏差,默认值为0.001;
-h shrinking:是否使用启发式,可选值为0 或1,默认值为1;
-b 概率估计:是否计算SVC或SVR的概率估计,可选值0 或1,默认0;
-wi weight:对各类样本的惩罚系数C加权,默认值为1;
-v n:n折交叉验证模式;
model_file:可选项,为要保存的结果文件,称为模型文件,以便在预测时使用。
训练完了之后,我们就可以对数据进行预测了,但是,训练的数据未必是最优参数,所以需要进一步优化。LibSVM提供了优化工具,就是tools文件夹,其中包含了grid.py文件和easy.py文件,grid文件可以针对训练数据优选出最佳参数值,而easy则提供了对样本文件做了“一条龙服务”,从参数优选,到文件预测。
7. grid.py参数优化
grid.py和easy.py这两个文件都要用python和绘图工具gnuplot。我的python安装在C:\Python33下,而gnuplot解压到D:\MyTests\SVM\gnuplot,libSVM放在了D:\MyTests\SVM\libSVM-3.18中。
文件grid.py是对C-SVC的参数c和γ做优选的,原理也是网格遍历,假设我们要对目录d:\libSVM\program\tools下的样本文件heart_scale做优选,其具体用法为:
第一步:打开D:\MyTests\SVM\libSVM-3.18下的tools文件夹,找到grid.py文件。用python打开(不能双击,而要右键选择“Edit with IDLE”),修改svmtrain_exe和gnuplot_exe的路径(由于我是win7 64位,所以修改的是64位的地址)。
r'D:\MyTests\SVM\libSVM-3.18\windows\svm-train.exe'
r'D:\MyTests\SVM\gnuplot\bin\pgnuplot.exe'
第二步:运行cmd,进入dos环境,定位到d:\libSVM\program\tools文件夹,输入:
python grid.py heart_scale,会看到dos窗口中飞速乱串的[local]数据,以及一个gnuplot的动态绘图窗口,如图7和图8:
图8 调优时gnuplot训练文本所形成的向量机
大约过10秒钟,就会停止。Dos窗口中的[local]数据时局部最优值,这个不用管,直接看最后一行:
2048.0 0.0001220703125 84.0741
其意义表示:C = 2048.0;γ=0.0001220703125;交叉验证精度CV Rate = 84.0741%,这就是最优结果。
第四步:打开目录d:\libSVM\program\tools,我们可以看到新生成了两个文件:heart_scale.out和heart_scale.png,第一个文件就是搜索过程中的[local]和最优数据,第二个文件就是gnuplot图像。
现在grid.py已经运行完了,可以把最优参数输入到svm-train中进行训练了。
OK,同开始一样,定位到svm的windows下,输入:
svm-train –c 2048.0 –g 0.0001220703125 heart_scaletrainagain1.model
其中-c和-g就是优化后的参数。
可以看出,迭代次数从162次上升到了1046次,边界上的支持向量个数从107下降到了91,说明在优化以前边界向量有10多个错误分类,同时,总支持向量个数从132减到了103。
8. 测试文本预测
之后,根据训练模型进行数据分类预测。用法:
svmpredict [options] test_file model_file output_file
其中,options为操作参数,可用的选项即表示的涵义如下所示:
b probability_estimates:是否需要进行概率估计预测,可选值为0 或者1,默认值为0。
model_file:是由svmtrain 产生的模型文件;
test_file:是要进行预测的数据文件,格式也要符合libSVM格式,即使不知道label的值,也要任意填一个,svmpredict会在output_file中给出正确的label结果,如果知道label的值,就会输出正确率;
output_file:是svmpredict 的输出文件,表示预测的结果值。
总结:
使用libSVM的关键在于熟悉SVM的工作原理以及文本的格式化,了解各部分的参数含义。预测的关键在于参数调优过程。libSVM只对惩罚系数C和核函数γ系数进行修改,其他参数不进行调优。
附录1:
需要了解两个命令
盘符: 例如想进入D盘 d:
cd 进入到当前盘某个目录。
cd \ 进入当前盘根目录
cd \windows 进入到当前盘Windows目录
cd.. 退出到上一级目录
注:进入含有特殊字符目录时需要加引号 例如 cd"c:\program files"