前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV 2.4.9 支持向量机(SVM)说明

OpenCV 2.4.9 支持向量机(SVM)说明

作者头像
剑影啸清寒
发布2018-01-02 13:30:19
1.7K0
发布2018-01-02 13:30:19
举报
文章被收录于专栏:琦小虾的Binary琦小虾的Binary

本文翻译自OpenCV 2.4.9官方文档《opencv2refman.pdf》。

前言

Originally, support vector machines (SVM) was a technique for building an optimal binary (2-class) classifier. Later the technique was extended to regression and clustering problems. SVM is a partial case of kernel-based methods. It maps feature vectors into a higher-dimensional space using a kernel function and builds an optimal linear discriminating function in this space or an optimal hyper-plane that fits into the training data. In case of SVM, the kernel is not defined explicitly. Instead, a distance between any 2 points in the hyper-space needs to be defined. The solution is optimal, which means that the margin between the separating hyper-plane and the nearest feature vectors from both classes (in case of 2-class classifier) is maximal. The feature vectors that are the closest to the hyper-plane are called support vectors, which means that the position of other vectors does not affect the hyper-plane (the decision function). SVM implementation in OpenCV is based on LibSVM.

通常来说,支持向量机(SVM)是一种用来构建一个最优二进制分类器(只分为两类)。后来,这项技术被延伸到回归与集群问题。SVM是以核函数方法为基础的众多方法之一,它通过核函数将特征向量映射到高维空间,并在这个空间创造一个最优线性分类函数,或者创造一个适合所有训练数据的最优超平面。在SVM中,核函数定义的并不明确,除此之外,在超平面上任意两点之间的距离都需要被定义。 解决方法是最优的,意味着分割超平面与两个分类(即二类分类器)上距离最近的特征向量之间的距离是最大的。距离超平面最近的特征向量被称为支持向量,就是说其它向量的位置都不会影响超平面(即决策函数)。 SVM在OpenCV中的实现是基于LibSVM的。

CvParamGrid

CvParamGrid

struct CvParamGrid 该结构体代表了统计模型参数的对数网格范围,它通过更新模型参数来优化统计模型准确度,准确度通过交叉验证的计算进行估计。

  • double CvParamGrid::min_val
    • 统计模型参数的最小值;
  • double CvParamGrid::max_val
    • 统计模型参数的最大值;
  • double CvParamGrid::step
    • 迭代统计模型参数的对数步长;

网格决定了统计模型参数值的迭代序列,如下所示:

其中n是一个最大索引号,满足:

网格已经经过对数化,所以step一定大于1。

CvParamGrid::CvParamGrid

CvParamGrid的构造函数。

  • C++: CvParamGrid::CvParamGrid()
  • C++: CvParamGrid::CvParamGrid( double min_val, double max_val, double log_step )

整个构造函数初始化了对应的数据成员,默认的构造函数创造的虚拟网格如下:

代码语言:javascript
复制
CvParamGrid::CvParamGrid()
{
    min_val = max_val = step = 0;
}

CvParamGrid::check

检测网格的有效性。

  • C++: bool CvParamGrid::check()

如果网格有效的,则返回true;如;如果无效,则返回false。当且仅当下列情况时,网格是有效的:

  • 网格的下边缘边界小于上边缘边界;
  • 网格的下边缘边界是正值;
  • 网格步长大于1;

CvSVMParams

CvSVMParams

struct CvSVMParams SVM训练参数。结构体将被初始化,并传递给CvSVM的训练函数。

CvSVMParams::CvSVMParams

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 )

CvSVMParams()的参数

svm_type

SVM公式类型。可能取值如下:

  • CvSVM::C_SVCCC支持向量分类器。可以分为n类 (n ≥ 2),并允许在带有松弛变量 (outliers) 的惩罚乘子C的情况下的不完善分类;
  • CvSVM::NU_SVCν\nu支持向量分类器。可以分为n类 (n ≥ 2),而且可能存在不完善的分类。参数ν\nu替代参数CC使用,且ν\nu值范围在[0, 1]之内,该值越大,决策边缘越光滑;
  • CvSVM::ONE_CLASS:分布估计(单类SVM)。所有的训练数据都是同一类的,SVM构建了边界,将该类与特征空间的其他部分分离;
  • CvSVM::EPS_SVRϵ\epsilon支持向量回归。训练集特征向量与拟合超平面间的距离一定小于pp。该分类器的松弛变量 (outliers) 使用的惩罚因子为CC;
  • CvSVM::NU_SVRν\nu支持向量回归。ν\nu被用来代替pp;

其他具体解释见LibSVM

kernel_type

SVM核函数类型。可能取值如下:

degree

核函数的参数degreedegree,用于多项式核。

gamma

核函数的参数γ\gamma,用于多项式核 / RBF核 / Sigmoid核。

coef0

核函数的参数coef0coef0,用于多项式核 / Sigmoid核。

Cvalue

SVM最优问题的参数CC,用于 C_SVC / EPS_SVR / NU_SVR 分类器。

nu

SVM最优问题的参数ν\nu,用于 NU_SVC / ONE_CLASS / NU_SVR 分类器。

p

SVM最优问题的参数ϵ\epsilon,用于 EPS_SVR 分类器。

class_weights

C_SVC问题中的最优权重,它被分配给特定的分类。这些权重与因子C做乘运算,所以第 i 个分类的的参数C值应该为:

因此,这些权重对其他分类的误分类惩罚有一定影响,权重越大,对应分类的数据误分类的惩罚越大。

term_crit

SVM训练迭代的迭代终止标准,用于解决带有约束条件的二次最优规划问题。你也能明确公差与 / 或迭代最大次数。

CvSVMParams()的函数

默认的构造函数使用下列取值初始化该结构体:

代码语言:javascript
复制
CvSVMParams::CvSVMParams() :
svm_type(CvSVM::C_SVC), kernel_type(CvSVM::RBF), degree(0),
gamma(1), coef0(0), C(1), nu(0), p(0), class_weights(0)
{
    term_crit = cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 1000, FLT_EPSILON );
}

CvSVM

class CvSVM : public CvStatModel

支持向量机。

注: · (Python) 使用SVM的数字识别例程可以在路径 opencv_source/samples/python2/digits.py 下找到; · (Python) 使用SVM的网格寻找数字识别可以在路径 opencv_source/samples/python2/digits_adjust.py 下找到; · (Python) 使用SVM的视频数字识别例程可以在路径 opencv_source/samples/python2/digits_video.py 下找到;

CvSVM::CvSVM

默认构造函数与训练构造函数。

  • C++: CvSVM::CvSVM()
  • C++: CvSVM::CvSVM( const Mat& trainData, const Mat& responses, const Mat& varIdx=Mat(), const Mat& sampleIdx=Mat(), CvSVMParams params=CvSVMParams() )
  • C++: CvSVM::CvSVM( const CvMat* trainData, const CvMat* responses, const CvMat* varIdx=0, const CvMat* sampleIdx=0, CvSVMParams params=CvSVMParams() )
  • Python: cv2.SVM( [ trainData, responses [ , varIdx [ , sampleIdx [ , params ]]]] ) →

构造函数与CvStatModel::CvStatModel()有相同的形式。可以在本文档的CvStatModel::train()寻找参数的具体含义。

本文注: 下面从CvStatModel::train()中找到参数列表:

  • C++: bool CvStatModel::train( const Mat& train_data, [int tflag,] …, const Mat& responses, …, [const Mat& var_idx,] …, [const Mat& sample_idx,] … [const Mat& var_type,] …, [const Mat& missing_mask,] … ) = 0

对于其中参数,解释如下:

CvSVM()的参数

通过使用一组输入特征向量并输出相应值(或响应)的方法,训练函数训练了统计模型。输入 / 输出向量(或输入 / 输出值)都以矩阵形式传递。默认情况下,输入特征向量被存入train_data的列中,所有训练向量的组成(即特征)被连续存储。然而当全部输入集的各特定特征值(特征 / 输入变量)的所有值都是连续存储的情况下,一些算法可以处理转置表达式。如果两种布局都支持,训练方法包含的tflag参数起作用,该参数用来明确数据存储方向,具体如下:

  • tflag=CV_ROW_SAMPLE:特征向量按行存储;
  • tflag=CV_COL_SAMPLE:特征向量按列存储;

训练数据train_data必须使用CV_32FC1格式(32位浮点数,单通道)。返回数据responses通常以一维向量(一行或一列)的形式存储,向量中的数据格式为CV_32SC1(仅在分类问题中)或CV_32FC1,返回数据的每个值与训练数据的每个向量一一对应。相反的,某些类似于各种类型的神经网络,返回数据的类型都为向量形式。 对于分类问题,返回值是离散的分类标签;对于回归问题,返回值是被估计函数的值。一些算法只能处理分类问题,一些算法只能处理回归问题,也有一些算法可以处理两种问题。对于后者,输出参数的类型可以通过两种方式传递:一种是单独的参数,另一种是向量var_type的最后一个元素:

  • CV_VAR_CATEGORICAL:输出值为离散类别标签;
  • CV_VAR_ORDERED( =CV_VAR_NUMERICAL):输出值为顺序排列的,即两个不同的值可以以数字形式拿来对比,而且这是一个回归问题;

输入变量的类型可以通过输入参数var_type指定。大多数算法仅仅可以处理连续输入变量。 很多 ML (机器学习)模型可以用一个指定的特征子集与 / 或指定的训练集的样本子集进行训练。为了使其对我们更加简单,训练方法train函数通常包含参数var_idxsample_idx,前者(即var_idx)用来指定该兴趣的变量(特征),后者(即sample_idx)指定感兴趣的样本。两个向量可以使用整数 (CV_32SC1) 向量(基于0的索引列表),也可以使用8位 (CV_8UC1)的活动变量 / 样本。我们也可以传递NULL空指针来代替众多参数,这样的话所有的变量 / 样本都被用来训练。 此外,当已知训练样本的已知特征存在未知值时,一些算法可以处理丢失的量(例如,我们星期一忘记测量病人A的体温)。参数missing_mask是一个与train_data有相同尺寸的8位矩阵,它被用来标记丢失的值(即用非零值进行标记)。 通常,先前的模型统计在运行训练函数之前都被CvStatModel::clear()清除了,然而一些算法可以选择使用新训练数据更新模型统计,而不是重置它。

CvSVM::train

训练一个SVM。

  • C++: bool CvSVM::train( const Mat& trainData, const Mat& responses, const Mat& varIdx=Mat(), const Mat& sampleIdx=Mat(), CvSVMParams params=CvSVMParams() )
  • C++: bool CvSVM::train( const CvMat* trainData, const CvMat* responses, const CvMat* varIdx=0, const CvMat* sampleIdx=0, CvSVMParams params=CvSVMParams() )
  • Python: cv2.SVM.train( trainData, responses [ , varIdx [ , sampleIdx [ , params ]]] ) → retval

该函数用来训练一个 SVM 模型,它继承了CvStatModel::train()函数的参数列表,但对下列进行了限制:

  • 数据布局仅仅支持CV_ROW_SAMPLE
  • 输入变量全部为连续值;
  • 输出变量可以是离散的 (param.svm = CvSVM::C_SVC 或 param.svm = CvSVM::NU_SVC),也可以是连续的 (param.svm = CvSVM::EPS_SVR 或 param.svm = CvSVM::NU_SVR),也可以不指定 (param.svm = CvSVM::ONE_CLASS)。
  • 不支持丢失测量值;

所有其他参数都被收集进入CvSVMParams结构体。

CvSVM::train_auto

用最优参数训练SVM。

  • 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 )
  • C++: bool CvSVM::train_auto( const CvMat* trainData, const CvMat* responses, const CvMat* varIdx, const CvMat* sampleIdx, CvSVMParams params, int kfold=10,   CvParamGrid Cgrid=get_default_grid(CvSVM::C),   CvParamGrid gammaGrid=get_default_grid(CvSVM::GAMMA),   CvParamGrid pGrid=get_default_grid(CvSVM::P),   CvParamGrid nuGrid=get_default_grid(CvSVM::NU),   CvParamGrid coeffGrid=get_default_grid(CvSVM::COEF),   CvParamGrid degreeGrid=get_default_grid(CvSVM::DEGREE),   bool balanced=false )
  • Python: cv2.SVM.train_auto( trainData, responses, varIdx, sampleIdx, params [ , k_fold [ , Cgrid [ , gammaGrid [ , pGrid [ , nuGrid [ , coeffGrid [ , degreeGrid [ , balanced ]]]]]]]] ) → retval

train_auto()参数

  • k_fold:交叉验证参数。训练集被分成k_fold子集。一个子集被用于测试模型,其余子集组成训练集。所以 SVM 算法总共被执行 k_fold 次;
  • Grid:相关SVM参数的迭代网格;
  • balanced:如果为true,而且问题为二类分类器,那么该函数就创造更平衡的交叉验证子集,子集各分类之间的比例接近在整个训练数据集中比例;

train_auto()函数说明

train_auto()函数通过从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)train_auto()函数可以被用来处理分类问题 (param.svm = CvSVM::C_SVC 或 param.svm = CvSVM::NU_SVC),也可以处理回归问题 (param.svm = CvSVM::EPS_SVR 或 param.svm = CvSVM::NU_SVR)。如果有param.svm_type = CvSVM::ONE_CLASS,则不会生成最优值,且普通带有确定参数的 SVM 将被执行。

CvSVM::predict

预测输入样本的返回值。

  • C++: float CvSVM::predict( const Mat& sample, bool returnDFVal=false ) const
  • C++: float CvSVM::predict( const CvMat* sample, bool returnDFVal=false ) const
  • C++: float CvSVM::predict( const CvMat* samples, CvMat* results ) const
  • Python: cv2.SVM.predict( sample [ , returnDFVal ] ) → retval
  • Python: cv2.SVM.predict_all( samples [ , results ] ) → results

predict()参数

  • sample:预测的单个输入样本;
  • samples:预测的多输入样本;
  • returnDFVal:指定一个返回值的类型。如果为true,且问题为二类分类器,那么该函数返回决策函数值是有符号的间隔距离;如果为false,那么函数返回一个类标签(分类问题),或者返回估计函数值(回归问题);
  • results:输出对应样本的预测返回值;

如果我们通过了一个样本,那么预测结果就会返回。如果我们想要得到几个样本的返回值,那么我们应该用矩阵results来保存预测结果。 该函数与 TBB 库并行运行。

CvSVM::get_default_grid

生成一个 SVM 参数的网格。

  • C++: CvParamGrid CvSVM::get_default_grid( int param_id )

param_id SVM 参数的 ID,必须从下列表中取值:

  • CvSVM::C
  • CvSVM::GAMMA
  • CvSVM::P
  • CvSVM::NU
  • CvSVM::COEF
  • CvSVM::DEGREE

网格将根据该 ID 参数生成。

该函数根据 SVM 算法的指定参数而生成一个网格,该网格会传递给函数CvSVM::train_auto()

CvSVM::get_params

返回当前 SVM 参数。

  • C++: CvSVMParams CvSVM::get_params() const

在使用函数CvSVM::train_auto()自动训练时,该函数被用来获取最优参数。

CvSVM::get_support_vector

取得若干支持向量与特定的向量。

  • C++: int CvSVM::get_support_vector_count() const
  • C++: const float* CvSVM::get_support_vector( int i ) const
  • Python: cv2.SVM.get_support_vector_count() → retval

i:特定的支持向量的序列;

该方法用来取得一组支持向量。

CvSVM::get_var_count

返回已使用特征的数量(即变量数量);

  • C++: int CvSVM::get_var_count() const
  • Python: cv2.SVM.get_var_count() → retval
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • CvParamGrid
    • CvParamGrid
      • CvParamGrid::CvParamGrid
        • CvParamGrid::check
        • CvSVMParams
          • CvSVMParams
            • CvSVMParams::CvSVMParams
              • CvSVMParams()的参数
              • CvSVMParams()的函数
          • CvSVM
            • class CvSVM : public CvStatModel
              • CvSVM::CvSVM
                • CvSVM()的参数
              • CvSVM::train
                • CvSVM::train_auto
                  • train_auto()参数
                  • train_auto()函数说明
                • CvSVM::predict
                  • predict()参数
                • CvSVM::get_default_grid
                  • CvSVM::get_params
                    • CvSVM::get_support_vector
                      • CvSVM::get_var_count
                      相关产品与服务
                      数据保险箱
                      数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档