SVM(支持向量机)是机器学习算法里用得最多的一种算法。SVM最经常使用的是用于分类,只是SVM也能够用于回归,我的实验中就是用SVM来实现SVR(支持向量回归)。

对于功能这么强的算法,opencv中自然也是有集成好了,我们能够直接调用。OpenCV中的SVM算法是基于LibSVM软件包开发的,LibSVM是台湾大学林智仁(Lin Chih-Jen)等开发设计的一个简单、易于使用和高速有效的SVM模式识别与回归的软件包。

网上讲opencv中SVM使用的文章有非常多,但讲SVM參数优化的文章却非常少。所以在这里不重点讲怎么使用SVM,而是谈谈如何通过opencv中自带的库优化SVM中的各參数。

    相信用SVM做过实验的人都知道,SVM的各參数对实验结果有非常大的影响,比方C,gama,P,coef等等。以下就是CvSVMParams类的原型。

C++: CvSVMParams::CvSVMParams()

C++: CvSVMParams::CvSVMParams(int svm_type,

int kernel_type,

double degree,

double gamma,

double coef0,

double Cvalue,

double nu,

double p,

CvMat* class_weights,

CvTermCriteria term_crit

        )

<1>svm_type:指定SVM的类型(5种):
  • CvSVM::C_SVC : C类支持向量分类机。 n类分组  (n≥2),同意用异常值惩处因子C进行不全然分类。
  • CvSVM::NU_SVC : 类支持向量分类机。n类似然不全然分类的分类器。參数为代替C(其值在区间【0,1】中,nu越大,决策边界越平滑)。
  • CvSVM::ONE_CLASS : 单分类器,全部的训练数据提取自同一个类里,然后SVM建立了一个分界线以切割该类在特征空间中所占区域和其他类在特征空间中所占区域。
  • CvSVM::EPS_SVR : 类支持向量回归机。训练集中的特征向量和拟合出来的超平面的距离须要小于p。异常值惩处因子C被採用。
  • CvSVM::NU_SVR : 类支持向量回归机。 代替了 p。

<2>kernel_type:SVM的内核类型(4种):

  • CvSVM::LINEAR : 线性内核,没有不论什么向映射至高维空间,线性区分(或回归)在原始特征空间中被完毕,这是最快的选择。
            .
  • CvSVM::POLY : 多项式内核:
             .
  • CvSVM::RBF : 基于径向的函数,对于大多数情况都是一个较好的选择:
             .
  • CvSVM::SIGMOID : Sigmoid函数内核:
            .
<3>degree:内核函数(POLY)的參数degree。
<4>gamma:内核函数(POLY/ RBF/ SIGMOID)的參数
<5>coef0:内核函数(POLY/ SIGMOID)的參数coef0。
<6>Cvalue:SVM类型(C_SVC/ EPS_SVR/ NU_SVR)的參数C。
<7>nu:SVM类型(NU_SVC/ ONE_CLASS/ NU_SVR)的參数 
<8>p:SVM类型(EPS_SVR)的參数
<9>class_weights:C_SVC中的可选权重,赋给指定的类,乘以C以后变成 。所以这些权重影响不同类别的错误分类惩处项。权重越大,某一类别的误分类数据的惩处项就越大。
<10>term_crit:SVM的迭代训练过程的中止条件,解决部分受约束二次最优问题。您能够指定的公差和/或最大迭代次数。
    当然对于一个特定的SVM训练器,里面的全部參数不一定全用。比方我用的svm_type为EPS_SVR,那么我要用到的參数主要就是p,c,gama这三个參数。以下是设置參数的代码
	CvSVMParams param;
param.svm_type = CvSVM::EPS_SVR; //我的实验是用SVR作回归分析,可能大部分人的实验是用SVM来分类,方法都一样
param.kernel_type = CvSVM::RBF;
param.C = 1;
param.p = 5e-3;
param.gamma = 0.01;
param.term_crit = cvTermCriteria(CV_TERMCRIT_EPS, 100, 5e-3);

       设置參数后就能够用CvSVM.train()进行训练了,以下是train的原型

C++: bool CvSVM::train(const Mat& trainData,

      const Mat& responses,

const Mat& varIdx=Mat(),

const Mat& sampleIdx=Mat(),

CvSVMParams params=CvSVMParams()

)

      我在用train完毕训练预測时出现了过拟合的情况,即对于训练集的数据有非常好的预測结果,但对不在训练集的測试集预測值都一样(我在网上看到非常多网友也遇到这个问题)。于是我開始调整參数,调了半天也没个好结果。
     后面我发现事实上opencv中SVM类是提供了优化參数值功能的,瞬间感觉世界美好了。以下讲讲详细的做法。
     要让svm自己主动优化參数,那么训练时就不能再用train函数了,而应该用train_auto函数。以下是train_auto的函数原型

C++: bool CvSVM::train_auto(const Mat& trainData,

const Mat& responses,

const Mat& varIdx,

const Mat& sampleIdx,

CvSVMParams params,

int k_fold=10,

CvParamGrid Cgrid=CvSVM::get_default_grid(CvSVM::C), CvParamGrid gammaGrid=CvSVM::get_default_grid(CvSVM::GAMMA), CvParamGrid pGrid=CvSVM::get_default_grid(CvSVM::P),
CvParamGrid nuGrid=CvSVM::get_default_grid(CvSVM::NU), CvParamGrid coeffGrid=CvSVM::get_default_grid(CvSVM::COEF), CvParamGrid degreeGrid=CvSVM::get_default_grid(CvSVM::DEGREE),

bool balanced=false

)

自己主动训练函数的參数凝视(13个)

  • 前5个參数參考构造函数的參数凝视。
  • k_fold: 交叉验证參数。训练集被分成k_fold的自子集。当中一个子集是用来測试模型,其它子集则成为训练集。所以,SVM算法复杂度是运行k_fold的次数。
  • *Grid: (6个)相应的SVM迭代网格參数。
  • balanced: 假设是true则这是一个2类分类问题。这将会创建很多其它的平衡交叉验证子集。
    自己主动训练函数的使用说明
  • 这种方法依据CvSVMParams中的最佳參数C, gamma, p, nu, coef0, degree自己主动训练SVM模型。
  • 參数被觉得是最佳的交叉验证,其測试集预估错误最小。
  • 假设没有须要优化的參数,对应的网格步骤应该被设置为小于或等于1的值。比如,为了避免gamma的优化,设置gamma_grid.step = 0,gamma_grid.min_val, gamma_grid.max_val 为随意数值。所以params.gamma 由gamma得出。
  • 最后,假设參数优化是必需的,可是对应的网格却不确定,你可能须要调用函数CvSVM::get_default_grid(),创建一个网格。比如,对于gamma,调用CvSVM::get_default_grid(CvSVM::GAMMA)。
  • 该函数为分类执行 (params.svm_type=CvSVM::C_SVC 或者 params.svm_type=CvSVM::NU_SVC) 和为回归执行 (params.svm_type=CvSVM::EPS_SVR 或者 params.svm_type=CvSVM::NU_SVR)效果一样好。假设params.svm_type=CvSVM::ONE_CLASS,没有优化,并指定执行一般的SVM。
     这里须要注意的是,对于须要的优化的參数尽管train_auto能够自己主动选择最优值,但在代码中也要先赋初始值,要不然编译能通过,但执行时会报错。以下是演示样例代码
	CvSVMParams param;
param.svm_type = CvSVM::EPS_SVR;
param.kernel_type = CvSVM::RBF;
param.C = 1; //给參数赋初始值
param.p = 5e-3; //给參数赋初始值
param.gamma = 0.01; //给參数赋初始值
param.term_crit = cvTermCriteria(CV_TERMCRIT_EPS, 100, 5e-3);
//对不用的參数step设为0
CvParamGrid nuGrid = CvParamGrid(1,1,0.0);
CvParamGrid coeffGrid = CvParamGrid(1,1,0.0);
CvParamGrid degreeGrid = CvParamGrid(1,1,0.0); CvSVM regressor;
regressor.train_auto(PCA_training,tr_label,NULL,NULL,param,
10,
regressor.get_default_grid(CvSVM::C),
regressor.get_default_grid(CvSVM::GAMMA),
regressor.get_default_grid(CvSVM::P),
nuGrid,
coeffGrid,
degreeGrid);

用上面的代码的就能够自己主动训练并优化參数。最后,若想查看优化后的參数值,能够使用CvSVM::get_params()函数来获得优化后的CvSVMParams。以下是演示样例代码:

CvSVMParams params_re = regressor.get_params();
regressor.save("training_srv.xml");
float C = params_re.C;
float P = params_re.p;
float gamma = params_re.gamma;
printf("\nParms: C = %f, P = %f,gamma = %f \n",C,P,gamma);
 
 本文系原创,转载请注明转载自 http://blog.csdn.net/computerme/article/details/38677599

      

OpenCV中的SVM參数优化的更多相关文章

  1. OpenCV中的SVM参数优化

    OpenCV中的SVM参数优化 svm参数优化opencv SVMSVR参数优化CvSVMopencv CvSVM        SVM(支持向量机)是机器学习算法里用得最多的一种算法.SVM最常用的 ...

  2. ubuntu nginx安装及相关linux性能參数优化

    一.安装 下载源代码,解压:tar -xzvf nginx-1.4.7.tar.gz ./configure make && make install 改动默认nginx的监听port ...

  3. 研究下JavaScript中的Rest參数和參数默认值

    研究下JavaScript中的Rest參数和參数默认值 本文将讨论使 JavaScript 函数更有表现力的两个特性:Rest 參数和參数默认值. Rest 參数 通常,我们须要创建一个可变參数的函数 ...

  4. opencv中的SVM图像分类(二)

    opencv中的SVM图像分类(二) 标签: svm图像 2015-07-30 08:45 8296人阅读 评论(35) 收藏 举报  分类: [opencv应用](5)  版权声明:本文为博主原创文 ...

  5. iOS 处理方法中的可变參数

    ## iOS 处理方法中的可变參数 近期写了一个自己定义的对话框的demo,想模仿系统的UIAlertView的实现方式.对处理可变參数的时候,遇到了小问题,于是谷歌了一下.写下了处理问题的方法.记录 ...

  6. 发现个delphi调用vc写的Dll中包括pchar參数报错奇怪现象

    发现个delphi调用vc写的Dll中包括pchar參数奇怪现象 procedure中的第一行语句不能直接调用DLL的函数,否则会执行报错,在之前随意加上条语句就不报错了奇怪! vc的DLL源代码地址 ...

  7. Extjs4.2 ajax请求url中传中文參数乱码问题

    今天有个需求须要在url中传入中文參数.结果在后台取得时出现乱码,怀疑可能是编码问题.上网查询了资料,试了几种办法.发现有一种可行,记录在此,以便查阅. url中用encodeURI 进行2次编码: ...

  8. Ngnix中的fastcgi參数性能优化和解释

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/luozhonghua2014/article/details/37737823 优化性能參数设置,在 ...

  9. MySQL具体解释(21)------------缓存參数优化

    数据库属于 IO 密集型的应用程序.其主要职责就是数据的管理及存储工作. 而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个IO是在毫秒级别,二者相差3个数量级.所以,要优 ...

随机推荐

  1. HDU4939Stupid Tower Defense (有思想的dp)

    Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Oth ...

  2. Windows XP 如何查看计算机开关机记录

    在Windows XP中,我们可以通过“事件查看器”的事件日志服务查看计算机的开.关机时间.因为事件日志服务会随计算机一起启动和关闭,并在事件日志中留下记录. 在这里有必要介绍两个ID号:6006和6 ...

  3. 解决sqlserver2008 r2 登陆时报错:provider 命名管道提供程序, error40 错误2

    错误截图: 这种错误是因为无法启动sqlserver服务,进入命令行,输入  services.msc  进入服务管理,找到sqlserver服务如下图. 在这里启动该服务会报错如下图: 此服务无法启 ...

  4. mysql iot 主键自增列问题

    mysql 如何避免热点块? 主键按sn自增列 Oracle 可以通过翻转索引 比如 插入101 102 103 104 变成101 201 301 401 分散数据 反转索引坏处,无法index r ...

  5. chfn,chsh,last,login,mail ,mesg ,talk,wall,write,nice ,pstree ,renice,skill ,expr ,reset,tset,compress ,lpd ,lpq ,lpr ,lprm,fdformat ,mformat ,mkdosf

    名称:chfn 使用权限:所有使用者 用法:shell>> chfn 说明:提供使用者更改个人资讯,用于finger and mail username 范例: shell>> ...

  6. Jar包转成Dll的方式(带嵌套的jar也能做) (转)

    研究很好几天,终于成功了.因为写了一个Java的项目,现在要求要改写成C#版本的.但是其中用到了svnkit,svnkit是java平台的.改写成C#的话,要使用SharpSVN,但是SharpSVN ...

  7. 2cifang.com_2次方学习

    2cifang.com_2次方学习

  8. Oracle的dbms_output包的put()和put_line()的区别只是有没有回车换行吗?(转)

    答案是否 除了自动添加回车换行外,还有就是缓冲区最大容量的问题!! 无论如何设置serveroutput size,10g里 put() 最多只能输出 32767 个byte 而 put_line() ...

  9. About VirtualBoxImages.com

    About VirtualBoxImages.com | VirtualBoxImages.com About VirtualBoxImages.com About: VirtualBoxImages ...

  10. Android中的跨进程通信方法实例及特点分析(二):ContentProvider

    1.ContentProvider简单介绍 在Android中有些数据(如通讯录.音频.视频文件等)是要供非常多应用程序使用的.为了更好地对外提供数据.Android系统给我们提供了Content P ...