机器学习结课项目报告.docx
《机器学习结课项目报告.docx》由会员分享,可在线阅读,更多相关《机器学习结课项目报告.docx(13页珍藏版)》请在冰豆网上搜索。
机器学习结课项目报告
机器学习结课项目报告
题目:
基于svm的分类器设计与实现
学 院:
计算机科学与工程学院
专业:
计算机科学与技术
学生姓名:
学号:
授课教师:
一.实验环境
本项目的开发环境为MatlabR2013b、所用到的工具包为libsvm-3.20包。
数据集为随机生成的平面坐标数据。
二.Libsvm在matlab下的使用
2.1libsvm的安装
2.1.1下载
在LIBSVM的主页上下载最新版本的软件包,并解压到合适目录中。
网址http:
//www.csie.ntu.edu.tw/~cjlin/libsvm/index.html
2.1.2编译
如果使用的是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++编译器,就选择一个已安装的编译器,如MicrosoftVisualC++2010。
之后Matlab会提示确认选择的编译器,输入y进行确认。
然后就可以输入以下命令进行编译。
>>make
注意,Matlab或VC版本过低可能会导致编译失败,建议使用最新的版本。
成功后,当前目录下会出现若干个后缀为mexw64(64位系统)或mexw32(32位系统)的文件。
2.1.3重命名
编译完成后,在当前目录下回出现svmtrain.mexw64、svmpredict.mexw64(64位系统)或者svmtrain.mexw32、svmpredict.mexw32(32位系统)这两个文件,把文件名svmtrain和svmpredict相应改成libsvmtrain和libsvmpredict。
这是因为Matlab中自带有SVM的工具箱,而且其函数名字就是svmtrain和svmpredict,和LIBSVM默认的名字一样,在实际使用的时候有时会产生一定的问题,比如想调用LIBSVM的变成了调用MatlabSVM。
如果有进行重命名的,以后使用LIBSVM时一律使用libsvmtrain和libsvmpredict这两个名字进行调用。
2.1.4添加路径
为了以后使用的方便,建议把LIBSVM的编译好的文件所在路径(如C:
\libsvm-3.17\matlab)添加到Matlab的搜索路径中。
具体操作为:
(中文版Matlab对应进行)
HOME->SetPath->AddFolder->加入编译好的文件所在的路径(如C:
\libsvm-3.17\matlab)
当然也可以把那4个编译好的文件复制到想要的地方,然后再把该路径添加到Matlab的搜索路径中。
2.2libsvm测试
2.2.1libsvm测试结果
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,'-c1-g0.07');
[predict_label,accuracy,dec_values]=libsvmpredict(heart_scale_label,heart_scale_inst,model);
如果LIBSVM安装正确的话,会出现以下的运行结果,显示正确率为86.6667%。
*
optimizationfinished,#iter=134
nu=0.433785
obj=-101.855060,rho=0.426412
nSV=130,nBSV=107
TotalnSV=130
Accuracy=86.6667%(234/270)(classification)
2.3svm原理
2.3.1svm原理简介
使用SVM前首先得了解SVM的工作原理,简单介绍如下。
SVM(SupportVectorMachine,支持向量机)是一种有监督的机器学习方法,可以学习不同类别的已知样本的特点,进而对未知的样本进行预测。
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中的多分类就是根据一对一的方法实现的。
2.4libsvm的使用
2.4.1训练
libsvm函数用于对训练集的数据进行训练,得到训练好的模型。
model=libsvmtrain(training_label_vector,training_instance_matrix[,'libsvm_options']);
这个函数有三个参数,其中
-training_label_vector:
训练样本的类标,如果有m个样本,就是mx1的矩阵(类型必须为double)。
这里可以是二分类和多分类,类标是(-1,1)、(1,2,3)或者其他任意用来表示不同的类别的数字,要转成double类型。
-training_instance_matrix:
训练样本的特征,如果有m个样本,每个样本特征是n维,则为mxn的矩阵(类型必须为double)。
-libsvm_options:
训练的参数,在下文详细介绍。
2.4.2预测
libpredict函数用于对测试集的数据进行测试,还能对未知样本进行预测。
[predicted_label,accuracy,decision_values/prob_estimates]
=libsvmpredict(testing_label_vector,testing_instance_matrix,model[,'libsvm_options']);
这个函数包括四个参数,其中
-testing_label_vector:
测试样本的类标,如果有m个样本,就是mx1的矩阵(类型必须为double)。
如果类标未知,可以初始化为任意mx1的double数组。
-testing_instance_matrix:
测试样本的特征,如果有m个样本,每个样本特征是n维,则为mxn的矩阵(类型必须为double)。
-model:
使用libsvmtrain返回的模型
-libsvm_options:
预测的参数,与训练的参数形式一样。
2.4.3训练参数
LIBSVM训练时可以选择的参数很多,包括:
-ssvm类型:
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)
-ddegree:
核函数中的degree设置(针对多项式核函数)(默认3)
-gr(gamma):
核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数)(默认1/k,k为总类别数)
-rcoef0:
核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)
-ccost:
设置C-SVC,e-SVR和v-SVR的参数(损失函数)(默认1)
-nnu:
设置v-SVC,一类SVM和v-SVR的参数(默认0.5)
-pp:
设置e-SVR中损失函数p的值(默认0.1)
-mcachesize:
设置cache内存大小,以MB为单位(默认40)
-eeps:
设置允许的终止判据(默认0.001)
-hshrinking:
是否使用启发式,0或1(默认1)
-wiweight:
设置第几类的参数C为weight*C(C-SVC中的C)(默认1)
-vn:
n-fold交互检验模式,n为fold的个数,必须大于等于2
以上这些参数设置可以按照SVM的类型和核函数所支持的参数进行任意组合,如果设置的参数在函数或SVM类型中没有也不会产生影响,程序不会接受该参数;如果应有的参数设置不正确,参数将采用默认值。
2.4.4训练返回的内容
libsvmtrain函数返回训练好的SVM分类器模型,可以用来对未知的样本进行预测。
这个模型是一个结构体,包含以下成员:
-Parameters:
一个5x1的矩阵,从上到下依次表示:
-sSVM类型(默认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个,则为mxn的稀疏矩阵。
另外,如果在训练中使用了-v参数进行交叉验证时,返回的不是一个模型,而是交叉验证的分类的正确率或者回归的均方根误差。
2.4.5预测返回的内容
libsvmtrain函数有三个返回值,不需要的值在Matlab可以用~进行代替。
-predicted_label:
第一个返回值,表示样本的预测类标号。
-accuracy:
第二个返回值,一个3x1的数组,表示分类的正确率、回归的均方根误差、回归的平方相关系数。
-decision_values/prob_estimates:
第三个返回值,一个矩阵包含决策的值或者概率估计。
对于n个预测样本、k类的问题,如果指定“-b1”参数,则nxk的矩阵,每一行表示这个样本分别属于每一个类别的概率;如果没有指定“-b1”参数,则为nxk*(k-1)/2的矩阵,每一行表示k(k-1)/2个二分类SVM的预测结果。
2.5.6读取或保存
libsvmread函数可以读取以LIBSVM格式存储的数据文件。
[label_vector,instance_matrix]=libsvmread(‘data.txt’);
这个函数输入的是文件的名字,输出为样本的类标和对应的特征。
libsvmwrite函数可以把Matlab的矩阵存储称为LIBSVM格式的文件。
libsvmwrite(‘data.txt’,label_vector,instance_matrix]
这个函数有三个输入,分别为保存的文件名、样本的类标和对应的特征(必须为double类型的稀疏矩阵)。
2.5.7更新libsvm包
从libsvm官网上下载svdd工具箱,目前使用libsvm3.18以及svdd3.18版本。
svdd工具箱里面有一个matlab文件夹和3个文件svm.cpp、svm.h、svm-train.c。
将matlab文件夹中的文件svmtrain.c覆盖原libsvm的matlab文件夹中的文件。
将svm.cpp、svm.h、svm-train.c这3个文件覆盖libsvm文件夹下的相同文件。
按本文刚开始讲述的方法进行mex-setup、make等完成安装,根据需要进行改名以及添加Path。
三matlab程序的设计与实现
3.1程序设计思想
在项目中,数据集是由matlab随机生成了100个正样本和100个负样本,正样本与负样本分别用红色和蓝色表示,然后把红色的点与蓝色的点分别圈出来,从而实现分类的效果。
通过调用libsvm包里面的函数libsvmtrain去训练样本,然后用函数libsvmpredict查看分类的结果并显示在命令行上,实验结果见(四实验结果)。
本项目kerneltypedefault=2(即Gaussiankernel),通过libsvmtrain(datalabel,data,'-c100-g4')设置了参数——C(c)和2σ2(g)分别为100和4。
3.2matlab源程序的实现
function[output_args]=Nonlinear_SVM(input_args)
%NONLINEAR_SVMSummaryofthisfunctiongoeshere
%Detailedexplanationgoeshere
%generatedata1
r=sqrt(rand(100,1));%generate100randomradius
t=2*pi*rand(100,1);%generate100randomangles,inrange[0,2*pi]
data1=[r.*cos(t),r.*sin(t)];%points
%generatedata2
r2=sqrt(3*rand(100,1)+1);%generate100randomradius
t2=2*pi*rand(100,1);%generate100randomangles,inrange[0,2*pi]
data2=[r2.*cos(t2),r2.*sin(t2)];%points
%plotdatas
plot(data1(:
1),data1(:
2),'r.')
holdon
plot(data2(:
1),data2(:
2),'b.')
ezpolar(@(x)1);%在极坐标下画ρ=1,θ∈[0,2π]的图像,即x^2+y^2=1
ezpolar(@(x)2);
axisequal%makexandyaxiswithequalscalar
holdoff
%buildavectorforclassification
data=[data1;data2];%mergethetwodatasetintoone
datalabel=ones(200,1);%labelforthedata
datalabel(1:
100)=-1;
%trainwithNon-linearSVMclassifieruseGaussianKernel
model=libsvmtrain(datalabel,data,'-c100-g4');
[predicted_label,accuracy,decision_values]=libsvmpredict(datalabel,data,model);
End
四实验结果
4.1运行结果
4.1.1matlab命令行输出
>>Nonlinear_SVM
*
optimizationfinished,#iter=197
nu=0.007276
obj=-72.771233,rho=-0.773878
nSV=33,nBSV=0
TotalnSV=33
Accuracy=100%(200/200)(classification)
4.2程序运行界面
五实验结论
5.1结论
通过上文的阐述,非常清晰的展示的libsvm包的安装与使用。
通过本实验,我进一步理解了svm的工作原理及工作过程,对机器学习也有更深的领悟。
SVM本质上是一个二分类的算法,当对于样本数不是很多的情况,效果非常的好,如上所示,针对200个样本,进行训练后,精确度达百分之100。
本实验用到了svm核函数算法,训练集和测试集是一样的,所以精确度能到100%。
本实验利用了libsvm工具包里面的算法解决了2个不同类型的样本分类问题,实验表明效果非常好。
5.2各种常见模型比较
logisticregression和SVM的比较:
用n表示feature个数,m表示trainingexample个数。
①当n>=m,如n=10000,m=10~1000时,建议用logisticregression,或者linearkernel的SVM。
②如果n小,m不大不小,如n=1~1000,m=10~10000,建议用GaussianKernel的SVM。
③如果n很小,m很大,如n=1~1000,m>50000,建议增加更多的feature并使用logisticregression,或者linearkernel的SVM。
原因,①模型简单即可解决,③如果还用Gaussiankernel会导致很慢,所以还选择logisticregression或者linearkernel。
神经网络可以解决以上任何问题,但是速度是一个很大的问题。
六展望
由于对svm的进一步了解,引发了我对svm更加强烈的兴趣,下一步将把所有数据分为testset和crossvalidationset、trainingset三部分,具体过程为:
1.使用训练集训练出10个模型
2.用10个模型分别对交叉验证集计算得出交叉验证误差(代价函数的值)
3.选取代价函数值最小的模型
4.用步骤3中选出的模型对测试集计算得出推广误差(代价函数的值)
从而选择出比较好的模型,然后再对testset进行预测和分类,希望能有更大的收获。
参考文献
【1】libsvm在matlab下的使用,noalgo著,http:
//noalgo.info/363.html
【2】stanford机器学习,rachel著,
【3】图解机器学习,杉山将著,人民邮电出版社
【4】机器学习理论与算法,张燕平等著,科学出版社
【5】机器学习导论,EthemAlpaydm著,机械工业出版社