SVM支持向量机算法及其代码实现
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
virtual bool train( const CvMat* _train_data, const CvMat* _responses, const CvMat* _var_idx=0, const CvMat* _sample_idx=0, CvSVMParams _params=CvSVMParams() );
double
nu; // for CV_SVM_NU_SVC, CV_SVM_ONE_CLASS, and CV_SVM_NU_SVR
double
p; // for CV_SVM_EPS_SVR
CvMat*
class_weights; // for CV_SVM_C_SVC
CvTermCriteria term_crit; // termination criteria
解是最优的在某种意义上是两类中距离分割面最近的特征向量和分割面的距离最大化。离分 割面最近的特征向量被称为”支撑向量”,意即其它向量不影响分割面(决策函数)。
有很多关于 SVM 的参考文献,这是两篇较好的入门文献。
【 Burges98 】 C. Burges. "A tutorial on support vector machines for pattern recognition", Knowledge Discovery and Data Mining 2(2), 1998. (available online at [1]).
virtual void clear();
virtual void save( const char* filename, const char* name=0 ); virtual void load( const char* filename, const char* name=0 );
virtual void write( CvFileStorage* storage, const char* name ); virtual void read( CvFileStorage* storage, CvFileNode* node ); int get_var_count() const { return var_idx ? var_idx->cols : var_all; }
};
svm_type,SVM 的类型:
CvSVM::C_SVC - n(n>=2)分类器,允许用异常值惩罚因子 C 进行不完全分类。 CvSVM::NU_SVC - n 类似然不完全分类的分类器。参数 nu 取代了 c,其值在区间【0,1】中, nu 越大,决策边界越平滑。 CvSVM::ONE_CLASS - 单分类器,所有的训练数据提取自同一个类里,然後 SVM 建立了一个 分界线以分割该类在特征空间中所占区域和其它类在特征空间中所占区域。 CvSVM::EPS_SVR - 回归。 训练集中的特征向量和拟合出来的超平面的距离需要小于 p。异
int int double double double
svm_type; kernel_type; degree; // for poly gamma; // for poly/rbf/sigmoid coef0; // for poly/sigmoid
double
C; // for CV_SVM_C_SVC, CV_SVM_EPS_SVR and CV_SVM_NU_SVR
_params.svm_type=CvSVM::NU_SVR)
or
not
required
at
பைடு நூலகம்
all
(_params.svm_type=CvSVM::ONE_CLASS), missing measurements are not supported.
所有的参数都被集成在 CvSVMParams 这个结构中。
首先是 SVM 的训练,这部分我并没有整合到 VC 里,直接使用它提供的 python 程序,虽然 网格搜索这种简易搜索也可以自己写,但是识别时只需要训练生成的 SVMmodel 文件即可, 所以可以和主程序分离开。至于 python 在 windows 下的使用,还是要设置一下的,首先要 在系统环境变量 path 里把 python 的路径设进去,libsvm 画训练等高线图还需要 gnuplot 的 支持,打开 python 源程序(grid.py),把 gnuplot_exe 设置成你机器里的安装路径,这样才能 正确的运行程序。然後就是改步长和搜索范围,官方建议是先用大步长搜索,搜到最优值後 再用小步长在小范围内搜索(我觉得这有可能会陷入局部最优,不过近似出的结果还可以接 受)。我用的 python 版本是 2.4,gnuplot4.0。
virtual float predict( const CvMat* _sample ) const; virtual int get_support_vector_count() const; virtual const float* get_support_vector(int i) const;
The method trains SVM model. It follows the conventions of generic train "method" with the
following limitations: only CV_ROW_SAMPLE data layout is supported, the input variables are all
CvSVM::train 训练 SVM
bool CvSVM::train( const CvMat* _train_data, const CvMat* _responses, const CvMat* _var_idx=0, const CvMat* _sample_idx=0, CvSVMParams _params=CvSVMParams() );
补充:在 WindowsXP+OpenCVRC1 平台下整合 OpenCV 与 libSVM 虽然从 RC1 版开始 opencv 开始增设 ML 类,提供对常见的分类器和回归算法的支持。但是尚存在一些问题,比如说例 子少(官方许诺说很快会提供一批新例子,见 CVS 版)。单说 SVM 这种算法,它自己提供了 一套比较完备的函数,但是并不见得优于老牌的 libsvm(它也应该参考过 libsvm,至于是否 效率优于 libsvm,我并没有作过测试,官方也没有什么说法,但是 libsvm 持续开源更新,是 公认的现存的开源 SVM 库中最易上手,性能最好的库)。所以在你的程序里整合 opencv 和 libSVM 还是一种比较好的解决方案。在 VC 中整合有些小地方需要注意,这篇文档主要是提 供把图象作为 SVM 输入时程序遇到的这些小问题的解决方案。希望大家遇到问题时,多去 读 libSVM 的源码,它本身也是开源的,C 代码写得也很优秀,数据结构定义得也比较好。
// SVM type enum { C_SVC=100, NU_SVC=101, ONE_CLASS=102, EPS_SVR=103, NU_SVR=104 };//SVC 是 SVM 分类器,SVR 是 SVM 回归
// SVM kernel type enum { LINEAR=0, POLY=1, RBF=2, SIGMOID=3 }; //提供四种核函数,分别是线性,多项式, 径向基,sigmoid 型函数。
C, nu, p:在一般的 SVM 优化求解时的参数。
class_weights: Optional weights, assigned to particular classes. They are multiplied by C and thus affect the mis-classification penalty for different classes. The larger weight, the larger penalty on mis-classification of data from the certain class.
CvSVM(); virtual ~CvSVM();
CvSVM( const CvMat* _train_data, const CvMat* _responses, const CvMat* _var_idx=0, const CvMat* _sample_idx=0, CvSVMParams _params=CvSVMParams() );
term_crit: Termination procedure for iterative SVM training procedure (which solves a partial case of constrained quadratic optimization problem) The structure needs to be initialized and passed to the training method of CvSVM
ordered, the output variables can be either categorical (_params.svm_type=CvSVM::C_SVC or
_params.svm_type=CvSVM::NU_SVC) or ordered (_params.svm_type=CvSVM::EPS_SVR or
LIBSVM - A Library for Support Vector Machines. By Chih-Chung Chang and Chih-Jen Lin ([2])
CvSVM 支撑矢量机
class CvSVM : public CvStatModel //继承自基类 CvStatModel { public:
常值惩罚因子 C 被采用。 CvSVM::NU_SVR - 回归;nu 代替了 p kernel_type//核类型:
CvSVM::LINEAR - 没有任何向映射至高维空间,线性区分(或回归)在原始特征空间中被完 成,这是最快的选择。 d(x,y) = x?y == (x,y) CvSVM::POLY - 多项式核: d(x,y) = (gamma*(x?y)+coef0)degree CvSVM::RBF - 径向基,对于大多数情况都是一个较好的选择:d(x,y) = exp(-gamma*|x-y|2) CvSVM::SIGMOID - sigmoid 函数被用作核函数: d(x,y) = tanh(gamma*(x?y)+coef0) degree, gamma, coef0:都是核函数的参数,具体的参见上面的核函数的方程。
protected: ...
};
CvSVMParamsSVM 训练参数 struct
struct CvSVMParams {
CvSVMParams(); CvSVMParams( int _svm_type, int _kernel_type,
double _degree, double _gamma, double _coef0, double _C, double _nu, double _p, CvMat* _class_weights, CvTermCriteria _term_crit );
CvSVM::get_support_vector*得到支撑矢量和特殊矢量的数
int CvSVM::get_support_vector_count() const; const float* CvSVM::get_support_vector(int i) const;
这个方法可以被用来得到支撑矢量的集合。
支持向量机算法及其代码实现 支持向量机(SVM),起初由 vapnik 提出时,是作为寻求最优(在一定程度上)二分类器的 一种技术。後来它又被拓展到回归和聚类应用。SVM 是一种基于核函数的方法,它通过某 些核函数把特征向量映射到高维空间,然後建立一个线性判别函数(或者说是一个高维空间 中的能够区分训练数据的最优超平面,参考异或那个经典例子)。假如 SVM 没有明确定义核 函数,高维空间中任意两点距离就需要定义。
double
nu; // for CV_SVM_NU_SVC, CV_SVM_ONE_CLASS, and CV_SVM_NU_SVR
double
p; // for CV_SVM_EPS_SVR
CvMat*
class_weights; // for CV_SVM_C_SVC
CvTermCriteria term_crit; // termination criteria
解是最优的在某种意义上是两类中距离分割面最近的特征向量和分割面的距离最大化。离分 割面最近的特征向量被称为”支撑向量”,意即其它向量不影响分割面(决策函数)。
有很多关于 SVM 的参考文献,这是两篇较好的入门文献。
【 Burges98 】 C. Burges. "A tutorial on support vector machines for pattern recognition", Knowledge Discovery and Data Mining 2(2), 1998. (available online at [1]).
virtual void clear();
virtual void save( const char* filename, const char* name=0 ); virtual void load( const char* filename, const char* name=0 );
virtual void write( CvFileStorage* storage, const char* name ); virtual void read( CvFileStorage* storage, CvFileNode* node ); int get_var_count() const { return var_idx ? var_idx->cols : var_all; }
};
svm_type,SVM 的类型:
CvSVM::C_SVC - n(n>=2)分类器,允许用异常值惩罚因子 C 进行不完全分类。 CvSVM::NU_SVC - n 类似然不完全分类的分类器。参数 nu 取代了 c,其值在区间【0,1】中, nu 越大,决策边界越平滑。 CvSVM::ONE_CLASS - 单分类器,所有的训练数据提取自同一个类里,然後 SVM 建立了一个 分界线以分割该类在特征空间中所占区域和其它类在特征空间中所占区域。 CvSVM::EPS_SVR - 回归。 训练集中的特征向量和拟合出来的超平面的距离需要小于 p。异
int int double double double
svm_type; kernel_type; degree; // for poly gamma; // for poly/rbf/sigmoid coef0; // for poly/sigmoid
double
C; // for CV_SVM_C_SVC, CV_SVM_EPS_SVR and CV_SVM_NU_SVR
_params.svm_type=CvSVM::NU_SVR)
or
not
required
at
பைடு நூலகம்
all
(_params.svm_type=CvSVM::ONE_CLASS), missing measurements are not supported.
所有的参数都被集成在 CvSVMParams 这个结构中。
首先是 SVM 的训练,这部分我并没有整合到 VC 里,直接使用它提供的 python 程序,虽然 网格搜索这种简易搜索也可以自己写,但是识别时只需要训练生成的 SVMmodel 文件即可, 所以可以和主程序分离开。至于 python 在 windows 下的使用,还是要设置一下的,首先要 在系统环境变量 path 里把 python 的路径设进去,libsvm 画训练等高线图还需要 gnuplot 的 支持,打开 python 源程序(grid.py),把 gnuplot_exe 设置成你机器里的安装路径,这样才能 正确的运行程序。然後就是改步长和搜索范围,官方建议是先用大步长搜索,搜到最优值後 再用小步长在小范围内搜索(我觉得这有可能会陷入局部最优,不过近似出的结果还可以接 受)。我用的 python 版本是 2.4,gnuplot4.0。
virtual float predict( const CvMat* _sample ) const; virtual int get_support_vector_count() const; virtual const float* get_support_vector(int i) const;
The method trains SVM model. It follows the conventions of generic train "method" with the
following limitations: only CV_ROW_SAMPLE data layout is supported, the input variables are all
CvSVM::train 训练 SVM
bool CvSVM::train( const CvMat* _train_data, const CvMat* _responses, const CvMat* _var_idx=0, const CvMat* _sample_idx=0, CvSVMParams _params=CvSVMParams() );
补充:在 WindowsXP+OpenCVRC1 平台下整合 OpenCV 与 libSVM 虽然从 RC1 版开始 opencv 开始增设 ML 类,提供对常见的分类器和回归算法的支持。但是尚存在一些问题,比如说例 子少(官方许诺说很快会提供一批新例子,见 CVS 版)。单说 SVM 这种算法,它自己提供了 一套比较完备的函数,但是并不见得优于老牌的 libsvm(它也应该参考过 libsvm,至于是否 效率优于 libsvm,我并没有作过测试,官方也没有什么说法,但是 libsvm 持续开源更新,是 公认的现存的开源 SVM 库中最易上手,性能最好的库)。所以在你的程序里整合 opencv 和 libSVM 还是一种比较好的解决方案。在 VC 中整合有些小地方需要注意,这篇文档主要是提 供把图象作为 SVM 输入时程序遇到的这些小问题的解决方案。希望大家遇到问题时,多去 读 libSVM 的源码,它本身也是开源的,C 代码写得也很优秀,数据结构定义得也比较好。
// SVM type enum { C_SVC=100, NU_SVC=101, ONE_CLASS=102, EPS_SVR=103, NU_SVR=104 };//SVC 是 SVM 分类器,SVR 是 SVM 回归
// SVM kernel type enum { LINEAR=0, POLY=1, RBF=2, SIGMOID=3 }; //提供四种核函数,分别是线性,多项式, 径向基,sigmoid 型函数。
C, nu, p:在一般的 SVM 优化求解时的参数。
class_weights: Optional weights, assigned to particular classes. They are multiplied by C and thus affect the mis-classification penalty for different classes. The larger weight, the larger penalty on mis-classification of data from the certain class.
CvSVM(); virtual ~CvSVM();
CvSVM( const CvMat* _train_data, const CvMat* _responses, const CvMat* _var_idx=0, const CvMat* _sample_idx=0, CvSVMParams _params=CvSVMParams() );
term_crit: Termination procedure for iterative SVM training procedure (which solves a partial case of constrained quadratic optimization problem) The structure needs to be initialized and passed to the training method of CvSVM
ordered, the output variables can be either categorical (_params.svm_type=CvSVM::C_SVC or
_params.svm_type=CvSVM::NU_SVC) or ordered (_params.svm_type=CvSVM::EPS_SVR or
LIBSVM - A Library for Support Vector Machines. By Chih-Chung Chang and Chih-Jen Lin ([2])
CvSVM 支撑矢量机
class CvSVM : public CvStatModel //继承自基类 CvStatModel { public:
常值惩罚因子 C 被采用。 CvSVM::NU_SVR - 回归;nu 代替了 p kernel_type//核类型:
CvSVM::LINEAR - 没有任何向映射至高维空间,线性区分(或回归)在原始特征空间中被完 成,这是最快的选择。 d(x,y) = x?y == (x,y) CvSVM::POLY - 多项式核: d(x,y) = (gamma*(x?y)+coef0)degree CvSVM::RBF - 径向基,对于大多数情况都是一个较好的选择:d(x,y) = exp(-gamma*|x-y|2) CvSVM::SIGMOID - sigmoid 函数被用作核函数: d(x,y) = tanh(gamma*(x?y)+coef0) degree, gamma, coef0:都是核函数的参数,具体的参见上面的核函数的方程。
protected: ...
};
CvSVMParamsSVM 训练参数 struct
struct CvSVMParams {
CvSVMParams(); CvSVMParams( int _svm_type, int _kernel_type,
double _degree, double _gamma, double _coef0, double _C, double _nu, double _p, CvMat* _class_weights, CvTermCriteria _term_crit );
CvSVM::get_support_vector*得到支撑矢量和特殊矢量的数
int CvSVM::get_support_vector_count() const; const float* CvSVM::get_support_vector(int i) const;
这个方法可以被用来得到支撑矢量的集合。
支持向量机算法及其代码实现 支持向量机(SVM),起初由 vapnik 提出时,是作为寻求最优(在一定程度上)二分类器的 一种技术。後来它又被拓展到回归和聚类应用。SVM 是一种基于核函数的方法,它通过某 些核函数把特征向量映射到高维空间,然後建立一个线性判别函数(或者说是一个高维空间 中的能够区分训练数据的最优超平面,参考异或那个经典例子)。假如 SVM 没有明确定义核 函数,高维空间中任意两点距离就需要定义。