转自http://noalgo.info/363.html
支持向量机(SVM,Support Vector Machine)是一种基于统计学习理论的模式识别方法,在解决小样本、高维度及非线性的分类问题中应用非常广泛。
LIBSVM是一个由台湾大学林智仁(Lin Chih-Jen)教授等开发的SVM模式识别与回归的软件包,使用简单,功能强大,本文主要介绍其在Matlab中的使用。
在LIBSVM的主页上下载最新版本的软件包,并解压到合适目录中。
如果你使用的是64位的操作的系统和Matlab,那么不需要进行编译步骤,因为自带软件包中已经包含有64位编译好的版本:libsvmread.mexw64、libsvmwrite.mexw64、svmtrain.mexw64、svmpredict.mexw64。否则,需要自己编译二进制文件。
首先在Mtlab中进入LIBSVM根目录下的matlab目录(如C:\libsvm-3.17\matlab),在命令窗口输入
>>mex –setup
然后Matlab会提示你选择编译mex文件的C/C++编译器,就选择一个已安装的编译器,如Microsoft Visual C++ 2010。之后Matlab会提示确认选择的编译器,输入y进行确认。
然后可以输入以下命令进行编译。
>>make
注意,Matlab或VC版本过低可能会导致编译失败,建议使用最新的版本。
编译成功后,当前目录下会出现若干个后缀为mexw64(64位系统)或mexw32(32位系统)的文件。
编译完成后,在当前目录下回出现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的编译好的文件所在路径(如C:\libsvm-3.17\matlab)添加到Matlab的搜索路径中。具体操作为:(中文版Matlab对应进行)
HOME -> Set Path -> Add Folder -> 加入编译好的文件所在的路径(如C:\libsvm-3.17\matlab)
当然也可以把那4个编译好的文件复制到想要的地方,然后再把该路径添加到Matlab的搜索路径中。
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的工作原理,简单介绍如下。
SVM(Support Vector Machine,支持向量机)是一种有监督的机器学习方法,可以学习不同类别的已知样本的特点,进而对未知的样本进行预测。
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中的多分类就是根据一对一的方法实现的。
关于LIBSVM在Matlab中的使用,可以参看软件包中matlab目录下的README文件,这里对里面内容做一个翻译和一些细节的讲解。
libsvm函数用于对训练集的数据进行训练,得到训练好的模型。
model = libsvmtrain(training_label_vector, training_instance_matrix [, 'libsvm_options']);
这个函数有三个参数,其中
libpredict函数用于对测试集的数据进行测试,还能对未知样本进行预测。
[predicted_label, accuracy, decision_values/prob_estimates]
= libsvmpredict(testing_label_vector, testing_instance_matrix, model [, 'libsvm_options']);
这个函数包括四个参数,其中
LIBSVM训练时可以选择的参数很多,包括:
以上这些参数设置可以按照SVM的类型和核函数所支持的参数进行任意组合,如果设置的参数在函数或SVM类型中没有也不会产生影响,程序不会接受该参数;如果应有的参数设置不正确,参数将采用默认值。
libsvmtrain函数返回训练好的SVM分类器模型,可以用来对未知的样本进行预测。这个模型是一个结构体,包含以下成员:
另外,如果在训练中使用了-v参数进行交叉验证时,返回的不是一个模型,而是交叉验证的分类的正确率或者回归的均方根误差。
libsvmtrain函数有三个返回值,不需要的值在Matlab可以用~进行代替。
libsvmread函数可以读取以LIBSVM格式存储的数据文件。
[label_vector, instance_matrix] = libsvmread(‘data.txt’);
这个函数输入的是文件的名字,输出为样本的类标和对应的特征。
libsvmwrite函数可以把Matlab的矩阵存储称为LIBSVM格式的文件。
libsvmwrite(‘data.txt’, label_vector, instance_matrix]
这个函数有三个输入,分别为保存的文件名、样本的类标和对应的特征(必须为double类型的稀疏矩阵)。
从libsvm官网下载svdd工具箱,目前使用libsvm3.18以及svdd3.18版本。
除非注明,文章来自NoAlGo博客原创,转载请保留链接:LIBSVM在Matlab下的使用