一、入门介绍 LIBSVM 是台湾大学林智仁(Chih-Jen Lin)博士等开发设计的一个操作简单、易于使用、快速有效的通用SVM软件包,可以解决分类问题(包括C- SVC、n - SVC )、回归问题(包括e - SVR、n - SVR )以及分布估计(one-class-SVM )等问题,提供了线性、多项式、径向基和S形函数四种常用的核函数供选择(也可以自定义核函数),可以有效地解决多类问题、交叉验证选择参数、对不平衡样本加权、多类问题的概率估计等。二、LIBSVM工具使用说明 由于libsvm程序小,运用灵活,输入参数较少,并且是开源的,易于扩展,目前已经成为国内应用最多的SVM库。LIBSVM可以从林智仁博士的个人主页http://www.csie./~cjlin/免费获得,目前已经发展到3.17版。下载.zip格式的版本,解压后可以看到,主要有6个文件夹和一些c++源码文件。 Java——主要是应用于java平台; matlab——应用于matlab平台; Python——是用来参数优选的工具,稍后介绍; svm-toy——可视化的工具,用来展示训练数据和分类界面,里面是源码,其编译后的程序在windows文件夹下; tools——主要包含四个python文件,用来数据集抽样(subset),参数优选(grid),集成测试(easy),数据检查(checkdata); windows——包含libSVM四个exe程序包,我们所用的库就是他们。 其他.h和.cpp文件都是程序的源码,可以编译出相应的.exe文件。其中,最重要的是svm.h和svm.cpp文件,svm-predict.c、svm-scale.c和svm-train.c(还有一个svm-toy.c在svm-toy文件夹中)都是调用的这个文件中的接口函数,编译后就是windows下相应的四个exe程序。还有个heart_scale,是一个样本文件,可以用记事本打开,用来测试用的。另外,里面的 README 跟 FAQ也是很好的文件,可以看英文试试不算太难。 如果仅仅是使用libsvm库中的工具来说,windows下的四个.exe文件就足够用了的。 1)用libsvm-3.17\windows文件夹下的exe文件执行 以windows平台为例,双击打开svm-toy.exe文件,点击“Run”按钮部分,在黑色区域的部分用鼠标随机点下点,代表第一类的数据分布情况;然后点击“Change”按钮,在黑色区域的另一部分点上点,这代表这选择第二类的数据分布;最后点击“Run”按钮,该工具就能将这两类数据分出两类,并用不同的颜色区域来表示不同的类别。如下图所示: 图中左上方绿色的区域,是第一类模式所在的区域,右下方的黄色区域,是你选择的第二类模式所在的的区域,而两者的分界面,也就是SVM的最优分类面。当然,SVM是通过核函数将原始数据映射到高维空间,在高维空间进行线性分类。换句话说,在高维空间,这两类数据应该是线性可分的,即:最优分类面应该是一条直线,而这里看到的,是将高维空间分类的结果又映射回原始空间所呈现的分类结果,即:非线性的分类面。细心的朋友可能已经发现,在上述界面的右下角,有一个编辑框,里面写着“-t 2 -c 100”,显然,这是libSVM的一些参数,你也可以试着更改这些参数,来选择不同的核函数、不同的SVM类型等来达到最好的分类效果。 以下简单介绍一下libsvm中的小工具: libSVM中包含以下可执行程序文件(小工具): (1)svm-scale.exe:一个用于对输入数据进行归一化的简易工具 (2)svm-toy.exe:一个带有图形界面的交互式SVM二分类功能演示小工具; (3)svm-train.exe:对用户输入的数据进行SVM训练。其中,训练数据是按照以下格式输入的: <类别号> <索引1>:<特征值1> <索引2>:<特征值2>... (4)svm-predict.exe:根据SVM训练得到的模型,对输入数据进行预测,即分类。测试数据的格式与训练数据格式相同,但要给定一个label值(这里必须得设定一个label值,任意label值都行)。 2)在myeclipse中建工程执行 上述表述都是直接在dos环境下用命令行运行的,下面给出在myeclipse中调用libsvm API的简单示例。 (1)准备训练样本和测试样本,直接从http://www.csie./~cjlin/libsvmtools/datasets/上下载即可,本实验采用的UCI的breast-cancer数据集。
如果想自己定义核函数,那么属于precompute kernel values and input them as training and testing files. 此时训练样本和测试样本变成如下格式:
New training instance for xi: <label> 0:i 1:K(xi,x1) ... L:K(xi,xL) That is, in the training file the first column must be the "ID" of xi. In testing, ? can be any value. (2)建立Java工程,导入libsvm.jar包,还需要导入java文件下的svm_train.java和svm_predict.java这两个文件,这两个文件其实主要是在LibSVM的基础上进一步封装,把命令行参数转换成String[]类型的函数参数,方便API调用。至于svm_toy(图形界面)和svm_scale(数据压缩)文件,可以选择性导入,不是必要文件。(3)把训练数据和测试数据放在工程文件下或自定义数据存放目录。 (4)编写Java调用LibSVM API分类代码如下:
(5)运行程序,可以得到分类准确率。对训练样本采用10折交叉验证法测试SVM分类性能,其结果如下:
其中,#iter为迭代次数,nu是你选择的核函数类型的参数,obj为SVM文件转换为的二次规划求解得到的最小值,rho为判决函数的偏置项b,nSV为标准支持向量个数(0<a[i]<c),nBSV为边界上的支持向量个数(a[i]=c),Total
nSV为支持向量总个数(对于两类来说,因为只有一个分类模型Total nSV = nSV,但是对于多类,这个是各个分类模型的nSV之和)。 在trainfile目录下多了个model_r.txt文件,这个文件是记录的训练模型的情况 svm_type c_svc //所选择的svm类型,默认为c_svc
补充:libsvm使用规范说明 1. libSVM的数据格式 Label 1:value 2:value …. Label:是类别的标识,比如上节train.model中提到的1 -1,你可以自己随意定,比如-10,0,15。当然,如果是回归,这是目标值,就要实事求是了。 Value:就是要训练的数据,从分类的角度来说就是特征值,数据之间用空格隔开 比如: -15 1:0.708 2:1056 3:-0.3333 需要注意的是,如果特征值为0,特征冒号前面的(姑且称做序号)可以不连续。如: -15 1:0.708 3:-0.3333 表明第2个特征值为0,从编程的角度来说,这样做可以减少内存的使用,并提高做矩阵内积时的运算速度。我们平时在matlab中产生的数据都是没有序号的常规矩阵,所以为了方便最好编一个程序进行转化。 2. svm-scale的用法 svm-scale是用来对原始样本进行缩放的,范围可以自己定,一般是[0,1]或[-1,1]。缩放的目的主要是 1)防止某个特征过大或过小,从而在训练中起的作用不平衡; 2)为了计算速度。因为在核计算中,会用到内积运算或exp运算,不平衡的数据可能造成计算困难。 通俗的说,也就是因为原始数据的范围可能过大或过小,svmscale可以将数据重新缩放到适当范围使训练与预测速度更快。 用法:svmscale [-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格式。 默认情况下,只需要输入要缩放的文件名就可以了:比如(已经存在的文件为test.txt) svm-scale test.txt 这时,test.txt中的数据已经变成[-1,1]之间的数据了。但是,这样原来的数据就被覆盖了,为了让规划好的数据另存为其他的文件,我们用一个dos的重定向符 > 来另存为(假设为out.txt): svmscale test.txt > out.txt 运行后,我们就可以看到目录下多了一个out.txt文件,那就是规范后的数据。假如,我们想设定数据范围[0,1],并把规则保存为test.range文件: svmscale –l 0 –u 1 –s test.range test.txt > out.txt 这时,目录下又多了一个test.range文件,可以用记事本打开,下次就可以用-r test.range来载入了。 3. svm-train的用法 svm-train我们在前面已经接触过,主要实现对训练数据集的训练,并可以获得SVM模型。 用法: svmtrain [options] training_set_file [model_file] 其中,options为操作参数,可用的选项即表示的涵义如下所示: -s 设置svm类型:默认值为0 0 – C-SVC 1 – v-SVC 2 – one-class-SVM 3 –ε-SVR 4 – n - SVR -t 设置核函数类型,默认值为2 0 --线性核:u'*v 1 --多项式核:(g*u'*v+coef0)degree 2 -- RBF核:exp(-γ*||u-v||2) 3 -- sigmoid核:tanh(γ*u'*v+coef0)
-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:可选项,为要保存的结果文件,称为模型文件,以便在预测时使用。 默认情况下,只需要给函数提供一个样本文件名就可以了,但为了能保存结果,还是要提供一个结果文件名,比如:test.model,则命令为: svm-train test.txt test.model svm-train -s 0 -c 10 -t 2 -g 0.5 -e 0.1 test.model 4. svm-predict的用法 svm-predict是根据训练获得的模型,对数据集合进行预测。 用法: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的输出文件,表示预测的结果值。 至此,主要的几个接口已经讲完了,满足一般的应用不成问题。
摘自:http://blog.sina.com.cn/s/blog_4c38701d01011ept.html
实际应用的小贴士
=======================
* 缩放数据。例如,缩放每个属性为 [0,1] 或 [-1,+1]。
* 对于 C-SVC,可以考虑用
* nu-SVC/one-class-SVM/nu-SVR 中的 nu 参数近似为训练误差和支持向量的比率。
* 如果要分类的数据是不平衡的(如,大正集和小负集),用 -wi 尝试不同的惩罚因子(参见下述例子)。
* 对于复杂问题,指定更大的缓存(即,larger -m)。
例子
======================= > svm-scale -l -1 -u 1 -s range train > train.scale > svm-scale -r range test > test.scale
缩放训练数据的每个特征值在 [-1,1] 内(训练数据文件为 train,缩放后的数据为 train.scale),缩放因子(就是一些参数)被存储在 range 文件中然后被用于缩放测试数据(测试数据文件为test,缩放后的数据为test.scale)。 > svm-train -s 0 -c 5 -t 2 -g 0.5 -e 0.1 data_file 用 RBF核函数 exp(-0.5|u-v|^2) 训练(data_file文件)得到一个分类器,C=10,终止允差为0.1。 > svm-train -s 3 -p 0.1 -t 0 data_file 用线性核函数 u'v 解决 SVM 回归(问题),损失函数中 epsilon=0.1。 > svm-train -c 10 -w1 1 -w2 5 -w4 2 data_file 训练一个分类器,对于 ‘1’ 类 惩罚因子为 10= 1 * 10,对于 ‘2’ 类 惩罚因子为 50 =
> svm-train -s 0 -c 100 -g 0.1 -v 5 data_file 对分类器用参数 C=100,gamma=0.1 做五折交叉验证。
> svm-train -s 0 -b 1 data_file
> svm-predict -b 1 test_file data_file.model output_file
用概率信息得到一个模型。用概率估计来预测测试数据。
自定义核函数 ======================= 用户可以自定义核函数的值并输入它们作为训练和测试文件。之后 libsvm 不需要原始的训练和测试集。
假定有
新训练实例 xi:
<label> 0:i 1:K(xi,x1) ... L:K(xi,xL)
新测试实例 任意 x:
<label> 0:? 1:K(x,x1) ... L:K(x,xL)
即,在训练文件中,第一列必须是 xi 的‘ID’。在测试中,用
所有核函数值包括 ZEROs 必须是明确提供的。训练和测试文件中任何随机的或排列的子集也有效(见下例)。
注意:格式与以前在 libsvmtools(文件夹)中发布的预定义核函数略有不同。
例子:
推荐博客: http://blog.csdn.net/zhzhl202/article/details/7583464(数据倾斜 松弛变量+惩罚因子, 说明很详细) http://blog.sina.com.cn/s/blog_72995dcc0100pflx.html(简单全面介绍LibSVM) |
|