SVM入门——基于matlab编程

基于matlab的svm入门编程虽然比较简单,但我也走了不少弯路,下面我就给大家分享关于我的经验。
在讲解之前,我们需要知道基于matlab进行svm有两种方法,第一,采用matlab本身自带的svm工具箱;第二,采用台湾大学林智仁教授等开发设计的一个简单、易于使用和快速有效的SVM模式识别与回归的工具箱。以我的个人经验,采用matlab本身自带的工具箱会比较简单,可以省去很多麻烦,但同时它本身能实现的功能比较少,且不能实现svm回归。而libsvm则能够实现更为复杂的功能,包括svm回归。下面我们开始来学习吧

目录
一、libsvm和matlab自带svm工具箱的区别
二、libsvm下载、安装及调试
		1、下载
		2、编译
		3、调试
三、svm实现二分类
        1、基于libsvm
        2、基于matlab自带工具箱

一、libsvm和matlab自带svm工具箱的区别

在MATLAB中,同样自带了一个svm工具箱,不过相比于libsvm,在功能性和易用性方面有一些差距。具体差别表现在:

  • MATLAB自带的svm实现函数仅支持分类问题,不支持回归问题;而libsvm不仅支持分类问题,亦支持回归问题
  • MATLAB自带的svm实现函数仅支持二分类问题,多分类问题需按照多分类的相应算法编程实现;而libsvm采用一对一方法支持多分类
  • MATLAB自带的svm工具箱无法改变高斯核函数中的参数,而libsvm可以
  • MATLAB自带的svm工具箱也有一些优点,比如在解决二次规划问题时,可选三种方法(经典二次方法;SMO;最小二乘),而libsvm只能是SMO。

常见的扩展为多分类的方法有:

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

二、libsvm下载、安装及调试

1、下载
下载地址为:https://www.csie.ntu.edu.tw/~cjlin/libsvm/
下载完成后,将压缩包解压到合适的目录,最好选择在matlab安装目录的toolbox文件夹下,本人的位置是D:\Matlab\toolbox,如图所示
在这里插入图片描述
2、编译
接下来进行编译,打开matlab,选择在D:\Matlab\toolbox\libsvm\matlab目录下工作

(1)输入mex –setup,目的是选择编辑器进行编译,如图所示
在这里插入图片描述
本人选择第一个,即
在这里插入图片描述
在这里说明一下,编译器每个人的安装可能不同,我电脑由于装有Visual Studio 2015,所以我不会报错,如果报错的话,需要你们自己去装个编译器

(2)输入make,即
在这里插入图片描述
若显示上面的界面,则表示成功

在这里说明一下,该指令必须是在D:\Matlab\toolbox\libsvm\matlab目录下运行,否则会报错,如下图
在这里插入图片描述
(3)修改函数名

编译完成后,在当前目录下回出现svmtrain.mexw64、svmpredict.mexw64(64位系统)或者svmtrain.mexw32、svmpredict.mexw32(32位系统)这两个文件,把文件名svmtrain和svmpredict相应改成libsvmtrain和libsvmpredict。这是因为高版本的Matlab中自带有SVM的工具箱,而且其函数名字就是svmtrain和svmpredict,和LIBSVM默认的名字一样,在实际使用的时候有时会产生一定的问题,比如想调用LIBSVM的变成了调用Matlab SVM。

(4)添加路径
将路径D:\Matlab\toolbox\libsvm\matlab和D:\Matlab\toolbox\libsvm加入到matlab的路径中,如图所示
在这里插入图片描述
3、调试
将Matlab工作目录选择到D:\Matlab\toolbox\libsvm下,这是因为测试数据在该目录下,官方提供的数据为heart_scale,可在当前目录下找到,输入

>> [heart_scale_label, heart_scale_inst] = libsvmread('heart_scale');
>> model = libsvmtrain(heart_scale_label,heart_scale_inst);

成功的话,会出现下面这样的运行结果
在这里插入图片描述

三、svm实现二分类

1、基于libsvm工具箱
(1)多维数据进行二分类

clc;clear;
[label, data] = libsvmread('heart_scale');

% 选取前200个数据作为训练集合,后70个数据作为测试集合
ind = 200;
traindata = data(1:ind,:);
trainlabel = label(1:ind,:);
testdata = data(ind+1:end,:);
testlabel = label(ind+1:end,:);

% 利用训练集合建立分类模型,进行线性分割
model = libsvmtrain(trainlabel,traindata,'-s 0 -t 0 -c 1');

% 利用建立的模型看其在训练集合上的分类效果
[ptrain,acctrain,train_dec_values] = libsvmpredict(trainlabel,traindata,model);

% 预测测试集合标签
[ptest,acctest,test_dec_values] = libsvmpredict(testlabel,testdata,model);

运行结果如下
在这里插入图片描述

其中libsvmtrain的参数说明如下
-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(-gamma|u-v|^2)
  3 –sigmoid:tanh(r*u'v + coef0)
-d degree:核函数中的degree设置(针对多项式核函数)(默认3)
-g r(gama):核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数)(默认1/ 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

其中-g选项中的k是指输入数据中的属性数。option -v 随机地将数据剖分为n部

(2)二维数据进行二分类
二维数据分类和上述多维数据的分类道路相同,这里要增加的内容是,如何画出决策线。我们知道,二维数据线性分割是一条直线,那我们该如何求出这条直线呢?主要有两种方法,方法一是直接利用求出来model的参数;方法二是从原理上出发进行求解
1)方法一

clear;
%导入数据
file_name = 'text.xlsx';%文件名
train_male = xlsread(file_name,3);
train_female = xlsread(file_name,1);
test_male = xlsread(file_name,4);
test_female = xlsread(file_name,2);
train_data = [train_male(:,2:3);train_female(:,2:3)];
train_label = [ones(length(train_male(:,1)),1);-1*ones(length(train_female(:,1)),1)];
test_data = [test_male(:,2:3);test_female(:,2:3)];
test_label = [ones(length(test_male(:,1)),1);-1*ones(length(test_female(:,1)),1)];
%建立模型
model = libsvmtrain(train_label,train_data,'-s 0 -t 0 -c 1');
% 利用建立的模型看其在训练集合上的分类效果
[ptrain,acctrain,train_dec_values] = libsvmpredict(train_label,train_data,model);
% 预测测试集合标签
[ptest,acctest,test_dec_values] = libsvmpredict(test_label,test_data,model);

%w和b的求解方法一
w = model.SVs'*model.sv_coef;
b = -model.rho;
%求解决策线
k = -w(1)/w(2);
b = b/w(2);
x = 145:1:195;
y = k*x-b;
hold on
grid on
plot(train_male(:,2),train_male(:,3),'bo');
plot(train_female(:,2),train_female(:,3),'r^');
plot(x,y)

运行结果如下
在这里插入图片描述
在这里插入图片描述
2)方法二

clear;
%导入数据
file_name = 'text.xlsx';%文件名
train_male = xlsread(file_name,3);
train_female = xlsread(file_name,1);
test_male = xlsread(file_name,4);
test_female = xlsread(file_name,2);
train_data = [train_male(:,2:3);train_female(:,2:3)];
train_label = [ones(length(train_male(:,1)),1);-1*ones(length(train_female(:,1)),1)];
test_data = [test_male(:,2:3);test_female(:,2:3)];
test_label = [ones(length(test_male(:,1)),1);-1*ones(length(test_female(:,1)),1)];
%建立模型
model = libsvmtrain(train_label,train_data,'-s 0 -t 0 -c 1');
% 利用建立的模型看其在训练集合上的分类效果
[ptrain,acctrain,train_dec_values] = libsvmpredict(train_label,train_data,model);
% 预测测试集合标签
[ptest,acctest,test_dec_values] = libsvmpredict(test_label,test_data,model);

%求w和b的求解方法二
SVs_idx = model.sv_indices;
x_SVs = train_data(SVs_idx,:);
y_SVs = train_label(SVs_idx);
alpha_SVs = model.sv_coef;
w = sum(diag(alpha_SVs)*x_SVs)';
SVs_on = (abs(alpha_SVs)<1);
y_SVs_on = y_SVs(SVs_on,:);
x_SVs_on = x_SVs(SVs_on,:);
b_temp = zeros(1,sum(SVs_on));
for idx=1:sum(SVs_on)
    b_temp(idx) = 1/y_SVs_on(idx)-x_SVs_on(idx,:)*w;
end
b = mean(b_temp);

%求解决策线
k = -w(1)/w(2);
b = b/w(2);
x = 145:1:195;
y = k*x-b;
hold on
grid on
plot(train_male(:,2),train_male(:,3),'bo');
plot(train_female(:,2),train_female(:,3),'r^');
plot(x,y)

运行结果如下
在这里插入图片描述
在这里插入图片描述
2、基于matlab自带工具箱
(1)对二维数据进行二分类

clc;
clear;
%导入数据
file_name = 'text.xlsx';%文件名
train_male = xlsread(file_name,3);
train_female = xlsread(file_name,1);
test_male = xlsread(file_name,4);
test_female = xlsread(file_name,2);
train_data = [train_male(:,2:3);train_female(:,2:3)];
train_label = [ones(length(train_male(:,1)),1);-1*ones(length(train_female(:,1)),1)];
test_data = [test_male(:,2:3);test_female(:,2:3)];
test_label = [ones(length(test_male(:,1)),1);-1*ones(length(test_female(:,1)),1)];

%训练模型
model = svmtrain(train_data,train_label,'kernel_function','linear','showplot',true);
%分类测试
classification=svmclassify(model,test_data,'Showplot',true);
grid on

运行结果如下
在这里插入图片描述

其中,svmtrain函数的参数说明如下
	调用方式:SVMStruct = svmtrain(Training,Group,Name,Value)
其输入参数为(训练数据,训练数据相应组属性,可选参数名,可选参数的值),输出为一个结构
体。可选参数有很多,包括boxconstraint,kernel_function,kernelcachelimit,
kktviolationlevel,method,kktviolationlevel,mlp_params,options,polyorder,
rbf_sigma,showplot,tolkkt。
这里我介绍一下上面例子中要用到的两个可选输入参数: 
1、kernel_function(核函数类型):可选的核函数有linear,quadratic,polynomial,rbf
mlp,@kfun ,如果不设置核函数类型,那么默认的选用线性核函数linear。 
2、showplot(绘图):是一个布尔值,用来指示是否绘制分类数据(这里是训练数据)和分类线
(其他参数说明可通过命令行输入>>help svmtrain进行了解)

svmclassify函数的参数说明如下
	调用方式:Group = svmclassify(SVMStruct,Sample,’Showplot’,true)
其最多只有这四个输入参数,包括(训练出的分类模型结构体,测试数据,绘图显示,’true’)

附:
(1)原始数据上传至:
https://pan.baidu.com/s/1wkGSQoUBY8eKEzD9AeLYqw 提取码:c6kk
(2)若有疑问或错误,可联系本人邮箱13682749369@163.com
(3)本文参考链接有:
https://blog.csdn.net/wlx19970505/article/details/62886936
http://www.matlabsky.com/thread-12379-1-1.html
http://www.matlabsky.com/thread-12380-1-1.html
https://blog.csdn.net/jbb0523/article/details/80918214
https://blog.csdn.net/lwwangfang/article/details/52351715

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值