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

来源:互联网 发布:淘宝商城是正品吗 编辑:程序博客网 时间:2024/06/05 09:50

转自:http://blog.csdn.net/chlele0105/article/details/17026963

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参数少有不同,如下:

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. ktrain1 = train_data*train_data';  
  2.   
  3. Ktrain1 = [(1:150)',ktrain1];  
  4.   
  5. model_precomputed1 = svmtrain(train_label, Ktrain1, '-t 4');  % 注意此处的 输入 Ktrain1  
  6.   
  7. ktest1 = test_data*train_data';  
  8.   
  9. Ktest1 = [(1:120)', ktest1];  
  10.   
  11. [predict_label_P1, accuracy_P1, dec_values_P1] = svmpredict(test_label,Ktest1,model_precomputed1); % 注意此处输入Ktest1  

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

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. %% Use_precomputed_kernelForLibsvm_example  
  2. % faruto  
  3. % last modified by 2011.04.20  
  4. %%  
  5. tic;  
  6. clear;  
  7. clc;  
  8. close all;  
  9. format compact;  
  10. %%  
  11. load heart_scale.mat;  
  12. % Split Data  
  13. train_data = heart_scale_inst(1:150,:);  
  14. train_label = heart_scale_label(1:150,:);  
  15. test_data = heart_scale_inst(151:270,:);  
  16. test_label = heart_scale_label(151:270,:);  
  17.   
  18. %% Linear Kernel  
  19. model_linear = svmtrain(train_label, train_data, '-t 0');  
  20. [predict_label_L, accuracy_L, dec_values_L] = svmpredict(test_label, test_data, model_linear);  
  21.   
  22. %% Precomputed Kernel One  
  23. % 使用的核函数 K(x,x') = (x * x')  
  24. % 核矩阵  
  25. ktrain1 = train_data*train_data';  
  26. Ktrain1 = [(1:150)',ktrain1];  
  27. model_precomputed1 = svmtrain(train_label, Ktrain1, '-t 4');  
  28. ktest1 = test_data*train_data';  
  29. Ktest1 = [(1:120)', ktest1];  
  30. [predict_label_P1, accuracy_P1, dec_values_P1] = svmpredict(test_label, Ktest1, model_precomputed1);  
  31.   
  32. %% Precomputed Kernel Two  
  33. % 使用的核函数 K(x,x') = ||x|| * ||x'||  
  34. % 核矩阵  
  35. ktrain2 = ones(150,150);  
  36. for i = 1:150  
  37.     for j = 1:150  
  38.         ktrain2(i,j) = sum(train_data(i,:).^2)^0.5 * sum(train_data(j,:).^2)^0.5;  
  39.     end  
  40. end  
  41. Ktrain2 = [(1:150)',ktrain2];  
  42. model_precomputed2 = svmtrain(train_label, Ktrain2, '-t 4');  
  43.   
  44. ktest2 = ones(120,150);  
  45. for i = 1:120  
  46.     for j = 1:150  
  47.         ktest2(i,j) = sum(test_data(i,:).^2)^0.5 * sum(train_data(j,:).^2)^0.5;  
  48.     end  
  49. end  
  50. Ktest2 = [(1:120)', ktest2];  
  51. [predict_label_P2, accuracy_P2, dec_values_P2] = svmpredict(test_label, Ktest2, model_precomputed2);  
  52. %% Precomputed Kernel Three  
  53. % 使用的核函数 K(x,x') = (x * x') / ||x|| * ||x'||  
  54. % 核矩阵  
  55. ktrain3 = ones(150,150);  
  56. for i = 1:150  
  57.     for j = 1:150  
  58.         ktrain3(i,j) = ...  
  59.         train_data(i,:)*train_data(j,:)'/(sum(train_data(i,:).^2)^0.5 * sum(train_data(j,:).^2)^0.5);  
  60.     end  
  61. end  
  62. Ktrain3 = [(1:150)',ktrain3];  
  63. model_precomputed3 = svmtrain(train_label, Ktrain3, '-t 4');  
  64.   
  65. ktest3 = ones(120,150);  
  66. for i = 1:120  
  67.     for j = 1:150  
  68.         ktest3(i,j) = ...  
  69.         test_data(i,:)*train_data(j,:)'/(sum(test_data(i,:).^2)^0.5 * sum(train_data(j,:).^2)^0.5);  
  70.     end  
  71. end  
  72. Ktest3 = [(1:120)', ktest3];  
  73. [predict_label_P3, accuracy_P3, dec_values_P3] = svmpredict(test_label, Ktest3, model_precomputed3);  
  74.   
  75.   
  76. %% Display the accuracy  
  77. accuracyL = accuracy_L(1) % Display the accuracy using linear kernel  
  78. accuracyP1 = accuracy_P1(1) % Display the accuracy using precomputed kernel One  
  79. accuracyP2 = accuracy_P2(1) % Display the accuracy using precomputed kernel Two  
  80. accuracyP3 = accuracy_P3(1) % Display the accuracy using precomputed kernel Three  
  81. %%  
  82. toc;  
运行结果:
[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. Accuracy = 85% (102/120) (classification)  
  2. Accuracy = 85% (102/120) (classification)  
  3. Accuracy = 67.5% (81/120) (classification)  
  4. Accuracy = 84.1667% (101/120) (classification)  
  5. accuracyL =  
  6.     85  
  7. accuracyP1 =  
  8.     85  
  9. accuracyP2 =  
  10.    67.5000  
  11. accuracyP3 =  
  12.    84.1667  
  13. 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在实作上便有困难几乎就是不显示,除非每次训练分类器得到模型的速度很快,或是可以用并行化计算减少计算所需的时间.

代码示例

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. 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类似,这里不再赘述。

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <pre code_snippet_id="88506" snippet_file_name="blog_20131129_4_309256"></pre>  
  2. <pre></pre>  
  3. <pre></pre>  
  4. <pre></pre>  
  5. <pre></pre>  
  6. <pre></pre>  
  7. <pre></pre>  
  8. <pre></pre>  
  9. <pre></pre>  
  10. <pre></pre>  
  11. <pre></pre>  
  12. <pre></pre>  
  13.      

0 0
原创粉丝点击