基于matlab的LIBSVM的调试


MinGW全称Minimalist GNU For Windows,是个精简的Windows平台C/C++、ADA及Fortran编译器,相比Cygwin而言,体积要小很多,使用较为方便。MinGW提供了一套完整的开源编译工具集,以适合Windows平台应用开发,且不依赖任何第三方C运行时库。

MinGW包括:

  • 一套集成编译器,包括C、C++、ADA语言和Fortran语言编译器
  • 用于生成Windows二进制文件的GNU工具的(编译器、链接器和档案管理器)
  • 用于Windows平台安装和部署MinGW和MSYS的命令行安装器(mingw-get)
  • 用于命令行安装器的GUI打包器(mingw-get-inst)

注:本文测试环境为Windows 7 SP1+MinGW 20120426。

一、MinGW安装

MinGW官方网址:http://www.mingw.org/

下载地址:http://sourceforge.net/projects/mingw/files/Installer/mingw-get-inst/

下载后只是个安装器,需要在线下载真正的安装内容,所以速度不会快。具体步骤如下:

1、选择安装版本(Repository Catalogues)

有两个选择,一个是当前打包版本,另一个是下载最新版本。只要你的安装器是从官方下载的,选择前者即可,结果一般就是最新版本。

2、设置安装目录

默认安装到C:\MinGW

3、选择安装组件

这个根据大家需要选择安装组件(C编译器、C++编译器、Fortran编译器、ObjC编译器、Ada编译器等),一般选择C/C++编译器即可,看各位用途确定,组件列表中还有MSYS小系统等可供选择。

4、等待下载并安装完成

5、设置MinGW环境变量

依次鼠标点击桌面“我的电脑”->选择左侧的“高级系统设置”,选择“高级”->“环境变量”,然后再Path里增加;C:\MinGW\bin声明。点击确定。

小提示:设置完成后,Windows似乎不会自动更新环境变量,除非重启机子,那么我们可以通过在下面的命令行中,胡乱设置一下PATH(比如SET PATH=C:\),然后退出命令行,那么系统环境变量就会被强制刷新。

6、查看GCC版本信息

开始运行,输入CMD,回车并运行,输入gcc -v查看编译器版本。如下图:


二、MinGW使用

1、测试编译C++

测试文件test.cpp,代码如下(下面为C代码,只是使用G++来编译而已)

1 #include
2  
3 int main() {
4     printf("Hello World!");
5         return 0;
6 }

2、编译test

编译命令如下:

g++ test.cpp -o test

输出结果为:test.exe

3、执行

输入test回车,结果如下:


参考资料:http://www.mingw.org/wiki/InstallationHOWTOforMinGW

文章来自:http://www.metsky.com/archives/588.html 

====================================================================================


(以上是转载他人的日志,设置mingw参见:http://jingyan.baidu.com/album/455a99509c76d8a1662778f6.html?picindex=5

下载的时候是选择了C++和c编译器,但是安装完成之后,进行libsvm的编译时matlab并没有显示所安装的组件,让我很是纳闷,然后按照网上的一        些教程我就安装了VC6.0编译器,安装完成之后才发现,我所安装的MATLAB2015b版本中是不支持vc6.0编译器的,这也是我在MATLAB官网上查        看https://cn.mathworks.com/support/sysreq/previous_releases.html?s_cid=pi_scl_4_R2015b_win64才知道的。之后下载了Microsoft visual studio professional2013这才算是搞定了这一步。

1.在此之前我们应该现将工作路径和当前路径设置好

工作路径:设置路径->添加并包含子文件夹...->添加C:\Program Files\MATLAB\R2015b\libsvm-3.22->保存

当前路径:C:\Program Files\MATLAB\R2015b\libsvm-3.22\matlab

 2.进行编译器的配置

>>mex -setup

MEX 配置为使用 'Microsoft Visual C++ 2013 Professional (C)' 以进行 C 语言编译。

警告: MATLAB C 和 Fortran API 已更改,现可支持

包含 2^32-1 个以上元素的 MATLAB 变量。不久以后,

您需要更新代码以利用

新的 API。您可以在以下网址找到相关详细信息:

http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html。


要选择不同的语言,请从以下选项中选择一种命令:

>> mex -setup C++ 

 mex -setup FORTRAN

MEX 配置为使用 'Microsoft Visual C++ 2013 Professional' 以进行 C++ 语言编译。

警告: MATLAB C 和 Fortran API 已更改,现可支持

包含 2^32-1 个以上元素的 MATLAB 变量。不久以后,

您需要更新代码以利用

新的 API。您可以在以下网址找到相关详细信息:

这里的警告是不用管的,之后是进行文件的编译。

3.编译

进行c文件编译,因为本身libsvm工具箱是用c++语言编写的,所以要在matlab平台下使用,要进行编译,编译成.mexw文件。实际上在windows文件夹下有已经编译好的.mexw文件

  在这里遇到了问题如下:

>> make%%%%%利用文件夹里的make文件进行编译

Error: C:\Program Files\MATLAB\R2015b\libsvm-3.22\matlab\make.m failed (line 13)

未找到 C:\Program Files\MATLAB\R2015b\libsvm-3.22\libsvmread.c;请检查您是否位于正确的当前文件夹,并检查 'C:\Program                

Files\MATLAB\R2015b\libsvm-3.22\libsvmread.c' 的拼写。

=> Please check README for detailed instructions.

解决办法:这个错误出现的问题应该是matlab程序没有取得管理员权限,不能在program files文件夹下添加文件,所以我们的解决办法是退出matlab程序,打开matlab程序时选用使用管理员权限打开matlab这样在common window输入“make”就可以正常编译出64位文件了(不知道以后运行matlab需不需要每次都以管理员身份运行)

         

4. 重命名(可选,但建议执行)

编译完成后,在当前目录下回出现svmtrain.mexw64、svmpredict.mexw64(64位系统)或者svmtrain.mexw32、svmpredict.mexw32(32位系统)这两个文件,把文件名svmtrain和svmpredict相应改成libsvmtrain和libsvmpredict。

这是因为Matlab中自带有SVM的工具箱,而且其函数名字就是svmtrain和svmpredict,和LIBSVM默认的名字一样,在实际使用的时候有时会产生一定的问题,比如想调用LIBSVM的变成了调用Matlab SVM。

如果有进行重命名的,以后使用LIBSVM时一律使用libsvmtrain和libsvmpredict这两个名字进行调用。

二 测试

LIBSVM软件包中自带有测试数据,为软件包根目录下的heart_scale文件,可以用来测试LIBSVM是否安装成功。这里的heart_scale文件不能用Matlab的load进行读取,需要使用libsvmread读取。

进入LIBSVM的根目录运行以下代码(因为heart_scale文件没有被添加进搜索路径中,其他路径下无法访问这个文件):

[heart_scale_label, heart_scale_inst] = libsvmread('heart_scale');
model = libsvmtrain(heart_scale_label, heart_scale_inst, '-c 1 -g 0.07');
[predict_label, accuracy, dec_values] = libsvmpredict(heart_scale_label, heart_scale_inst, model);

如果LIBSVM安装正确的话,会出现以下的运行结果,显示正确率为86.6667%。

*
optimization finished, #iter = 134
nu = 0.433785
obj = -101.855060, rho = 0.426412
nSV = 130, nBSV = 107
Total nSV = 130
Accuracy = 86.6667% (234/270) (classification)
二、原理介绍
svm是一种有监督的机器学习方法,可以学习不同类别的已知样本的特点,进而对未知的样本进行预测。
SVM本质上是一个二分类的算法,对于n维空间的输入样本,它寻找一个最优的分类超平面,使得两类样本在这个超平面下可以获得最好的分类效果。这个最优可以用两类样本中与这个超平面距离最近的点的距离来衡量,称为边缘距离,边缘距离越大,两类样本分得越开,SVM就是寻找最大边缘距离的超平面,这个可以通过求解一个以超平面参数为求解变量的优化问题获得解决。给定适当的约束条件,这是一个二次优化问题,可以通过用KKT条件求解对偶问题等方法进行求解。

对于不是线性可分的问题,就不能通过寻找最优分类超平面进行分类,SVM这时通过把n维空间的样本映射到更高维的空间中,使得在高维的空间上样本是线性可分的。在实际的算法中,SVM不需要真正地进行样本点的映射,因为算法中涉及到的高维空间的计算总是以内积的形式出现,而高维空间的内积可以通过在原本n维空间中求内积然后再进行一个变换得到,这里计算两个向量在隐式地映射到高维空间的内积的函数就叫做核函数。SVM根据问题性质和数据规模的不同可以选择不同的核函数

虽然SVM本质上是二分类的分类器,但是可以扩展成多分类的分类器,常见的方法有一对多(one-versus-rest)和一对一(one-versus-one)。在一对多方法中,训练时依次把k类样本中的某个类别归为一类,其它剩下的归为另一类,使用二分类的SVM训练处一个二分类器,最后把得到的k个二分类器组成k分类器。对未知样本分类时,分别用这k个二分类器进行分类,将分类结果中出现最多的那个类别作为最终的分类结果。而一对一方法中,训练时对于任意两类样本都会训练一个二分类器,最终得到k*(k-1)/2个二分类器,共同组成k分类器。对未知样本分类时,使用所有的k*(k-1)/2个分类器进行分类,将出现最多的那个类别作为该样本最终的分类结果。

LIBSVM中的多分类就是根据一对一的方法实现的。

1. 训练


libsvm函数用于对训练集的数据进行训练,得到训练好的模型。

model = libsvmtrain(training_label_vector,training_instace_matrix [, 'libsvm_poptions'])  
这个函数有三个参数,其中
  • -training_label_vector:训练样本的类标,如果有m个样本,就是m x 1的矩阵(类型必须为double)。这里可以是二分类和多分类,类标是(-1,1)、(1,2,3)或者其他任意用来表示不同的类别的数字,要转成double类型。
  • -training_instance_matrix:训练样本的特征,如果有m个样本,每个样本特征是n维,则为m x n的矩阵(类型必须为double)。
  • -libsvm_options:训练的参数,在第3点详细介绍。

2. 预测


libpredict函数用于对测试集的数据进行测试,还能对未知样本进行预测。

[predicted_label,accuracy,decision_values/prob_estimates]
=libsvmpredict(testing_label_vector,testing_instance_matrix,model [,'libsvm_options']);
-testing_label_vector:测试样本的类标,如果有m个样本,就是m*1的矩阵(类型必须是double)。如果类标未知,可以初始化任意m*1的double数组。
-testing_instance_matrix:测试样本的特征,如果有m个样本,每个样本特征是n维,则为m*n的矩阵(类型必须是double)
-model:使用libsvmtrain返回的模型
-libsvm_options:预测的参数,与训练的参数形式一样

3. 训练的参数


LIBSVM训练时可以选择参数很多,包括:

-s svm类型: SVM设置类型(默认0)
           0——C-SVC    1——v-SVC   2—— 一类SVM      3—— e-SVR  4——  v-SVR
  • -t 核函数类型:核函数设置类型(默认2)
        0 – 线性核函数:u’v 
        1 – 多项式核函数:(r*u’v + coef0)^degree
        2 – RBF(径向基)核函数:exp(-r|u-v|^2)
        3 – sigmoid核函数:tanh(r*u’v + coef0)
  • -d degree:核函数中的degree设置(针对多项式核函数)(默认3)
  • -g r(gamma):核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数)(默认1/k,k为总类别数)
  • -r coef0:核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)
  • -c cost:设置C-SVC,e -SVR和v-SVR的参数(损失函数)(默认1)
  • -n nu:设置v-SVC,一类SVM和v- SVR的参数(默认0.5)
  • -p p:设置e -SVR 中损失函数p的值(默认0.1)
  • -m cachesize:设置cache内存大小,以MB为单位(默认40)
  • -e eps:设置允许的终止判据(默认0.001)
  • -h shrinking:是否使用启发式,0或1(默认1)
  • -wi weight:设置第几类的参数C为weight*C (C-SVC中的C) (默认1)
  • -v n: n-fold交互检验模式,n为fold的个数,必须大于等于2
  • 以上这些参数设置可以按照SVM的类型和核函数所支持的参数进行任意组合,如果设置的参数在函数或SVM类型中没有也不会产生影响,程序不会接受该参数;如果应有的参数设置不正确,参数将采用默认值

4. 训练返回的内容


libsvmtrain函数返回训练好的SVM分类器模型,可以用来对未知的样本进行预测。这个模型是一个结构体,包含以下成员:

-Parameters: 一个5 x 1的矩阵,从上到下依次表示:
          -s SVM类型(默认0);
          -t 核函数类型(默认2)
          -d 核函数中的degree设置(针对多项式核函数)(默认3);
          -g 核函数中的r(gamma)函数设置(针对多项式/rbf/sigmoid核函数) (默认类别数目的倒数);
           -r 核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)
  • -nr_class: 表示数据集中有多少类别,比如二分类时这个值即为2。
  • -totalSV: 表示支持向量的总数。
  • -rho: 决策函数wx+b中的常数项的相反数(-b)。
  • -Label: 表示数据集中类别的标签,比如二分类常见的1和-1。
  • -ProbA: 使用-b参数时用于概率估计的数值,否则为空。
  • -ProbB: 使用-b参数时用于概率估计的数值,否则为空。
  • -nSV: 表示每类样本的支持向量的数目,和Label的类别标签对应。如Label=[1; -1],nSV=[63; 67],则标签为1的样本有63个支持向量,标签为-1的有67个。
  • -sv_coef: 表示每个支持向量在决策函数中的系数。
  • -SVs: 表示所有的支持向量,如果特征是n维的,支持向量一共有m个,则为m x n的稀疏矩阵。

另外,如果在训练中使用了-v参数进行交叉验证时,返回的不是一个模型,而是交叉验证的分类的正确率或者回归的均方根误差。
这是我用grid search method寻优得到的一个结果
optimization finished, #iter = 53                  %%迭代第53次
nu = 0.013789                                      %%选择核函数类型的参数
obj = -62.388449, rho = 0.699109                   %%objSVM文件转换为的二次规划求解得到的最小值,rho为判决函数的偏置项bnSV 为标准支持向量个数(0nBSV为边界上的支持向量个数(a[i]=c)Total nSV为支持向量总个数(对于两类来说,因为只有一个分类模型Total nSV = nSV但是对于多类,这个是各个分类模型的nSV之和)。
nSV = 6, nBSV = 0
Total nSV = 63
Accuracy = 100% (150/150) (classification)
Accuracy = 87.3333% (131/150) (classification)

5. 预测返回的内容


libsvmtrain函数有三个返回值,不需要的值在Matlab可以用~进行代替。
  • -predicted_label:第一个返回值,表示样本的预测类标号。
  • -accuracy:第二个返回值,一个3 x 1的数组,表示分类的正确率、回归的均方根误差、回归的平方相关系数
  • -decision_values/prob_estimates:第三个返回值,一个矩阵包含决策的值或者概率估计。对于n个预测样本、k类的问题,如果指定“-b 1”参数,则n x k的矩阵,每一行表示这个样本分别属于每一个类别的概率;如果没有指定“-b 1”参数,则为n x k*(k-1)/2的矩阵,每一行表示k(k-1)/2个二分类SVM的预测结果。

6. 读取或保存


libsvmread函数可以读取以LIBSVM格式存储的数据文件

[label_vector, instance_matrix] = libsvmread(‘data.txt’);

这个函数输入的是文件的名字,输出为样本的类标和对应的特征。

libsvmwrite函数可以把Matlab的矩阵存储称为LIBSVM格式的文件。

libsvmwrite(‘data.txt’, label_vector, instance_matrix]

这个函数有三个输入,分别为保存的文件名、样本的类标和对应的特征(必须为double类型的稀疏矩阵)。


libsvm了解
http://www.matlabsky.com/thread-9327-1-1.html
nargin使用
http://blog.sina.com.cn/s/blog_674956e70100j6om.html
mapminmax函数使用
http://www.ilovematlab.cn/thread-47224-1-1.html

你可能感兴趣的:(机器学习)