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这三个参数。下面是设置参数的代码
  1. CvSVMParams param;
  2. param.svm_type = CvSVM::EPS_SVR;  //我的实验是用SVR作回归分析,可能大部分人的实验是用SVM来分类,方法都一样
  3. param.kernel_type = CvSVM::RBF;
  4. param.C = 1;
  5. param.p = 5e-3;
  6. param.gamma = 0.01;
  7. 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可以自动选择最优值,但在代码中也要先赋初始值,要不然编译能通过,但运行时会报错。下面是示例代码
  1. CvSVMParams param;
  2. param.svm_type = CvSVM::EPS_SVR;
  3. param.kernel_type = CvSVM::RBF;
  4. param.C = 1;  //给参数赋初始值
  5. param.p = 5e-3;  //给参数赋初始值
  6. param.gamma = 0.01;  //给参数赋初始值
  7. param.term_crit = cvTermCriteria(CV_TERMCRIT_EPS, 100, 5e-3);
  8. //对不用的参数step设为0
  9. CvParamGrid nuGrid = CvParamGrid(1,1,0.0);
  10. CvParamGrid coeffGrid = CvParamGrid(1,1,0.0);
  11. CvParamGrid degreeGrid = CvParamGrid(1,1,0.0);
  12. CvSVM regressor;
  13. regressor.train_auto(PCA_training,tr_label,NULL,NULL,param,
  14. 10,
  15. regressor.get_default_grid(CvSVM::C),
  16. regressor.get_default_grid(CvSVM::GAMMA),
  17. regressor.get_default_grid(CvSVM::P),
  18. nuGrid,
  19. coeffGrid,
  20. degreeGrid);

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

  1. CvSVMParams params_re = regressor.get_params();
  2. regressor.save("training_srv.xml");
  3. float C = params_re.C;
  4. float P = params_re.p;
  5. float gamma = params_re.gamma;
  6. 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參数优化

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

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

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

  3. OpenCV中使用SVM简介

    下面这是opencv官方文档中的代码,我加了一部分注释: #include "stdafx.h" #include "opencv2/core/core.hpp" ...

  4. paper 32 :svm参数优化的进展

    从今天开始,我的微信公众号“天空之窗”就暂且停止更新内容了,专心搞研究!上午从师姐那儿淘到一份关于faruto讲解的Libsvm-FarutoUltimate3.1 based on libsvm-3 ...

  5. Opencv中SVM样本训练、归类流程及实现

    支持向量机(SVM)中最核心的是什么?个人理解就是前4个字--"支持向量",一旦在两类或多累样本集中定位到某些特定的点作为支持向量,就可以依据这些支持向量计算出来分类超平面,再依据 ...

  6. OpenCV机器学习库函数--SVM

    svm分类算法在opencv3中有了很大的变动,取消了CvSVMParams这个类,因此在参数设定上会有些改变. opencv中的svm分类代码,来源于libsvm. #include "o ...

  7. 【OpenCV】opencv3.0中的SVM训练 mnist 手写字体识别

    前言: SVM(支持向量机)一种训练分类器的学习方法 mnist 是一个手写字体图像数据库,训练样本有60000个,测试样本有10000个 LibSVM 一个常用的SVM框架 OpenCV3.0 中的 ...

  8. Linux中MySQL配置文件my.cnf参数优化

    MySQL参数优化这东西不好好研究还是比较难懂的,其实不光是MySQL,大部分程序的参数优化,是很复杂的.MySQL的参数优化也不例外,对于不同的需求,还有硬件的配置,优化不可能又最优选择,只能慢慢的 ...

  9. [OpenCV-Python] OpenCV 中机器学习 部分 VIII

    部分 VIII机器学习 OpenCV-Python 中文教程(搬运)目录 46 K 近邻(k-Nearest Neighbour ) 46.1 理解 K 近邻目标 • 本节我们要理解 k 近邻(kNN ...

随机推荐

  1. 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  2. Atcoder Grand 011 C - Squared Graph

    题意: 给出一个n个点的图,现在构造一个有n^2个点的新图,新图每个点表示为(a,b)(a,b<=n),两个点$(a,b),(c,d)$之间有边当且仅当原图中ac之间有边,bd之间有边. 问新图 ...

  3. 洛谷P1155 双栈排序

    这题什么毒瘤......之前看一直没思路,然后心说写个暴搜看能有多少分,然后就A了??! 题意:给你一个n排列,求它们能不能通过双栈来完成排序.如果能输出最小字典序方案. [update]这里面加了一 ...

  4. 界面编程之QT的线程20180731

    /*******************************************************************************************/ 一.为什么需 ...

  5. 各种蕴含算法思想的DP - 1

    study from: https://www.cnblogs.com/flashhu/p/9480669.html 1.前缀和 https://www.luogu.org/problemnew/sh ...

  6. @RequestParam注解一般用法

    原文链接:https://www.cnblogs.com/likaileek/p/7218252.html SpringMVC注解@RequestParam全面解析   在此之前,写项目一直用的是@R ...

  7. Bellman-Ford 最短路径算法

    算法证明:http://courses.csail.mit.edu/6.006/spring11/lectures/lec15.pdf 先来看一个这样的图: 这是含有负边权的,如果是用djistra的 ...

  8. 何凯文每日一句打卡||DAY7

  9. Docker 入门 第二部分: 容器

    目录 Docker 入门 第二部分: 容器 先决条件 介绍 你的新开发环境 使用 Dockerfile 定义一个容器 Dockerfile 应用本身 requirements.txt app.py 构 ...

  10. htm、html、shtml网页区别

    htm.html.shtml网页区别 html或者htm是一种静态的页面格式,也就是说不需要服务器解析其中的脚本,或者说里面没有服务器端执行的脚本,而shtml或者shtm由于它基于SSI技术,当有服 ...