LIBSVM是台湾大学林智仁(Lin Chih-Jen)教授等开发设计的一个简单、易于使用和快速有效的SVM模式识别与回归的软件包,他不但提供了编译好的可在Windows系列系统的执行文件,还提供了源代码,方便改进、修改以及在其它操作系统上应用;该软件对SVM所涉及的参数调节相对比较少,提供了很多的默认参数,利用这些默认参数可以解决很多问题;并提供了交互检验(Cross Validation)的功能。

SVM 函数及参数介绍

该库主要有两个函数, svmtrain 和svmpredict。其中

model = svmtrain(training_label_vector, training_instance_matrix [, 'libsvm_options']);

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

我们忽略支持向量机的数学理论,主要说明一下上述函数中的参数相关的含义。

s svm类型:设置SVM模型类型(默认0)
        0 -- C-SVC
        1 -- nu-SVC
        2 -- one-class SVM
        3 -- epsilon-SVR
        4 -- nu-SVR
-t 核函数类型:核函数设置类型(默认2)
        0 -- 线性核函数: u'*v
        1 -- 多项式核函数: (gamma*u'*v + coef0)^degree
        2 -- RBF核函数: exp(-gamma*|u-v|^2)
        3 -- sigmoid核函数: tanh(gamma*u'*v + coef0)
        4 -- 预定义核函数(指定核矩阵)
-d degree:核函数中的degree设置(针对多项式核函数)(默认3)
-g gama:核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数)(默认1/num_features,即属性数目的倒数)
-r coef0:核函数中的coef0设置(针对多项式/sigmoid核函数)(默认0)
-c cost:设置C-SVC,epsilon-SVR和nu-SVC的参数(损失函数)(默认1)
-n nu:设置nu-SVC,one-class SVM和nu-SVR的参数(默认0.5)
-p epsilon:设置epsilon-SVR中损失函数epsilon的值(默认0.1)
-m cachesize:设置cache内存大小,以MB为单位(默认100)
-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

svmtrain 函数返回的参数有

        -Parameters: parameters
        -nr_class: number of classes; = 2 for regression/one-class svm
        -totalSV: total #SV
        -rho: -b of the decision function(s) wx+b
        -Label: label of each class; empty for regression/one-class SVM
        -sv_indices: values in [1,...,num_traning_data] to indicate SVs in the training set
        -ProbA: pairwise probability information; empty if -b 0 or in one-class SVM
        -ProbB: pairwise probability information; empty if -b 0 or in one-class SVM
        -nSV: number of SVs for each class; empty for regression/one-class SVM
        -sv_coef: coefficients for SVs in decision functions
        -SVs: support vectors

利用SVM进行分类任务

给定下述数据集

sigma = [1,0;0,1];
mu1 = [1,-1];
x1 = mvnrnd(mu1,sigma,200);
mu2 = [5,-4];
x2 = mvnrnd(mu2,sigma,200);
mu3 = [1,4];
x3 = mvnrnd(mu3,sigma,200);
mu4 = [6,4.5];
x4 = mvnrnd(mu4,sigma,200);
mu5= [7.5,0.0];
x5 = mvnrnd(mu5,sigma,200);

% Show the data points;
plot(x1(:,1),x1(:,2),'r.'); hold on;
plot(x2(:,1),x2(:,2),'b.');
plot(x3(:,1),x3(:,2),'k.');
plot(x4(:,1),x4(:,2),'g.');
plot(x5(:,1),x5(:,2),'m.');

可视化知,其分布为

我们利用支持向量机来进行分类。 首先,我们将数据集按照 6:4 的比例分为训练集合测试集, 再对数据集进行标准化

% Set the train set and test set;
choose = randperm(200);
x1_train = x1(choose(1:120),:);
x2_train = x2(choose(1:120),:);
x3_train = x3(choose(1:120),:);
x4_train = x4(choose(1:120),:);
x5_train = x5(choose(1:120),:);
x1_test = x1(choose(121:200),:);
x2_test = x2(choose(121:200),:);
x3_test = x3(choose(121:200),:);
x4_test = x4(choose(121:200),:);
x5_test = x5(choose(121:200),:);

X_train = [x1_train;x2_train;x3_train;x4_train;x5_train];
X_test = [x1_test;x2_test;x3_test;x4_test;x5_test];
label_train = [ones(120,1);2*ones(120,1);3*ones(120,1);4*ones(120,1);5*ones(120,1)];
label_test = [ones(80,1);2*ones(80,1);3*ones(80,1);4*ones(80,1);5*ones(80,1)];

% normalization
[X_train,PS] = mapminmax(X_train');
X_train = X_train';
X_test = mapminmax('apply',X_test',PS);
X_test = X_test';

其次,我们选取径向基函数, 对正则化参数进行讨论,有

%% Part1: Fix g=1, find the optimal c;
c = 0:1:1000;
y =zeros(size(c));
for i = 1:1001
    cmd = ['-t 2','-c',num2str(c(i))];
    model = svmtrain(label_train,X_train,cmd);
    [~,accuracy,~] = svmpredict(label_test,X_test,model);
    y(i) = accuracy(1)/100;
end
plot(c,y);

由此,我们便得到正确率随参数c变化的图像

其次,我们采用 5 折交叉验证来确定 $c,g$的最优参数,这里的 $g=\gamma,$

 K(u,v)=e^{-\gamma|u-v|^2}

%% Part2: Find the optimal parameters (c/g) 
[c,g] = meshgrid(-10:0.2:10,-10:0.2:10);
[m,n] = size(c);
cg = zeros(m,n);
eps = 10^(-4);
v = 5;
bestc = 1;
bestg = 0.1;
bestacc = 0;
for i = 1:m
    for j = 1:n
        cmd = ['-v ',num2str(v),' -t 2',' -c ',num2str(2^c(i,j)),' -g ',num2str(2^g(i,j))];
        cg(i,j) = svmtrain(label_train,X_train,cmd);     
        if cg(i,j) > bestacc
            bestacc = cg(i,j);
            bestc = 2^c(i,j);
            bestg = 2^g(i,j);
        end        
        if abs( cg(i,j)-bestacc )<=eps && bestc > 2^c(i,j) 
            bestacc = cg(i,j);
            bestc = 2^c(i,j);
            bestg = 2^g(i,j);
        end               
    end
end
cmd = [' -t 2',' -c ',num2str(bestc),' -g ',num2str(bestg)];

model = svmtrain(label_train,X_train,cmd);
[predict_label,accuracy,dec_vectors] = svmpredict(label_test,X_test,model);

得到相应的最优参数 $c=\gammma =0.0009765.$

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐