现在的位置: 首页 > 综合 > 正文

libsvm 核函数 交叉验证 参数优化

2014年06月04日 ⁄ 综合 ⁄ 共 9094字 ⁄ 字号 评论关闭

1.下载及安装

libsvm3.1下载:http://download.csdn.net/detail/chlele0105/6631687

里面包含了libsvm和参数寻优算法,GA,GridSearch,PSO等

安装:http://www.matlabsky.com/thread-11925-1-1.html

2. 学习教程:Learn SVM Step by Step :http://www.matlabsky.com/thread-18457-1-1.html

3.参数说明:

详细说明可以参考:http://pan.baidu.com/share/home?uk=875657448#category/type=0

下面简单介绍各个参数:

English:
libsvm_options:
-s svm_type : set type of SVM (default 0)
        0 -- C-SVC
        1 -- nu-SVC
        2 -- one-class SVM
        3 -- epsilon-SVR
        4 -- nu-SVR

关于各种模型优化函数,请参考:http://pan.baidu.com/share/home?uk=875657448#category/type=0
-t kernel_type : set type of kernel function (default 2)
        0 -- linear: u'*v
        1 -- polynomial: (gamma*u'*v + coef0)^degree
        2 -- radial basis function: exp(-gamma*|u-v|^2)
        3 -- sigmoid: tanh(gamma*u'*v + coef0)
        4 -- precomputed kernel (kernel values in training_instance_matrix指定核矩阵)
-d degree : set degree in kernel function (default 3)
-g gamma : set gamma in kernel function (default 1/num_feature)
-r coef0 : set coef0 in kernel function (default 0)
-c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1)
-n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 

0.5)
-p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)
-m cachesize : set cache memory size in MB (default 100)
-e epsilon : set tolerance of termination criterion (default 0.001)
-h shrinking: whether to use the shrinking heuristics, 0 or 1 (default 1)
-b probability_estimates: whether to train a SVC or SVR model for 

probability estimates, 0 or 1 (default 0)
-wi weight: set the parameter C of class i to weight*C, for C-SVC (default 1)

注意:wi只能在模型C-SVC中使用。假设有两类样本,类别标签为1、-1,标签卫1的样本较少,则

   model=svmtrain(label,data,'c 1 -w1 2 -w-1 0.5')

   -标签为1的样本的惩罚参数是1*2=2

   -标签卫-1的样本的惩罚参数是1*0.5=0.5

-v n: n-fold cross validation mode

注意:当使用-v参数时,svmtrain返回的不再是一个训练好的结构体model,对于分类问题,返回的是交叉验证下的平均分类准确率

           对于回归问题,返回的是交叉验证下的平均分类均方根误差

使用libsvm工具箱时,可以指定使用工具箱自带的一些核函数(-t参数),主要有:

-t kernel_type : set type of kernel function (default 2)

        0 -- linear: u'*v

        1 -- polynomial: (gamma*u'*v + coef0)^degree

        2 -- radial basis function: exp(-gamma*|u-v|^2)

        3 -- sigmoid: tanh(gamma*u'*v + coef0)


但有时我们需要使用自己的核函数,这时候可以用 -t 4参数来实现:

-t kernel_type : set type of kernel function (default 2)

        4 -- precomputed kernel (kernel values in training_instance_matrix)


使用-t 4参数时,再有了核函数后,需要给出核矩阵,关于核函数以及核函数构造相关的知识,大家可以看看相关书籍,在此不特别深入说明。

比如线性核函数 是 K(x,x') = (x * x'),设训练集是train_data,设训练集有150个样本 , 测试集是test_data,设测试集有120个样本
则 训练集的核矩阵是 ktrain1 = train_data*train_data' 
     测试集的核矩阵是 ktest1 = test_data*train_data'
想要使用-t 4参数还需要把样本的序列号放在核矩阵前面 ,形成一个新的矩阵,然后使用svmtrain建立支持向量机,再使用svmpredict进行预测即可。形式与使用其他-t参数少有不同,如下:

ktrain1 = train_data*train_data';

Ktrain1 = [(1:150)',ktrain1];

model_precomputed1 = svmtrain(train_label, Ktrain1, '-t 4');  % 注意此处的 输入 Ktrain1

ktest1 = test_data*train_data';

Ktest1 = [(1:120)', ktest1];

[predict_label_P1, accuracy_P1, dec_values_P1] = svmpredict(test_label,Ktest1,model_precomputed1); % 注意此处输入Ktest1

下面是一个整体的小例子:

%% Use_precomputed_kernelForLibsvm_example
% faruto
% last modified by 2011.04.20
%%
tic;
clear;
clc;
close all;
format compact;
%%
load heart_scale.mat;
% 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 One
% 使用的核函数 K(x,x') = (x * x')
% 核矩阵
ktrain1 = train_data*train_data';
Ktrain1 = [(1:150)',ktrain1];
model_precomputed1 = svmtrain(train_label, Ktrain1, '-t 4');
ktest1 = test_data*train_data';
Ktest1 = [(1:120)', ktest1];
[predict_label_P1, accuracy_P1, dec_values_P1] = svmpredict(test_label, Ktest1, model_precomputed1);

%% Precomputed Kernel Two
% 使用的核函数 K(x,x') = ||x|| * ||x'||
% 核矩阵
ktrain2 = ones(150,150);
for i = 1:150
    for j = 1:150
        ktrain2(i,j) = sum(train_data(i,:).^2)^0.5 * sum(train_data(j,:).^2)^0.5;
    end
end
Ktrain2 = [(1:150)',ktrain2];
model_precomputed2 = svmtrain(train_label, Ktrain2, '-t 4');

ktest2 = ones(120,150);
for i = 1:120
    for j = 1:150
        ktest2(i,j) = sum(test_data(i,:).^2)^0.5 * sum(train_data(j,:).^2)^0.5;
    end
end
Ktest2 = [(1:120)', ktest2];
[predict_label_P2, accuracy_P2, dec_values_P2] = svmpredict(test_label, Ktest2, model_precomputed2);
%% Precomputed Kernel Three
% 使用的核函数 K(x,x') = (x * x') / ||x|| * ||x'||
% 核矩阵
ktrain3 = ones(150,150);
for i = 1:150
    for j = 1:150
        ktrain3(i,j) = ...
        train_data(i,:)*train_data(j,:)'/(sum(train_data(i,:).^2)^0.5 * sum(train_data(j,:).^2)^0.5);
    end
end
Ktrain3 = [(1:150)',ktrain3];
model_precomputed3 = svmtrain(train_label, Ktrain3, '-t 4');

ktest3 = ones(120,150);
for i = 1:120
    for j = 1:150
        ktest3(i,j) = ...
        test_data(i,:)*train_data(j,:)'/(sum(test_data(i,:).^2)^0.5 * sum(train_data(j,:).^2)^0.5);
    end
end
Ktest3 = [(1:120)', ktest3];
[predict_label_P3, accuracy_P3, dec_values_P3] = svmpredict(test_label, Ktest3, model_precomputed3);


%% Display the accuracy
accuracyL = accuracy_L(1) % Display the accuracy using linear kernel
accuracyP1 = accuracy_P1(1) % Display the accuracy using precomputed kernel One
accuracyP2 = accuracy_P2(1) % Display the accuracy using precomputed kernel Two
accuracyP3 = accuracy_P3(1) % Display the accuracy using precomputed kernel Three
%%
toc;

运行结果:

Accuracy = 85% (102/120) (classification)
Accuracy = 85% (102/120) (classification)
Accuracy = 67.5% (81/120) (classification)
Accuracy = 84.1667% (101/120) (classification)
accuracyL =
    85
accuracyP1 =
    85
accuracyP2 =
   67.5000
accuracyP3 =
   84.1667
Elapsed time is 1.424549 seconds.

交叉验证(CrossValidation)方法思想简介

以下简称交叉验证(Cross Validation)为CV.CV是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分做为验证集(validation set),首先用训练集对分类器进行训练,在利用验证集来测试训练得到的模型(model),以此来做为评价分类器的性能指标.常见CV的方法如下:

1).Hold-Out Method

将原始数据随机分为两组,一组做为训练集,一组做为验证集,利用训练集训练分类器,然后利用验证集验证模型,记录最后的分类准确率为此Hold-OutMethod下分类器的性能指标.此种方法的好处的处理简单,只需随机把原始数据分为两组即可,其实严格意义来说Hold-Out Method并不能算是CV,因为这种方法没有达到交叉的思想,由于是随机的将原始数据分组,所以最后验证集分类准确率的高低与原始数据的分组有很大的关系,所以这种方法得到的结果其实并不具有说服性.

2).K-fold Cross Validation(记为K-CV)

将原始数据分成K组(一般是均分),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型,用这K个模型最终的验证集的分类准确率的平均数作为此K-CV下分类器的性能指标.K一般大于等于2,实际操作时一般从3开始取,只有在原始数据集合数据量小的时候才会尝试取2.K-CV可以有效的避免过学习以及欠学习状态的发生,最后得到的结果也比较具有说服性.

3).Leave-One-Out Cross Validation(记为LOO-CV)

如果设原始数据有N个样本,那么LOO-CV就是N-CV,即每个样本单独作为验证集,其余的N-1个样本作为训练集,所以LOO-CV会得到N个模型,用这N个模型最终的验证集的分类准确率的平均数作为此下LOO-CV分类器的性能指标.相比于前面的K-CV,LOO-CV有两个明显的优点:


a.每一回合中几乎所有的样本皆用于训练模型,因此最接近原始样本的分布,这样评估所得的结果比较可靠。


b.实验过程中没有随机因素会影响实验数据,确保实验过程是可以被复制的。

但LOO-CV的缺点则是计算成本高,因为需要建立的模型数量与原始数据样本数量相同,当原始数据样本数量相当多时,LOO-CV在实作上便有困难几乎就是不显示,除非每次训练分类器得到模型的速度很快,或是可以用并行化计算减少计算所需的时间.

代码示例

accuracy = svmtrain(train_label, Ktrain1, '-t 4 -v 10');

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

关于libsvm-mat-加强工具箱介绍 by faruto

最终版本号:

libsvm-mat-2.89-3[farutoUltimateVersion2.0]

=====================================

libsvm-mat-加强工具箱介绍

由于libsvm的matlab版本的工具箱libsvm-mat并没有给出寻参的函数模块,而无论利用libsvm工具箱进行分类还是回归,参数的选取是十分重要的,鉴于此libsvm-mat-加强工具箱在libsvm-mat-2.89-3的基础上给出相应的辅助函数插件,方便用户来选取最佳的参数,该加强工具箱可以在MATLAB中文论坛上下载,现对该加强工具箱里主要的辅助函数插件的接口进行介绍,所有的源代码可以到MATLAB中文论坛下载并查看。

归一化函数:scaleForSVM

[train_scale,test_scale,ps]= scaleForSVM(train_data,test_data,ymin,ymax)

输入:

train_data:训练集,格式要求与svmtrain相同。

test_data:测试集,格式要求与svmtrain相同。

ymin,ymax:归一化的范围,即将训练集和测试都归一化到[ymin,ymax],这两个参数可不输入,默认值为ymin=0,ymax=1,即默认将训练集和测试都归一化到[0,1]。

输出:

train_scale:归一化后的训练集。

test_scale:归一化后的测试集。

ps:归一化过程中的映射(方便反归一化使用)。

 

pca降维预处理函数:pcaForSVM

[train_pca,test_pca] = pcaForSVM(train_data,test_data,threshold)

输入:

train_data:训练集,格式要求与svmtrain相同。

test_data:测试集,格式要求与svmtrain相同。

threshold:对原始变量的解释程度([0,100]之间的一个数),通过该阈值可以选取出主成分,该参数可以不输入,默认为90,即选取的主成分默认可以达到对原始变量达到90%的解释程度。

输出:

train_pca:进行pca降维预处理后的训练集。

test_pca:进行pca降维预处理后的测试集。

 

网格参数寻优函数(分类问题):SVMcgForClass

[bestCVaccuracy,bestc,bestg]=

SVMcgForClass(train_label,train,

cmin,cmax,gmin,gmax,v,cstep,gstep,accstep)

输入:

train_label:训练集的标签,格式要求与svmtrain相同。

train:训练集,格式要求与svmtrain相同。

cmin,cmax:惩罚参数c的变化范围,即在[2^cmin,2^cmax]范围内寻找最佳的参数c,默认值为cmin=-8,cmax=8,即默认惩罚参数c的范围是[2^(-8),2^8]。

gmin,gmax:RBF核参数g的变化范围,即在[2^gmin,2^gmax]范围内寻找最佳的RBF核参数g,默认值为gmin=-8,gmax=8,即默认RBF核参数g的范围是[2^(-8),2^8]。

v:进行Cross Validation过程中的参数,即对训练集进行v-fold Cross Validation,默认为3,即默认进行3折CV过程。

cstep,gstep:进行参数寻优是c和g的步进大小,即c的取值为2^cmin,2^(cmin+cstep),…,2^cmax,,g的取值为2^gmin,2^(gmin+gstep),…,2^gmax,默认取值为cstep=1,gstep=1。

accstep:最后参数选择结果图中准确率离散化显示的步进间隔大小([0,100]之间的一个数),默认为4.5。

输出:

bestCVaccuracy:最终CV意义下的最佳分类准确率。

bestc:最佳的参数c。

bestg:最佳的参数g。

 

网格参数寻优函数(回归问题):SVMcgForRegress

[bestCVmse,bestc,bestg]=

SVMcgForRegress(train_label,train,

cmin,cmax,gmin,gmax,v,cstep,gstep,msestep)

其输入输出与SVMcgForClass类似,这里不再赘述。

 

利用PSO参数寻优函数(分类问题):psoSVMcgForClass

[bestCVaccuracy,bestc,bestg,pso_option]=

psoSVMcgForClass(train_label,train,pso_option)

输入:

train_label:训练集的标签,格式要求与svmtrain相同。

train:训练集,格式要求与svmtrain相同。

pso_option:PSO中的一些参数设置,可不输入,有默认值,详细请看代码的帮助说明。

输出:

bestCVaccuracy:最终CV意义下的最佳分类准确率。

bestc:最佳的参数c。

bestg:最佳的参数g。

pso_option:记录PSO中的一些参数。

利用PSO参数寻优函数(回归问题):psoSVMcgForRegress

[bestCVmse,bestc,bestg,pso_option]=

psoSVMcgForRegress(train_label,train,pso_option)

其输入输出与psoSVMcgForClass类似,这里不再赘述。

 

利用GA参数寻优函数(分类问题):gaSVMcgForClass

[bestCVaccuracy,bestc,bestg,ga_option]=

gaSVMcgForClass(train_label,train,ga_option)

输入:

train_label:训练集的标签,格式要求与svmtrain相同。

train:训练集,格式要求与svmtrain相同。

ga_option:GA中的一些参数设置,可不输入,有默认值,详细请看代码的帮助说明。

输出:

bestCVaccuracy:最终CV意义下的最佳分类准确率。

bestc:最佳的参数c。

bestg:最佳的参数g。

ga_option:记录GA中的一些参数。

 

利用GA参数寻优函数(回归问题):gaSVMcgForRegress

[bestCVmse,bestc,bestg,ga_option]=

gaSVMcgForRegress(train_label,train,ga_option)

其输入输出与gaSVMcgForClass类似,这里不再赘述。













抱歉!评论已关闭.