libSVM学习笔记

来源:互联网 发布:网络故障诊断工具作用 编辑:程序博客网 时间:2024/05/29 15:00

目录

一、        LibSVM文件结构说明... 2

二、        LibSVM安装及测试... 2

1.下载libsvm...2

2.解压至指定目录...2

3.设置路径...3

4.编译libsvm...3

5.执行编译...4

6.安装测试...6

三、        LibSVM基础使用... 7

四、        LibSVM使用规范... 9

1. libSVM的数据格式...9

2.svmscale的用法...9

3.svmtrain的用法...10

4.svmpredict 的用法...12

五、        逐步深入LibSVM... 12

1. svm_group_class.14

2. 多类判别的one-against-one.15

1)1-V-R方式...15

2)1-V-1方式...15

3)有向无环图(DAG-SVM)...15

3. hessian矩阵的内存处理...16

4. 数据选择select_working_set(i,j)17

5. 停止准则...18

6. 因子α的更新...18

7. 数据缩放do_shrinking()19

8. 截距b的计算...19

六、        分界线的输出... 20

七、        easy.py和grid.py的使用... 22

 

一、           LibSVM文件结构说明

LibSVM是台湾 林智仁(Chih-Jen Lin) 教授2001年开发的一套支持向量机的库,可以很方便的对数据做分类或回归。这套库可以从http://www.csie.ntu.edu.tw/~cjlin/免费获得。下载.zip格式的版本,解压后可以看到,主要有5个文件夹和一些c++源码文件。

Java—— 主要是应用于java平台;

Python—— 是用来参数优选的工具,稍后介绍;

svm-toy—— 一个可视化的工具,用来展示训练数据和分类界面,里面是源码,其编译后的程序在windows文件夹下;

tools—— 主要包含四个python文件,用来数据集抽样(subset),参数优选(grid),集成测试(easy), 数据检查(checkdata);

windows——包含libSVM四个exe程序包,我们所用的库就是他们。

里面还有个heart_scale,是一个样本文件,可以用记事本打开,用来测试用的。

其他.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 也是很好的文件,对于初学者如果E文过得去,可以看一下。

二、           LibSVM安装及测试

1.下载libsvm

http://www.csie.ntu.edu.tw/~cjlin/libsvm/

2.解压至指定目录

将libsvm解压至D:\MATLAB\R2010a\toolbox下,你也可以解压至你喜欢的地方。

3.设置路径

下载下来的借口包里有svm的一些源文件,没有可执行的exe文件,所以,必须先将svmtrain等源文件编译为matlab可以使用的dll等文件。于是先选择编译器,如下:

4.编译libsvm

首先在matlab设置当前目录为 D:\MATLAB\R2010a\toolbox\libsvm-3.12\matlab

5.执行编译

在matlab命令窗口中输入

mex -setup

显示

输入n

选择编译器:【21】

输入n

输入编译器所在路径

再次确认自己的选择,输入y

编译器选择好了之后,用make.m编译

命令窗口输入make

可以看到新编译出4个文件libsvmread.mexw32,libsvmwrite.mexw32,svmtrain.mexw32,svmpredict.mexw32

6.安装测试

在命令窗口中输入

load heart_scale;

此时需注意,libsvm3.12中提供的是c++版本的数据集heart_scale,这里需要加载matlab版本的数据集。

这两个数据集有什么不同呢?

C++版本的数据集里面如果某一个样本的某一个特征为0,这个特征可以不写在数据集中,但是在matlab版本中,必须要写出来。否则的话,会报这样一个错误:

此时你可以选择下载matlab型的数据集,给一个链接。

http://download.csdn.net/detail/boruoshui/4881338

然后读取数据集

libsvmread('heart_scale');

完成该步骤后发现Workspace中出现了heart_scale_inst 和 heart_scale_label,说明正确。

model=svmtrain(heart_scale_inst,heart_scale_label)

[predict_lebel,accuracy]=svmpredict(heart_scale_label,heart_scale_inst,model)

由于libsvm新的版本对于输出结果的重新设定

[predict_lebel,accuracy]=svmpredict(heart_scale_label,heart_scale_inst,model)

命令会报BUG

改为如下命令即可。(老版本不用改变。本文是libsvm-3.12。)

model=svmtrain(heart_scale_label,heart_scale_inst)

[predicted_label,accuracy, decision_values]=svmpredict(heart_scale_label,heart_scale_inst,model)

证明libsvm安装成功,可以进行其他的实验了。

三、           LibSVM基础使用

1. 把LibSVM包解压到相应的目录,比如D:/libsvm。

2. 在电脑“开始”的“运行”中输入cmd,进入DOS环境。定位到cdD:\libsvm\windows

3. 进行libsvm训练,输入命令:(这里要注意文件的名字,2.89以前版本都是svmtrain.exe)

svm-train heart_scale train.model

heart_scale ——是目录下的已经存在的样本文件,要换成自己的文件,只需改成自己的文件名就可以了

train.model ——是创建的结果文件,保存了训练后的结果

可以看到结果:

#iter——为迭代次数

nu—— 为选择的核函数类型的参数

obj——为SVM文件转换为的二次规划求解得到的最小值

rho——为判决函数的偏置项b,nSV 为标准支持向量个数(0<a[i]<c)

nBSV——为边界上的支持向量个数(a[i]=c)

Total nSV——为支持向量总个数(对于两类来说,因为只有一个分类模型Total nSV = nSV,但是对于多类,这个是各个分类模型的nSV之和)。

    在目录下,还可以看到产生了一个train.model文件,可以用记事本打开,记录了训练后的结果。

         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                                          //以下为各个类的权系数及相应的支持向量

   1 1:0.166667 2:1 3:-0.333333 …10:-0.903226 11:-1 12:-1 13:1

   0.5104832128985164 1:0.125 2:13:0.333333 … 10:-0.806452 12:-0.333333 13:0.5

   ………..

   -1 1:-0.375 2:1 3:-0.333333…. 10:-1 11:-112:-1 13:1

   -1 1:0.166667 2:1 3:1 ….10:-0.870968 12:-1 13:0.5

四、           LibSVM使用规范

需要说明的是,2.89版本以前,都是svmscale、svmtrain和svmpredict,最新的是svm-scale、svm-train和svm-predict,要是用不习惯,只需要把那四个exe文件名去掉中间的短横线,改成svmscale、svmtrain和svmpredict就可以了,我们还是按原来函数名的讲。

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. svmscale的用法

svmscale是用来对原始样本进行缩放的,范围可以自己定,一般是[0,1]或[-1,1]。缩放的目的主要是

1)防止某个特征过大或过小,从而在训练中起的作用不平衡;

2)为了计算速度。因为在核计算中,会用到内积运算或exp运算,不平衡的数据可能造成计算困难。

用法: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) :

svmscale test.txt

这时,test.txt中的数据已经变成[-1,1]之间的数据了。但是,这样原来的数据就被覆盖了,为了让规划好的数据另存为其他的文件,我们用一个dos的重定向符 > 来另存为(假设为out.txt):

svmscaletest.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. svmtrain的用法

svmtrain我们在前面已经接触过,他主要实现对训练数据集的训练,并可以获得SVM模型。

用法: svmtrain [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:设置核函数中的coef0,默认值为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,则命令为:

svmtraintest.txt test.model

4. svmpredict 的用法

   svmpredict 是根据训练获得的模型,对数据集合进行预测。

   用法: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 的输出文件,表示预测的结果值。

对于要做研究的,还需要深入到svm.cpp文件内部,看看都做了什么。

五、           逐步深入LibSVM

其实,在之前上海交大模式分析与机器智能实验室对2.6版本的svm.cpp做了部分注解,(在哪里?google一下你就知道)。但是,这个注释只是针对代码而注释,整篇看下来,你会发现除了理解几个参数的含义,还是会对libsvm一头雾水。当然作为理解程序的辅助材料,还是有很大用处的。特别是,对几个结构体的说明,比较清楚。但是要清楚程序具体做了什么,还是要追踪程序中去。SVC是SVM分类器,  由于svm涉及的数学知识比较多,我们这篇只是讲一些基本的思路,所以就从最基本的C-SVC型svm,核函数采用常用的RBF函数(SVC是SVM分类器,SVR是SVM回归http://wiki.opencv.org.cn/index.php/机器学习中文参考手册#.E6.94.AF.E6.8C.81.E5.90.91.E9.87.8F.E6.9C.BA.E9.83.A8.E5.88.86)。LibSVM就采用2.6版本的好了,因为后续的版本作者又加了很多内容,不易理解作者最初的思路。我是做模式识别,主要从分类的角度来解析函数的调用过程,我们从svmtrain.c看起,其调用的函数过程如下:

      

   

    上图是整个C-SVC的计算过程,下面对一些重要的内容进行具体说明:

1. svm_group_class

      在2.6版中没有此函数的,其功能直接在svm_train实现,为了增强可读性,2.89版中设置了这个函数,其实所作的工作都是一样的。需要说明的是其重新排列后perm中只存储的是各个样本在原始位置的序号,而非数据。这样做的好处有两个:

       1)不必破坏原始数据(也就是读进来的x的数据);

       2)检索起来方便,只需要L维的数据检索,得到序号后,然后定位到原始数据中相应的位置就可以。 

 

       perm是中各类的排列顺序是按照原始样本中各类出现的先后顺序排列的,不一定是按照你原始样本的label序号排列,假如原始样本的label是{-1,0,1},而最先出现的label为1的样本,那么perm中就把label为1的作为类0最先排列。而start中记录的是各类的起始序号,而这个序号是在perm中的序号。

2. 多类判别的one-against-one

      svm做判别是用的分界线(面),两类之间只有一个分界线(面),因此分类器也只有1种,要么是1类要么是2类。但是对于多类,分类方式就有多种。目前,存在的方法主要有:

       1)1-V-R方式

       对于k类问题,把其中某一类的n个训练样本视为一类,所有其他类别归为另一类,因此共有k个分类器。最后预测时,判别式使用竞争方式,也就是哪个类得票多就属于那个类。

       2)1-V-1方式

       也就是我们所说的one-against-one方式。这种方法把其中的任意两类构造一个分类器,共有(k-1)×k/2个分类器。最后预测也采用竞争方式。

       3)有向无环图(DAG-SVM)

       该方法在训练阶段采用1-V-1方式,而判别阶段采用一种两向有向无环图的方式。

       LibSVM采用的是1-V-1方式,因为这种方式思路简单,并且许多实践证实效果比1-V-R方式要好。  

 

       上图是一个5类1-V-1组合的示意图,红色是0类和其他类的组合,紫色是1类和剩余类的组合,绿色是2类与右端两类的组合,蓝色只有3和4的组合。因此,对于nr_class个类的组合方式为:

                                                       for(i = 0; i < nr_class; i ++)

                                                        {

                                                              for(j = i+1; i < nr_class; j ++)     

                                                              { 类 i–V – 类 j }

                                                        }

 

3. hessian矩阵的内存处理        

      因为svm是基于结构风险最小的,因此在分类识别方式具有较传统的基于经验风险最小的方式有优势。但是svm也有一个致命的缺陷,因为要计算hessian矩阵Qij所耗的内存巨大,不利于实践中应用。目前,怎么减小内存的使用依旧是SVM的研究的课题。LibSVM对hessian矩阵处理的策略是定义了一个内存处理类Cache类,预先认为分配一定的内存,存储计算好的Qij,其序号的检索采用双向链表的方式,加快了检索速度。其最重要的函数为: 

       int Cache::get_data(constint index, Qfloat **data, int len)

       //len 是 data 的长度,data为返回的内存首地址,index为Qij的行。

       每次都要查找链表中行为index的Qi,假如已经计算过了,就返回计算过的内存地址,并把储存首地址的链表节点插入到链表尾部。假如没计算过,就分配内存并进行计算,当剩余的内存不够时,就要回收链表头指向的内存。这里,可能有人会问,难道以前计算的就没有用了吗??其实,是因为Qij是稀疏矩阵,在训练过程中只要其对应的alpha[i]不再变动(这时alpha[i]=0或者alpha[i]=C),其对应的Qi就不会被选到来训练,因此原来计算的Qi就没有用了。其实,链表的顺序代表了别选到的频率,最头部的是最不可能被选到,因为这时alpha[i]=0或者alpha[i]=C,而最尾部的最容易被选到。

4. 数据选择select_working_set(i,j)     

     对于样本数量比较多的时候(几千个),SVM所需要的内存是计算机所不能承受的。目前,对于这个问题的解决方法主要有两种:块算法和分解算法。这里,libSVM采用的是分解算法中的SMO(串行最小化)方法,其每次训练都只选择两个样本。我们不对SMO做具体的讨论,要想深入了解可以查阅相关的资料,这里只谈谈和程序有关的知识。

      一般SVM的对偶问题为:                      

                                                               

 S.t.                                                                                                         (4.1)

                                                                                              

     SVM收敛的充分必要条件是KKT条件,其表现为:

                                           (4.2) 

     由4.1式求导可得:

                                           (4.3) 

     进一步推导可知:

                                                 (4.4)

    也就是说,只要所有的样本都满足4.4式,那么得到解就是最优值。因此,在每轮训练中,每次只要选择两个样本(序号为i和j),是最违反KKT条件(也就是4.4式)的样本,就能保证其他样本也满足KKT条件。序号i和j的选择方式如下: 

                         (4.5)

5. 停止准则

    LibSVM程序中,停止准则蕴含在了函数select_working_set(i,j)返回值中。也就是,当找不到符合4.5式的样本时,那么理论上就达到了最优解。但是,实际编程时,由于KKT条件还是蛮苛刻的,要进行适当的放松。令: 

                                                          (4.6)

     由4.4式可知,当所有样本都满足KKT条件时,gi ≤ -gj

       加一个适当的宽松范围ε,也就是程序中的eps,默认为0.001,那么最终的停止准则为:

gi ≤ -gj +ε  →    gi + gj ≤ε                                  (4.7)

6. 因子α的更新

    由于SMO每次都只选择2个样本,那么4.1式的等式约束可以转化为直线约束: 

                                             (4.8)

   转化为图形表示为: 

                             

      把4.8式中α1由α2 表示,即:,结合上图由解析几何可得α2的取值范围: 

                                   (4.9)

     经过一系列变换,可以得到的α2更新值α2new:

                                                 (4.10)

    结合4.9和4.10式得到α2new最终表达式:

                                                                    (4.11)

      得到α2new后,就可以由4.8式求α1new。

      这里,具体操作的时候,把选择后的序号i和j代替这里的1和2就可以了。当然,编程时,这些公式还是太抽象。对于4.9式,还需要具体细分。比如,对于y1 y2 = -1时的L = max(0,α2 - α1),是0大还α2 - α1是大的问题。总共需要分8种情况。

7. 数据缩放do_shrinking()

     上面说到SVM用到的内存巨大,另一个缺陷就是计算速度,因为数据大了,计算量也就大,很显然计算速度就会下降。因此,一个好的方式就是在计算过程中逐步去掉不参与计算的数据。因为,实践证明,在训练过程中,alpha[i]一旦达到边界(alpha[i]=0或者alpha[i]=C),alpha[i]值就不会变,随着训练的进行,参与运算的样本会越来越少,SVM最终结果的支持向量(0<alpha[i]<C)往往占很少部分。

       LibSVM采用的策略是在计算过程中,检测active_size中的alpha[i]值,如果alpha[i]到了边界,那么就应该把相应的样本去掉(变成inactived),并放到栈的尾部,从而逐步缩小active_size的大小。

8. 截距b的计算

    b计算的基本公式为:

                                                                         (4.12)

     理论上,b的值是不定的。当程序达到最优后,只要用任意一个标准支持向量机(0<alpha[i]<C)的样本带入4.12式,得到的b值都是可以的。目前,求b的方法也有很多种。在libSVM中,分别对y=+1和y=-1的两类所有支持向量求b,然后取平均值:

                                                                     (4.13)

    至此,libSVM的整个思路我们简单的过了一遍,里面涉及到很到理论知识,许多细节需要查看相关的SVM的书籍。说实话,笔者也是新手,有些理论也没弄很清楚,我只能把我知道的尽量的讲出来。希望对一些想要了解SVM的有所帮助。 

六、           分界线的输出

LibSVM自带了一个可视化的程序svm-toy,用来输出类之间的分界线。它是先把样本文件载入,然后进行训练,通过对每个像素点的坐标进行判断,看属于哪一类,就附上那类的颜色,从而使类与类之间形成分割线。

为什么说是分界线呢,其实严格说来是分界超平面,但是我们为了能直观用绘图工具绘(比如matlab)出图来只能输出具有二维(也就是特征数是2)的样本分界,因此也就成了线了。要绘分界线,就要用到训练结果,我们在第二节和第三节都讨论了,训练结果(或训练模型)文件怎么输出,但是,没怎么详细说明怎么使用训练结果,现在具体说明。下面是两个模型文件: 

        

                   图5.1 两类模型文件                                 图5.2 三类模型文件

从图5.1和5.2比较可以看出,两类只存在一个分类器,因此每个支持向量对应的系数α(也就是SV的第一排),也只有 1个(当然,截距rho也只有一个)。这种情况最简单,只要把相应的支持向量和α的值带入方程: 

                                (5.1)

找到为0的解,就是分界点了。(式中,有些文献是+b,libSVM采用的是-b)

对于三类或多类时,情况就比较复杂。我们原来讨论过,对于类数k>2的情况,分类器个数为k×(k-1)/2个,那么对应的b值(也就是rho)应该也是k×(k-1)/2个。那么每个支持向量对应的系数α是多少呢?是k-1个,因为每个支持向量(sv)与其他每个类都有一个系数相对应。当然,和有的类对应时可能不是标准支持向量(0<alpha[i]<C),但是至少和其中一个类对应是标准的。我们先看一下图5.2的SV的数据结构: 

 

各nSV对应的αiyi

特征1

特征2

类0(label为-1)

前13个

类0 - V - 类1

类0 - V - 类2

 

1:0.297595

 

2:1.197805

0.4800095239454689

0.2016577869168293

类1(label为0)

中间9个

类1 - V - 类0

类1 - V - 类2

 

1:3.621706

 

2:1.263636

-0.6580578158072528

0.7036762846823739

类2(label为1)

后8个

类2 - V - 类0

类2 - V - 类1

 

1:8.296066

 

2:7.225341

-0.7056286598529473

-0.6494097661702236

    从表中,可以看出,每个支持向量(SV)都有相应的k-1(这里的k为3)个α,后面就是向量的数据。因此,输出分界线时,只要认清系数的位置就可以了。如要输出类0和类2之间的分界线,就要带入类0的第二列和类2的第1列中的α。 

   这里需要重点说明的是:文件输出的不是单纯的α,实际上是αiyi(这里的yi是在训练时的+1或-1,而不是原始样本的label),因此在带入5.1式时,不需要判断yi的值了。

      了解了数据结构以后,就是求解方程。5.1式是个多元方程(这和x的维数有关,这里讨论的是2维的,因此是二元方程),而只有一个等式,因此要对其中一个参数做定常处理。先求出其中一个参数的范围,不妨设为x[0](在绘图时相当于x坐标轴)x_max和x_min,然后分成100等分,对每一个节点处

      x[0]i = i×(x_max- x_min)/100+ x_min

      这样,x[0]就相当于固定了,然后代入5.1式求x[1](也就是y)。这就转化成了一元方程,可以采用传统的数学解法,这里,我采用的是网络遍历法。也就是对x[1]也分成100分进行遍历,把节点处的x[1]:

       x[1]j = j×(y_max- y_min)/100+ y_min

     代入5.1式,看是否接近于0,如果接近0,说明此点是边界点,然后输出坐标就可以了。

                                                for(i = 0; i < 100; i ++)

                                                       for(j = 0; j < 100; j ++)

                                                       {

                                                              X[0] = x[0]i;

                                                              X[1] = x[1]j;

                                                            if( )

                                                              cout<< X[0] << “ “ <<  X[1] <<endl;

                                                       }

分界点坐标输出以后,就可以用matlab把分界线绘制出来了。

七、           easy.pygrid.py的使用

LibSVM有一个tools文件夹,里面包含有四个python文件,是用来对参数优选的。其中,常用到的是easy.py和grid.py两个文件。都要用python(可以在http://www.python.org上下载到,需要安装)和绘图工具gnuplot(可以在ftp://ftp.gnuplot.info/pub/gnuplot/上下载,不需要安装)。

假设:

python安装在d:/libsvm/tools/python26下

gnuplot解压到d:/libsvm/tools/gnuplot

libsvm放在了d:/libsvm/program中(这时easy.py和grid.py文件的目录为d:/libsvm/program/tools)。另外,需要注意的是版本,我的是python 2.6、gnuplot 4.2 和libsvm 2.89,操作系统是WINXP。

1. grid.py使用方法

文件grid.py是对C-SVC的参数c和γ做优选的,原理也是网格遍历,假设我们要对目录d:/libsvm/program/tools下的样本文件heart_scale做优选,其具体用法为:

第一步:打开d:/libsvm/program下的tools文件夹,找到grid.py文件。用python打开(不能双击,而要右键选择“Edit with IDLE”),修改svmtrain_exe和gnuplot_exe的路径。

                              svmtrain_exe= r"D:/libSVM/program/svm-train.exe"

                            gnuplot_exe =r"D:/libSVM/gnuplot/pgnuplot.exe"

(这里面有一个是对非win32的,可以不用改,只改# example for windows下的就可以了)

 第二步:运行cmd,进入dos环境,定位到d:/libsvm/program/tools文件夹,这里是放置grid.py的地方。

第三步:输入以下命令:

                                         d:/libsvm/python26/python  grid.py heart_scale

你就会看到dos窗口中飞速乱串的[local]数据,以及一个gnuplot的动态绘图窗口。大约过10秒钟,就会停止。Dos窗口中的[local]数据时局部最优值,这个不用管,直接看最后一行:

                                         2048.0 0.0001220703125 84.0741

其意义表示:C = 2048.0;γ=0.0001220703125(γ是哪个参数?参看LibSVM学习(三)中svmtrain的参数说明);交叉验证精度CV Rate = 84.0741%,这就是最优结果。

第四步:打开目录d:/libsvm/program/tools,我们可以看到新生成了两个文件:heart_scale.out和heart_scale.png,第一个文件就是搜索过程中的[local]和最优数据,第二文件就是gnuplot图像。

 现在,grid.py已经运行完了,你可以把最优参数输入到svmtrain中进行训练了。当然了,你在当中某一步很可能出现问题,不过不要紧,我也不是一下子成功的,摸索了半天才成功。下面就需要注意的问题说明一下:

1)grid.py和svm-train的版本要统一,也就是说你不能用2.6的grid.py去调用2.89的svm-train。

2)你的目录中如果有空格,比如d:/program files/ libsvm/...,那么无论是在第一步还是第二步,请把目录改成d:/progra~1/ libsvm/...

3) 第三步的命令问题。首先要看你定位到哪个目录,那么其下的文件就不需要带路径,否则就要带。像我们上面的命令,我当前的目录是d:/libsvm/program/tools,那么其下的easy.py和heart_scale文件就不需要加路径,而python.exe是在d:/libsvm/python26/下,因此不在当前目录下,所以要加路径。比如,当我首先用dos定位到d:/libsvm/python26时,其命令就可以改成:

                    python  d:/libsvm/program/tools/grid.py d:/libsvm/program/tools/heart_scale

总起来说,命令为python 目标文件 样本文件,其原则是要让系统找得到文件。假如系统提示你“不是内部或外部命令”,说明你python的路径错误,而如果是‘not found file’的提示,很可能是其他两个文件路径错误。

4)假如,你仍旧出现问题,那么请换一下python或者gnuplot的版本,目前python最新版本是3.1,但是好像会出问题,老一点的版本2.4或2.5的兼容性会更好。

2. easy.py使用方法

文件easy.py对样本文件做了“一条龙服务”,从参数优选,到文件预测。因此,其对grid.py、svm-train、svm-scale和svm-predict都进行了调用(当然还有必须的python和gnuplot)。因此,运行easy.py需要保证这些文件的路径都要正确。当然还需要样本文件和预测文件,这里样本文件还是用heart_scale,预测文件我们复制一份然后改名heart_test,下面说一下使用方法:

     第一步:打开easy.py,修改# example for windows下的几个路径:  

   第二步:运行cmd,进入dos环境,定位到放置easy.py的目录d:/libsvm/program/tools。

   第三步:输入命令:

                    d:/libsvm/python26/pythoneasy.py heart_scale heart_test

           你就会看到一个gnuplot的动态绘图窗口。大约20s以后停止,dos窗口显示为:

                                  Scaling training data...

                                  Cross validation...

                                  Best c=2048.0, g=0.0001220703125 CV rate=84.0741

                                  Training...

                                  Output model: heart_scale.model

                                  Scaling testing data...

                                  Testing...

                                  Accuracy = 85.1852% (230/270) (classification)

                                  Output prediction: heart_test.predict

    这就是最终预测结果,可以看到第三行就是调用grid.py的结果。在d:/libsvm/program/tools下你会看到又多了7个文件,都是以前我们碰到的过程文件,都可以用记事本打开。

3. 常见的问题解析:

    1)

            Scalingtraining data...
              Crossvalidation...
             Traceback (most recent call last):
              File"easy.py", line 61, in ?
             c,g,rate = map(float,last_line.split())
             ValueError: need more than 0 values to unpack

       [解析] 说明你的grid.py运行出现错误,你可以参照第一部分“grid.py使用方法”运行一下就会发现问题。另外,有的说是相对路径的问题,建议找到easy.py的以下部分:

       cmd = "%s -svmtrain %s-gnuplot %s %s" % (grid_py, svmtrain_exe, gnuplot_exe, scaled_file)
改成
          cmd = "%s %s-svmtrain %s -gnuplot %s %s" % (python_path, grid_py, svmtrain_exe,gnuplot_exe, scaled_file)

 

     2)

            Traceback(most recent call last)
              File"grid.py", line 349, in ?
             main()
              File"grid.py", line 344, in main
             redraw(db)
              File"grid.py", line 132, in redraw
             gnuplot.write("set term windows/n")
             IOError [Errno 22] Invalid argument
       [解析] 说明你的gnuplot.exe在调用过程中出现问题,要么是你的路径不对,要么是你的版本不对,请检查。

3)

            Traceback(most recent call last): 
              File"C:/Python24/lib/threading.py", line 442, in __bootstrap 
             self.run() 
              File"c:/libsvm/tools/gridregression.py", line 212, in run 
             self.job_queue.put((cexp,gexp,pexp)) 
              File"C:/Python24/lib/Queue.py", line 88, in put 
             self._put(item) 
              File"c:/libsvm/tools/gridregression.py", line 268, in _put 
             self.queue.insert(0,item) 
             AttributeError: 'collections.deque' object has no attribute 'insert

       [解析] 很显然,你调用的是gridregression.py,其是用来做回归用的。如果你调用easy.py也出现这种问题按照原作者的说法,这里是因为你的python调用出现错误,很可能是版本不对,如果是2.4的版本,请把easy.py中的

      self.queue.insert(0,item)
改成
      if sys.hexversion >= 0x020400A1:
             self.queue.appendleft(item)
       else
             self.queue.insert(0,item)

 

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 户口迁移身份证没换驾照怎么办 户口迁回时身份证掉了怎么办 户口毕业托管身份证掉了怎么办 身份证和户口都掉了怎么办 毕业生户口迁回原籍没身份证怎么办 落户上海后怎么办医保卡 小车临时牌过期了怎么办 驾驶证地址错了一个字怎么办 驾驶证名下车辆有违章怎么办 a2如果扣12分怎么办 b2一次超速12分怎么办 b2本扣了12分怎么办 驾照扣了27分怎么办 大车一次扣12分怎么办 a2驾照扣10分怎么办 驾驶证强制降级没给驾驶证怎么办 6P升11.2卡了怎么办 b2驾照记满12分怎么办 c1驾驶证没分了怎么办 驾照扣了15分怎么办 驾驶证暂扣六个月后怎么办 醉驾交警不通知怎么办 参军后地方驾驶证年审怎么办 军人驾驶证到期身份证注销了怎么办 资格证脱审30天怎么办 驾驶证c证扣6分怎么办 驾照被扣了9分怎么办 驾驶证被扣了9分怎么办 a2驾驶本扣3分怎么办 c1e没过扣了满分怎么办 c1一下扣12分怎么办 换证体检过不了怎么办 唐山驾驶本到期换本怎么办 北京居住证变更地址了怎么办 眼睛弱视驾驶证换证不了怎么办? 驾照的分扣完了怎么办 驾照被扣了3分怎么办 交警扣了行驶证怎么办 报考驾照时手机号录错怎么办 摩托车被交警队拖走怎么办 汽车牌照被偷了怎么办