LIBSVM在MATLAB中的使用及SVM最优参数选取示例代码

1. 参考网站:

LIBSVM 库下载:http://www.csie.ntu.edu.tw/~cjlin/libsvm/

https://www.csie.ntu.edu.tw/~cjlin/libsvm/index.html?js=1#svm-toy-js

视频:
http://v.youku.com/v_showMini/id_XMjc2NTY3MzYw_ft_131.html

详解:http://www.matlabsky.com/thread-11925-1-1.html

更多细节可查看
https://sites.google.com/site/kittipat/libsvm_matlab

2. 操作流程:

请注意:详细操作流程请参考上面的“详解”网站,这里只说大框架和详解里没有提到的问题。

A.设置path

方法1
File->set path ->add with subfolders->加入libsvm-3.21文件夹的路径

方法2

addpath(genpath(currentFolder))

currentFolder 为 libsvm-3.21 所在路径

B. 在matlab中编译

目的:将libsvm-3.21\matlab 中 libsvmwrite.c 等 C++文件编译成 libsvmread.mexw64等matlab文件,这样就可以在command window中被直接调用了。

C.加载数据集

训练集和测试集都是自带的 heart_scale

cd D:\CMWang\libsvm-3.21
[heart_scale_label, heart_scale_inst] = libsvmread('heart_scale');

model = svmtrain(heart_scale_label, heart_scale_inst, '-c 1 -g 0.07');

[predict_label, accuracy, dec_values] = svmpredict(heart_scale_label, heart_scale_inst, model); % test the training data

还可以使用 load来载入数据

load heart_scale

有两个数据集,一个是C++的, 一个是matlab的。libsvm库中下载的是C++数据,所以matlab加载我们下载的heart_scale是会报错的, .mat 格式的数据下载地址

下载matlab数据集(http://download.csdn.net/detail/abcjennifer/4215779)

For probability estimate

%For probability estimates, you need '-b 1' for training and testing:

[heart_scale_label, heart_scale_inst] = libsvmread('heart_scale');
model = svmtrain(heart_scale_label, heart_scale_inst, '-c 1 -g 0.07 -b 1');
[predict_label, accuracy, prob_estimates] = svmpredict(heart_scale_label, heart_scale_inst, model, '-b 1');

For Linear Kernel and Precomputed Kernel

% We give the following detailed example by splitting heart_scale into
% 150 training and 120 testing data.  Constructing a linear kernel
% matrix and then using the precomputed kernel gives exactly the same
% testing error as using the LIBSVM built-in linear kernel.

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

 % Split Data
 train_data = heart_scale_inst(1:150,:);
 train_label = heart_scale_label(1:150,:);
 test_data = heart_scale_inst(151:270,:);
 test_label = heart_scale_label(151:270,:);

 % Linear Kernel
 model_linear = svmtrain(train_label, train_data, '-t 0');
 [predict_label_L, accuracy_L, dec_values_L] = svmpredict(test_label, test_data, model_linear);

 % Precomputed Kernel
 model_precomputed = svmtrain(train_label, [(1:150)', train_data*train_data'], '-t 4');
 [predict_label_P, accuracy_P, dec_values_P] = svmpredict(test_label, [(1:120)', test_data*train_data'], model_precomputed);

 accuracy_L % Display the accuracy using linear kernel
 accuracy_P % Display the accuracy using precomputed kernel

备注:

(1) libsvmread主要用于读取数据

这里的数据是非matlab下的.mat数据,比如说是.txt,.data等等,这个时候需要使用libsvmread函数进行转化为matlab可识别数据,比如自带的数据是heart_scale数据,那么导入到matlab有两种方式,
一种使用libsvmread函数,在matlab下直接libsvmread(heart_scale);
第二种方式为点击matlab的‘导入数据’按钮,然后导向heart_scale所在位置,直接选择就可以了。因为有的数据libsvmread读取不管用,但是‘导入数据’后就可以变成matlab下数据。

(2)libsvmwrite写函数,就是把已知数据存起来

使用方式为:libsvmwrite(‘filename’,label_vector, instance_matrix);
label_vector是标签,instance_matrix为数据矩阵(注意这个数据必须是稀疏矩阵,就是里面的数据不包含没用的数据(比如很多0),有这样的数据应该去掉再存)。

(3)svmtrain训练函数,训练数据产生模型的

一般直接使用为:model=svmtrain(label,data,cmd); label为标签,data为训练数据(数据有讲究,每一行为一个样本的所有数据,列数代表的是样本的个数),每一个样本都要对应一个标签(分类问题的话一般为二分类问题,也就是每一个样本对应一个标签)。
cmd为相应的命令集合,都有哪些命令呢?很多,-v,-t,-g,-c,等等,不同的参数代表的含义不同,
比如对于分类问题,这里-t就表示选择的核函数类型,-t=0时线性核。-t=1多项式核,-t=2,径向基函数(高斯),-t=3,sigmod核函数,新版出了个-t=4,预计算核(还不会用);
-g为核函数的参数系数-c为惩罚因子系数-v为交叉验证的数,默认为5,这个参数在svmtrain写出来使用与不写出来不使用的时候,model出来的东西不一样,不写的时候,model为一个结构体,是一个模型,可以带到svmpredict中直接使用,写出来的时候,出来的是一个训练模型的准确率,为一个数值。

用法: 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 — 线性核: μ‘∗ν

1 — 多项式核:    (γ∗μ‘∗ν+coef0)degree

2 — RBF核: exp(–γ∗∥μ−ν∥2)

3 — sigmoid 核: tanh(γ∗μ‘∗ν+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: 是否使用启发式, 01(默认1);

-wi weight: 设置第几类的参数C为weight*C (C-SVC中的C) (默认1);

-v n: n-fold交互检验模式, n为fold的个数, 必须大于等于2;

-b 概率估计: 是否计算SVCSVR的概率估计, 可选值01, 默认0;

model_file: 可选项, 为要保存的结果文件, 称为模型文件, 以便在预测时使用.

(3)svmpredict训练函数,使用训练的模型去预测来的数据类型

使用方式为:

[predicted_label,accuracy,decision_values/prob_estimates]= svmpredict(testing_label_vector,testing_instance_matrix,model,’libsvm_options’) 

或者:

[predicted_label]=svmpredict(testing_label_vector,testing_instance_matrix, model, ‘libsvm_options’) 

第一种方式中,输出为三个参数,预测的类型,准确率,评估值(非分类问题用着),输入为测试类型(这个可与可无,如果没有,那么预测的准确率accuracy就没有意义了,如果有,那么就可以通过这个值与预测出来的那个类型值相比较得出准确率accuracy,但是要说明一点的是,无论这个值有没有,在使用的时候都得加上,即使没有,也要随便加上一个类型值,反正你也不管它对不对,这是函数使用所规定的的),再就是输入数据值,最后是参数值(这里的参数值只有两种选择,-p和-b参数),曾经遇到一个这样的问题,比如说我在训练函数中规定了-g参数为0.1,那么在预测的时候是不是也要规定这个参数呢?当你规定了以后,程序反而错误,提醒没有svmpredict的-g参数,原因是在svmtrain后会出现一个model,而在svmpredict中你已经用了这个model,而这个model中就已经包含了你所有的训练参数了,所以svmpredict中没有这个参数,那么对于的libsvm_options就是-p和-b参数了。对于函数的输出,两种方式调用的方法不一样,第一种调用把所有需要的数据都调用出来了,二第二种调用,只调用了predicted_label预测的类型,这里我们可以看到,在单纯的分类预测模型中,其实第二种方式更好一些吧,既简单有实用。

下面给出一个在Matlab中运行SVM的示例
https://sites.google.com/site/kittipat/libsvm_matlab

本文转自:

http://blog.csdn.net/abcjennifer/article/details/7370177

http://blog.csdn.net/on2way/article/details/47733861

http://blog.csdn.net/m624197265/article/details/41894261

https://sites.google.com/site/kittipat/libsvm_matlab

关于SVM参数c&g选取的总结(matlab-libsvm)

选取SVM中参数 c和g的最佳值
寻找最佳c和g的思想仍然是让c和g在一定的范围里跑(比如 c = 2^(-5),2^(-4),…,2^(5),g = 2^(-5),2^(-4),…,2^(5)),然后用cross validation的想法找到是的准确率最高的c和g,在这里做了一点修改是: 因为会有不同的c和g都对应最高的的准确率,我把具有最小c的那组c和g认为是最佳的c和g,因为惩罚参数不能设置 太高,很高的惩罚参数能使得validation数据的准确率提高,但过高的惩罚参数c会造成过学习状态,往往都是惩罚参数c过高会导致最终测试集合的准确率并不是很理想 。

先大范围粗糙的找 比较理想的c和g,然后再细范围找更加理想的c和g.
比如首先让 c = 2^(-5),2^(-4),…,2^(5),g = 2^(-5),2^(-4),…,2^(5)在这个范围找比较理想的c和g。
此时bestc = 0.5,bestg=1,bestacc = 98.8764[cross validation 的准确率]
最终测试集合的准确率 Accuracy = 96.6292% (86/89) (classification)

示例

load wine_SVM;

train_wine = [wine(1:30,:);wine(60:95,:);wine(131:153,:)];
train_wine_labels = [wine_labels(1:30);wine_labels(60:95);wine_labels(131:153)];

test_wine = [wine(31:59,:);wine(96:130,:);wine(154:178,:)];
test_wine_labels = [wine_labels(31:59);wine_labels(96:130);wine_labels(154:178)];

[train_wine,pstrain] = mapminmax(train_wine');
pstrain.ymin = 0;
pstrain.ymax = 1;
[train_wine,pstrain] = mapminmax(train_wine,pstrain);

[test_wine,pstest] = mapminmax(test_wine');
pstest.ymin = 0;
pstest.ymax = 1;
[test_wine,pstest] = mapminmax(test_wine,pstest);

train_wine = train_wine';
test_wine = test_wine';

[bestacc,bestc,bestg] = SVMcg(train_wine_labels,train_wine,-2,4,-4,4,3,0.5,0.5,0.9);

cmd = ['-c ',num2str(bestc),' -g ',num2str(bestg)];
model = svmtrain(train_wine_labels,train_wine,cmd);
[pre,acc] = svmpredict(test_wine_labels,test_wine,model);
function [bestacc,bestc,bestg] = SVMcg(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,accstep)
%SVMcg cross validation by faruto
%Email:[email protected] QQ:516667408 http://blog.sina.com.cn/faruto BNU
%last modified 2009.8.23
%Super Moderator @ www.ilovematlab.cn
% 使用说明.如下:
% [bestacc,bestc,bestg] = SVMcg(train_label,train,cmin,cmax,gmin,gmax,v,cstep,gstep,accstep)
%
% train_label:训练 集标签.要求与libsvm工具箱中要求一致.
% train:训练集.要求与libsvm工具箱中要求一致.
% cmin:惩罚参数c的变化范围的最小值(取以2为底的对数后),即 c_min = 2^(cmin).默认为 -5
% cmax:惩罚参数c的变化范围的最大值(取以2为底的对数后),即 c_max = 2^(cmax).默认为 5
% gmin:参数g的变化范围的最小值(取以2为底的对数后),即 g_min = 2^(gmin).默认为 -5
% gmax:参数g的变化范围的最小值(取以2为底的对数后),即 g_min = 2^(gmax).默认为 5
%
% v:cross validation的参数,即给测试集分为几部分进行cross validation.默认为 3
% cstep:参数c步进的大小.默认为 1
% gstep:参数g步进的大小.默认为 1
% accstep:最后显示准确率图时的步进大小. 默认为 1.5

%% about the parameters of SVMcg
if nargin < 10
    accstep = 1.5;
end
if nargin < 8
    accstep = 1.5;
    cstep = 1;
    gstep = 1;
end
if nargin < 7
    accstep = 1.5;
    v = 3;
    cstep = 1;
    gstep = 1;
end
if nargin < 6
    accstep = 1.5;
    v = 3;
    cstep = 1;
    gstep = 1;
    gmax = 5;
end
if nargin < 5
    accstep = 1.5;
    v = 3;
    cstep = 1;
    gstep = 1;
    gmax = 5;
    gmin = -5;
end
if nargin < 4
    accstep = 1.5;
    v = 3;
    cstep = 1;
    gstep = 1;
    gmax = 5;
    gmin = -5;
    cmax = 5;
end
if nargin < 3
    accstep = 1.5;
    v = 3;
    cstep = 1;
    gstep = 1;
    gmax = 5;
    gmin = -5;
    cmax = 5;
    cmin = -5;
end
%% X:c Y:g cg:acc
[X,Y] = meshgrid(cmin:cstep:cmax,gmin:gstep:gmax);
[m,n] = size(X);
cg = zeros(m,n);
%% record acc with different c & g,and find the bestacc with the smallest c
bestc = 0;
bestg = 0;
bestacc = 0;
basenum = 2;
for i = 1:m
    for j = 1:n
        cmd = ['-v ',num2str(v),' -c ',num2str( basenum^X(i,j) ),' -g ',num2str( basenum^Y(i,j) )];
        cg(i,j) = svmtrain(train_label, train, cmd);

        if cg(i,j) > bestacc
            bestacc = cg(i,j);
            bestc = basenum^X(i,j);
            bestg = basenum^Y(i,j);
        end
        if ( cg(i,j) == bestacc && bestc > basenum^X(i,j) )
            bestacc = cg(i,j);
            bestc = basenum^X(i,j);
            bestg = basenum^Y(i,j);
        end

    end
end
%% to draw the acc with different c & g
[C,h] = contour(X,Y,cg,60:accstep:100);
clabel(C,h,'FontSize',10,'Color','r');
xlabel('log2c','FontSize',10);
ylabel('log2g','FontSize',10);
grid on;

具体详情请查看
http://blog.csdn.net/alextowarson/article/details/4764801

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