libsvm使用说明
http://www.hankcs.com/ml/libsvm-usage.html
libsvm使用说明
目录
本文记录了libsvm的使用方法、参数说明、数据格式、模型格式,并且对数据标准化和自动寻参等,做了整理。对libsvm的Java代码,整理成了Maven结构,注释了主要接口。本来准备完整地将libsvm源码剖析一遍的,后来太忙顾不上了,连这篇libsvm使用说明也差点烂在草稿箱里,想想还是先发出来吧。
libsvm简介
LIBSVM 是台湾大学林智仁(Lin Chih-Jen)副教授等开发设计的一个简单、易于使用和快速有效的 SVM 模式识别与回归的软件包,他不但提供了编译好的可在 Windows 系列系统的执行文件,还提供了源代码,方便改进、修改以及在其它操作系统上应用; 该软件还有一个特点,就是对 SVM 所涉及的参数调节相对比较少,提供了很多的默认参数,利用这些默认参数就可以解决很多问题;并且提供了交互检验(Cross-SVM回归等问题,包括基于一对一算法的多类模式识别问题。SVM 用于模式识别或回归时, SVM方法及其参数、核函数及其参数的选择,目前国际上还没有形成一个统一的模式, 也就是说最优 SVM 算法参数选择还只能是凭借经验、实验对比、大范围的搜寻或者利用软件包提供的交互检验功能进行寻优的功能。该软件包可以在http://www.csie.ntu.edu.tw/~cjlin/免费获得。
——简介摘录自《LIBSVM使用方法.pdf》
libsvm编译安装
以Java版为例,下载libsvm-3.20.zip后,从java目录中得到全部源码,其他不以.java结尾的都是无关的文件。新建Maven项目,或者直接clone我的Maven repository,项目结构如图:
数据集
获取数据集
libsvm-3.20.zip中附带了一个heart_scale数据集,其主页上也提供了很多数据集,我整理了三个作为例子:
数据集格式
libsvm每行使用的格式如下:
<label> <index1>:<value1> <index2>:<value2> …
-
label为类别标号,index为特征序号,value为特征的值
-
value为0时该项可以省略(大规模数据时节省存储空间)
比如dataset/iris.scale.txt:
- 1 1:-0.555556 2:0.5 3:-0.694915 4:-0.75
- 3 1:-0.166667 2:-0.333333 3:0.38983 4:0.916667
- 2 1:-0.333333 2:-0.75 3:0.0169491 4:-4.03573e-08
- 1 1:-0.833333 3:-0.864407 4:-0.916667
- 1 1:-0.611111 2:0.0833333 3:-0.864407 4:-0.916667
- 3 1:0.611111 2:0.333333 3:0.728813 4:1
- 3 1:0.222222 3:0.38983 4:0.583333
- 2 1:0.222222 2:-0.333333 3:0.220339 4:0.166667
- 2 1:-0.222222 2:-0.333333 3:0.186441 4:-4.03573e-08
- ...
这是(UCI / Iris Plant, 4 features, 3 classes)提供的数据集,一共4个特征,3种类:
- 1. sepal length in cm
- 2. sepal width in cm
- 3. petal length in cm
- 4. petal width in cm
- 5. class:
- -- Iris Setosa
- -- Iris Versicolour
- -- Iris Virginica
分别描述了3种鸢尾花。
svm_scale用法
scale是缩放的意思,这里应该引申为数据标准化,也就是将所有数据缩放到一个标准的区间内。
未标准化的例子
先看看未标准化的一个数据集dataset/diabetes.txt:
- -1 1:6.000000 2:148.000000 3:72.000000 4:35.000000 5:0.000000 6:33.599998 7:0.627000 8:50.000000
- +1 1:1.000000 2:85.000000 3:66.000000 4:29.000000 5:0.000000 6:26.600000 7:0.351000 8:31.000000
- -1 1:8.000000 2:183.000000 3:64.000000 4:0.000000 5:0.000000 6:23.299999 7:0.672000 8:32.000000
- +1 1:1.000000 2:89.000000 3:66.000000 4:23.000000 5:94.000000 6:28.100000 7:0.167000 8:21.000000
- -1 1:0.000000 2:137.000000 3:40.000000 4:35.000000 5:168.000000 6:43.099998 7:2.288000 8:33.000000
- +1 1:5.000000 2:116.000000 3:74.000000 4:0.000000 5:0.000000 6:25.600000 7:0.201000 8:30.000000
- -1 1:3.000000 2:78.000000 3:50.000000 4:32.000000 5:88.000000 6:31.000000 7:0.248000 8:26.000000
- +1 1:10.000000 2:115.000000 3:0.000000 4:0.000000 5:0.000000 6:35.299999 7:0.134000 8:29.000000
- -1 1:2.000000 2:197.000000 3:70.000000 4:45.000000 5:543.000000 6:30.500000 7:0.158000 8:53.000000
- -1 1:8.000000 2:125.000000 3:96.000000 4:0.000000 5:0.000000 6:0.000000 7:0.232000 8:54.000000
这是关于Pima Indians罹患糖尿病的数据,一共有8个特征,2个类别。
标准化方法
libsvm采用的是极值标准化方法Min-max 标准化:
min-max标准化方法是对原始数据进行线性变换。设minA和maxA分别为属性A的最小值和最大值,将A的一个原始值x通过min-max标准化映射成在区间[0,1]中的值x',其公式为:
新数据=(原数据-极小值)/(极大值-极小值)
svm_scale参数
格式
svm-scale [options] filename
options:
• 上下界(默认[-1,1]):-l lower -u upper
• 存储标准化尺度:-s scalefile
• 加载标准化尺度:-r scalefile
• 标签的标准化(用于回归):-y lower upper
这里的标准化尺度其实就是指的某个数据的min和max。
使用提醒
• 训练集和测试集一起scale,将所有数据缩放到[lower, upper]
• 新来的测试样本,应该使用训练时候的标准化尺度进行标准化
示例
- svm-scale -s diabetes.scale.txt -l 1 -u 10 -y 0 1 dataset/diabetes.txt
得到标准化尺度文件diabetes.scale.txt:
- y
- 0.000000000000000 1.000000000000000
- -1.000000000000000 1.000000000000000
- x
- 1.000000000000000 10.00000000000000
- 1 0.000000000000000 17.00000000000000
- 2 0.000000000000000 199.0000000000000
- 3 0.000000000000000 122.0000000000000
- 4 0.000000000000000 99.00000000000000
- 5 0.000000000000000 846.0000000000000
- 6 0.000000000000000 67.09999800000000
- 7 0.07800000000000000 2.420000000000000
- 8 21.00000000000000 81.00000000000000
由上到下分别代表y和x_i缩放时指定的参数,以及数据的min和max。
同时stdout输出缩放后的数据:
- 0.0 1:4.1764705882352935 2:7.693467336683417 3:6.311475409836065 4:4.181818181818182 5:1.0 6:5.506706274417475 7:3.109735269000854 8:5.35
- 1.0 1:1.5294117647058822 2:4.844221105527638 3:5.868852459016393 4:3.6363636363636362 5:1.0 6:4.567809346283438 7:2.0491033304867634 8:2.5
- 0.0 1:5.235294117647059 2:9.27638190954774 3:5.721311475409836 4:1.0 5:1.0 6:4.12518624814266 7:3.2826643894107606 8:2.65
- 1.0 1:1.5294117647058822 2:5.025125628140704 3:5.868852459016393 4:3.090909090909091 5:2.0 6:4.769001602652805 7:1.3420153714773697 8:1.0
- 0.0 1:1.0 2:7.1959798994974875 3:3.9508196721311477 4:4.181818181818182 5:2.7872340425531914 6:6.780923898090132 7:9.492741246797609 8:2.8
- 1.0 1:3.6470588235294117 2:6.2462311557788945 3:6.459016393442623 4:1.0 5:1.0 6:4.433681175370527 7:1.47267292912041 8:2.35
- 0.0 1:2.5882352941176467 2:4.527638190954773 3:4.688524590163935 4:3.909090909090909 5:1.9361702127659575 6:5.157973298300248 7:1.6532877882152006 8:1.75
- 1.0 1:6.294117647058823 2:6.201005025125628 3:1.0 4:1.0 5:1.0 6:5.734724299097595 7:1.215200683176772 8:2.2
- 0.0 1:2.0588235294117645 2:9.909547738693467 3:6.163934426229508 4:5.090909090909091 5:6.776595744680851 6:5.090909212843791 7:1.3074295473953885 8:5.8
- 0.0 1:5.235294117647059 2:6.653266331658291 3:8.081967213114755 4:1.0 5:1.0 6:1.0 7:1.591801878736123 8:5.95
svm_toy用法
svm_toy顾名思义就是一个玩具,以GUI的方式展现SVM的运行效果,编译运行后得到一个窗口:
用鼠标在上面点一些数据点出来,按下Change按钮切换类别:
然后点击run进行分类:
svm_train用法
这是训练的入口,参数有点多,不看源码基本不明白。
参数
svmtrain [options] training_set_file [model_file]
其中, options(可选参数):可用的选项与意义如下所示
-s svm类型:设置SVM 类型,默认值为0,可选类型有(对于回归只能选3或4,这些类型详见论文):
-t 核函数类型:设置核函数类型,默认值为2,可选类型有:
0 — 线性核:u'*v
1 — 多项式核: (g*u'*v+ coef 0)degree
2 — RBF 核:e( u v 2) g –
3 — sigmoid 核:tanh(g*u'*v+ coef 0)
-d degree:核函数中的degree设置,默认值为3;
-g g :设置核函数中的g ,默认值为1/ k ;
-r coef 0:设置核函数中的coef 0,默认值为0;
-c cost:设置C- SVC、e – SVR、n – SVR中从惩罚系数C,默认值为1;
-n n :设置n – SVC、one-class-SVM 与n – SVR 中参数n ,默认值0.5;
-p e :设置n – SVR的损失函数中的e ,默认值为0.1;
-m cachesize:设置cache内存大小,以MB为单位,默认值为40;
-e e :设置终止准则中的可容忍偏差,默认值为0.001;
-h shrinking:是否使用启发式,可选值为0 或1,默认值为1;
-b 概率估计:是否计算SVC或SVR的概率估计,可选值0 或1,默认0;
-wi weight:对各类样本的惩罚系数C加权,默认值为1;
-v n:n折交叉验证模式。
示例
- svm_train dataset/iris.scale.txt dataset/iris.scale.model
会得到一个模型。
- svm_train -v 10 dataset/iris.scale.txt dataset/iris.scale.model
并不会得到任何模型,哪怕你的确指定了一个文件名,因为-v参数使训练模块进入了交叉验证模式。
调参
c和g的参数寻优是个麻烦的问题,libsvm的tools目录下提供了一个自动化的工具grid.py。
用法
参数自动寻优的训练脚本grid.py (Cross-validation and Grid-search)
§ 适用任务:分类问题& RBF核(或linear核)
§ 格式:python [options] grid.py trainingfilename
§ options
• -svmtrain pathname
• -gnuplot pathname
• -out pathname
• -png pathname
• -log2c begin,end,step
• -log2g begin,end,step
• additional same options for svm-train
示例
- python grid.py dataset\iris.scale.txt
输出
- [local] 5 -7 96.6667 (best c=32.0, g=0.0078125, rate=96.6667)
- [local] -1 -7 92.6667 (best c=32.0, g=0.0078125, rate=96.6667)
- [local] 5 -1 95.3333 (best c=32.0, g=0.0078125, rate=96.6667)
- [local] -1 -1 96.0 (best c=32.0, g=0.0078125, rate=96.6667)
- [local] 11 -7 97.3333 (best c=2048.0, g=0.0078125, rate=97.3333)
- ……
- [local] 13 -3 94.6667 (best c=2048.0, g=0.0078125, rate=97.3333)
- 2048.0 0.0078125 97.3333
的确是比手工一个个试要方便得多。
可视化
指定gnuplot的路径还可以得到参数寻优的图像:
- python grid.py -svmtrain C:\libsvm\windows\svm-train.exe -gnuplot C:\gnuplot\bin\gnuplot.exe -png C:\iris.gird.png -log2c -8,8,2 -log2g 8,-8,-2 -v 10 C:\dataset\iris.scale.txt
得到:
绿线上的c和g是最佳的。
svm_predict用法
刚才训练的model现在可以拿过来用了。
格式:svm-predict [options] testfile modelfile resultfile
options
§ -b probability : -b 0只输出类别;-b 1输出各类概率
返回结果
§ 各测试样本的类别(-b 1时为各类后验概率)
§ 正确率
示例
- svm-train –b 1 iris.train iris.model
- svm-predict iris.test iris.model iris.result
值得注意的
§ 部分任务不支持概率输出(比如SVR, one-class SVM)
§ -b参数需要svm-train的时候建立概率模型与之对应
§ 新来的样本按照训练集标准化的尺度进行标准化
- svm-predict –b 1 iris.test iris.model iris.result
- svm-scale -r iris.train.scale iris.test > iris.test.scaled
比如
- dataset/iris.scale.txt dataset/iris.scale.model dataset/iris.scale.result
输出
- Accuracy = 97.33333333333334% (146/150) (classification)
得到dataset/iris.scale.result:
- 1.0
- 1.0
- 1.0
- 2.0
- 2.0
- 2.0
- 3.0
- 3.0
- 3.0
- 3.0
- ……