从基础开始讲起,没有这些东西看支持向量机真的很难!

1.拉格朗日乘子(Lagrangemultiplier)
    假设需要求极值的目标函数(objectivefunction)为f(x,y),限制条件为φ(x,y)=M
    设 
    定义一个新函数 
    则用偏导数方法列出方程: 、 、  求出x,y,λ的值,代入即可得到目标函数的极值。
    扩展为多个变量的式子为:
    F(x1,x2,...,xn,λ)=f(x1,x2,...,xn)-λg(x1,x2,...,xn)
    则求极值点的方程为:∂F/∂xi=0(xi即为x1,x2,...,xn等自变量)∂F/∂λ=g(x1,x2,...,xn)=0
2.凸二次规划
    
    

    二次规划的一般形式可以表示为,如右下图:
    其中G是Hessian矩阵,τ是有限指标集,c,x和{ai},都是R中的向量。如果Hessian矩阵是半正定的,则我们说(1.1)是一个凸二次规划,
    在这种情况下该问题的困难程度类似于线性规划如果=0,二次规划问题就变成线性规划问题了)。
    如果有至少一个向量满足约束并且在可行域有下界,则凸二次规划问题就有一个全局最小值。
    如果是正定的,则这类二次规划为严格的凸二次规划,那么全局最小值就是唯一的。如果是一个不定矩阵,则为非凸二次规划,
    这类二次规划更有挑战性,因为它们有多个平稳点和局部极小值点。

   

3.线性中的对偶

    线性规划有一个有趣的特性,就是任何一个求极大的问题都有一个与其匹配的求极小的线性规划问题。    例;原问题为     MAX X=8*Z1+10*Z2+2*Z3              s.t.  2*Z1+1*Z2+3*Z3  <=70                    4*Z1+2*Z2+2*Z3  <=80                    3*Z1+     1*Z3  <=15                    2*Z1+2*Z2       <=50                    Z1,Z2,Z3 〉=0    Z则其对偶问题为    MIN =70*Y1+80*Y2+15*Y3+50*Y4            s.t    2*y1+4*y2+3*y3+2*y4>=8                   1*y1+2*y2+       1*y4>=10                   3*y1+2*y2+1*y3      >=2                 y1,y2,y3,y3>=0

    可以看出:    1、若一个模型为目标求 极大 约束为 小于等于的不等式,则它的对偶模型为目标求极小 约束为极大的不等式    即 “MAX,〈=”  “与MIN,〉=”相对应     2、从约束条件系数矩阵来看,一个模型中为A 另一个为A的转质,一个模型是 m个约束n个变量 则他的对偶模型为n个约束 m个变量    3、从数据b c 的位置看 两个规划模型中b和 c的位置对换     即8、10、2 与 70、80、15、50 对换       4、两个规划模型中变量非负。

 4. 内积空间

      

 5.欧式空间

      

 6.线性空间、希尔伯特空间、巴拿赫空间

在数学中有许多空间表示,比如欧几里德空间、赋范空间、希尔伯特空间等。这些空间之间有什么关系呢?

首先要从距离的定义说起。 
什么是距离呢?实际上距离除了我们经常用到的直线距离外,还有向量距离如Σni=1xi⋅yi−−−−−−−−√, 函数距离如∫ba(f(x)−g(x))2dx、 曲面距离、折线距离等等,这些具体的距离与距离之间的关系类似于苹果、香蕉等与水果的关系,前面是具体的事物,后面是抽象的概念。距离就是一个抽象的概念,其定义为: 
设X是任一非空集,对X中任意两点x,y,有一实数d(x,y)与之对应且满足: 
1. d(x,y) ≥0,且d(x,y)=0当且仅当x=y; 
2. d(x,y)=d(y,x); 
3. d(x,y) ≤d(x,z)+d(z,y)。 
称d(x,y)为X中的一个距离。

定义了距离后,我们再加上线性结构,如向量的加法、数乘,使其满足加法的交换律、结合律、零元、负元;数乘的交换律、单位一;数乘与加法的结合律(两个)共八点要求,从而形成一个线性空间,这个线性空间就是向量空间。

在向量空间中,我们定义了范数的概念,表示某点到空间零点的距离: 
1. ||x|| ≥0; 
2. ||ax||=|a|||x||; 
3. ||x+y||≤||x||+||y||。

将范数与距离比较,可知,范数比距离多了一个条件2,数乘的运算,表明其是一个强化了的距离概念。范数与距离的关系可以类似理解为与红富士苹果与苹果的关系。

接下来对范数和距离进行扩展,形成如下: 
范数的集合⟶ 赋范空间+线性结构⟶线性赋范空间 
距离的集合⟶ 度量空间+线性结构⟶线性度量空间

下面在已经构成的线性赋范空间上继续扩展,添加内积运算,使空间中有角的概念,形成如下: 
线性赋范空间+内积运算⟶ 内积空间; 
这时的内积空间已经有了距离、长度、角度等,有限维的内积空间也就是我们熟悉的欧氏空间。

继续在内积空间上扩展,使得内积空间满足完备性,形成希尔伯特空间如下: 
内积空间+完备性⟶ 希尔伯特空间 
其中完备性的意思就是空间中的极限运算不能跑出该空间,如有理数空间中的2√ 的小数表示,其极限随着小数位数的增加收敛到2√,但2√ 属于无理数,并不在有理数空间,故不满足完备性。一个通俗的理解是把学校理解为一个空间,你从学校内的宿舍中开始一直往外走,当走不动停下来时(极限收敛),发现已经走出学校了(超出空间),不在学校范围内了(不完备了)。希尔伯特就相当于地球,无论你怎么走,都还在地球内(飞出太空除外)。

此外,前面提到的赋范空间,使其满足完备性,扩展形成巴拿赫空间如下: 
赋范空间+完备性⟶ 巴拿赫空间

以上均是在距离的概念上进行添加约束形成的,递增关系如下: 
距离⟶范数⟶内积 
向量空间+范数⟶ 赋范空间+线性结构⟶线性赋范空间+内积运算⟶内积空间+完备性⟶希尔伯特空间 
内积空间+有限维⟶欧几里德空间 
赋范空间+完备性⟶巴拿赫空间

顺便提以下,对距离进行弱化,保留距离的极限和连续概念,就形成拓扑的概念。


有了上面的基础知识,下面开始支持向量机的理论学习

注:已经有很多关于SVM的优秀文章,自认为我距离大牛很远而且表达的没他们好,所以接下来的分析是我觉得难懂的地方,或者自认为老师和前辈们感觉太简单没说到的地方。

1.开篇距离公式推导

          推导如下的公式:

                  

2.SMO算法(主体来自博客,下面会给出链接,自己更改的部分已经标注

    

假设我们选取了初始值满足了问题中的约束条件。接下来,我们固定,这样W就是的函数。并且满足条件:

由于 ,所以推到出:

由于都是已知固定值,因此为了方面,可将等式右边标记成实数值

异号时,也就是一个为1,一个为-1时,他们可以表示成一条直线:a1-a2=ζ,相当于x-y=c作图,斜率为1。如下图:

横轴是,纵轴是既要在矩形方框内,也要在直线上,因此

注:这里L、H表示a1给定之后a2的取值范围,从图中可以看到a2取值两种情况,其中{0,C-ζ}属于一条直线、{-ζ,C}属于一条直线,且后者在前者之上,那么:

a2的最小值从{0,-ζ}取最大的值,a2的最大值从{C-ζ,C}取最小的值,因为 ζ = a1 - a2,所以:

同理,当同号时,


opencv实现SVM

按照以前的性格肯定是用C++把SVM写出来,现在感觉没多大意思,因为很多算法都要自己去实现太难了而且没那么多时间,毕竟现在还用不到SVM,先用opencv自带的例子测试再说。

        本文用的opencv3.1实现的非线性分类,看了网上的基本都是2.4或者2.9,要么就是用的线性实现的,弄了很长世间才实现! 

    其实主要是讲解一些参数的意义和怎么调用:

SVM的类型:

 1 enum Types {
 2 /** C-Support Vector Classification. n-class classification (n \f$\geq\f$ 2), allows
 3 imperfect separation of classes with penalty multiplier C for outliers. */
 4 C_SVC=100, //C类支持向量分类机。 n类分组  (n≥2),允许用异常值惩罚因子C进行不完全分类。
 5 /** \f$\nu\f$-Support Vector Classification. n-class classification with possible
 6 imperfect separation. Parameter \f$\nu\f$ (in the range 0..1, the larger the value, the smoother
 7 the decision boundary) is used instead of C. */
 8 NU_SVC=101,// 类支持向量分类机。n类似然不完全分类的分类器。参数为取代C(其值在区间【0,1】中,nu越大,决策边界越平滑)。
 9 /** Distribution Estimation (One-class %SVM). All the training data are from
10 the same class, %SVM builds a boundary that separates the class from the rest of the feature
11 space. */
12 ONE_CLASS=102,//单分类器,所有的训练数据提取自同一个类里,然后SVM建立了一个分界线以分割该类在特征空间中所占区域和其它类在特征空间中所占区域。
13 /** \f$\epsilon\f$-Support Vector Regression. The distance between feature vectors
14 from the training set and the fitting hyper-plane must be less than p. For outliers the
15 penalty multiplier C is used. */
16 EPS_SVR=103,//类支持向量回归机。 代替了 p。
17 /** \f$\nu\f$-Support Vector Regression. \f$\nu\f$ is used instead of p.
18 See @cite LibSVM for details. */
19 NU_SVR=104
20 };

核函数:

 1 enum KernelTypes {
 2         /** Returned by SVM::getKernelType in case when custom kernel has been set */
 3         CUSTOM=-1,
 4         /** Linear kernel. No mapping is done, linear discrimination (or regression) is
 5         done in the original feature space. It is the fastest option. \f$K(x_i, x_j) = x_i^T x_j\f$. */
 6         LINEAR=0,//线性核函数
 7         /** Polynomial kernel:
 8         \f$K(x_i, x_j) = (\gamma x_i^T x_j + coef0)^{degree}, \gamma > 0\f$. */
 9         POLY=1,//多项式函数(r*u'v + coef0)^degree
10         /** Radial basis function (RBF), a good choice in most cases.
11         \f$K(x_i, x_j) = e^{-\gamma ||x_i - x_j||^2}, \gamma > 0\f$. */
12         RBF=2,//exp(-gamma|u-v|^2)基于径向的函数,对于大多数情况都是一个较好的选择:
13         /** Sigmoid kernel: \f$K(x_i, x_j) = \tanh(\gamma x_i^T x_j + coef0)\f$. */
14         SIGMOID=3,//tanh(r*u'v + coef0)
15         /** Exponential Chi2 kernel, similar to the RBF kernel:
16         \f$K(x_i, x_j) = e^{-\gamma \chi^2(x_i,x_j)}, \chi^2(x_i,x_j) = (x_i-x_j)^2/(x_i+x_j), \gamma > 0\f$. */
17         CHI2=4,
18         /** Histogram intersection kernel. A fast kernel. \f$K(x_i, x_j) = min(x_i,x_j)\f$. */
19         INTER=5
20     };

核函数的参数:

成员变量degree针对多项式核函数degree的设置,

gamma针对多项式/rbf/sigmoid核函数的设置,

coef0针对多项式/sigmoid核函数的设置,

Cvalue为损失函数,在C-SVC、e-SVR、v-SVR中有效,

nu设置v-SVC、一类SVM和v-SVR参数,

p为设置e-SVR中损失函数的值,

class_weightsC_SVC的权重,

一些函数的参数:

1  TermCriteria::TermCriteria(int _type, int _maxCount, double _epsilon)
2     : type(_type), maxCount(_maxCount), epsilon(_epsilon) {}
3     //_type:迭代结束的类型,如果为CV_TERMCRIT_ITER,则用最大迭代次数作为终止条件,如果为CV_TERMCRIT_EPS 则用精度作为迭代条件,如果为CV_TERMCRIT_ITER+CV_TERMCRIT_EPS则用最大迭代次数或者精度作为迭代条件,看哪个条件先满足。
4     //_maxCount:终止程序的最大迭代次数
5     //_epsilon:终止程序的精度

1     train( InputArray samples, int layout, InputArray responses );
2     //samples:输入数据
3     //layout: 读取数据方式
4                     //----ROW_SAMPLE = 0, //!< 一行为一个样本
5                     //----COL_SAMPLE = 1  //!< 一列为一个样本
6     //responses:返回的数据(默认为不返回)

上代码:

  1 #include <opencv2/opencv.hpp>
  2 #include <iostream>
  3 #include "math.h"
  4
  5 using namespace cv;
  6 using namespace std;
  7 int test = 0;
  8 RNG rng(99999);
  9 void drawCross(Mat &img, Point center, Scalar color)
 10 {
 11     int col = center.x > 2 ? center.x : 2;
 12     int row = center.y> 2 ? center.y : 2;
 13     line(img, Point(col - 2, row - 2), Point(col + 2, row + 2), color);
 14     line(img, Point(col + 2, row - 2), Point(col - 2, row + 2), color);
 15 }
 16
 17 void newSvmTest(int rows, int cols, int testCount)
 18 {
 19     assert(testCount >= rows * cols);
 20
 21     Mat img = Mat::zeros(rows, cols, CV_8UC3);
 22     Mat testPoint = Mat::zeros(rows, cols, CV_8UC1);
 23     Mat data = Mat::zeros(testCount, 2, CV_32FC1);
 24     Mat res = Mat::zeros(testCount, 1, CV_32SC1);
 25
 26     //Create random test points
 27     for (int i = 0; i < testCount; i++)
 28     {
 29         int row = rng.uniform(0,255) % rows;
 30         int col = rng.uniform(0,255) % cols;
 31         //-----存储数据
 32         if (testPoint.at<unsigned char>(row, col) == 0)
 33         {
 34             testPoint.at<unsigned char>(row, col) = 1;
 35             data.at<float>(i, 0) = float(col) / cols;
 36             data.at<float>(i, 1) = float(row) / rows;
 37         }
 38         else//防止重复
 39         {
 40             i--;
 41             continue;
 42         }
 43         //分成三类
 44         if (row > (50 * cos(col * CV_PI / 100) + 200))
 45         {
 46             drawCross(img, Point(col, row), CV_RGB(255, 0, 0));
 47             res.at<unsigned int>(i, 0) = 1;
 48         }
 49         else
 50         {
 51             if (col > 200)
 52             {
 53                 drawCross(img, Point(col, row), CV_RGB(0, 255, 0));
 54                 res.at<unsigned int>(i, 0) = 2;
 55             }
 56             else
 57             {
 58                 drawCross(img, Point(col, row), CV_RGB(0, 0, 255));
 59                 res.at<unsigned int>(i, 0) = 3;
 60             }
 61         }
 62
 63     }
 64     Mat show = img.clone();
 65     //----SVM训练
 66     cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
 67     svm->setType(cv::ml::SVM::Types::C_SVC);
 68     svm->setKernel(cv::ml::SVM::KernelTypes::RBF);
 69     svm->setDegree(3);
 70     svm->setGamma(3);
 71     svm->setCoef0(1.0);
 72     svm->setC(10);
 73     svm->setNu(0);
 74     svm->setP(0.1);
 75     svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::EPS, 1000, FLT_EPSILON));
 76     // train operation
 77     svm->train(data, cv::ml::SampleTypes::ROW_SAMPLE, res);
 78     //----预测数据
 79     for (int i = 0; i< rows; i++)
 80     {
 81         for (int j = 0; j< cols; j++)
 82         {
 83             Mat m = Mat::zeros(1, 2, CV_32FC1);
 84             m.at<float>(0, 0) = float(j) / cols;
 85             m.at<float>(0, 1) = float(i) / rows;
 86
 87             float ret = 0.0;
 88             ret = svm->predict(m);
 89             Scalar rcolor;
 90
 91             switch ((int)ret)
 92             {
 93             case 1: rcolor = Scalar(100, 0, 0); break;
 94             case 2: rcolor = Scalar(0, 100, 0); break;
 95             case 3: rcolor = Scalar(0, 0, 100); break;
 96             }
 97
 98             line(img, Point(j, i), Point(j, i), rcolor);
 99         }
100     }
101     //-------获得支持向量
102     int thickness = 2;
103     int lineType = 8;
104     //Mat sv = svm->getUncompressedSupportVectors();//不能使用,不知道什么原因,网上有的人可以使用
105     Mat sv = svm->getSupportVectors();
106     for (int i = 0; i < sv.rows; ++i)
107     {
108         const float* v = sv.ptr<float>(i);
109         circle(img, Point((int)(v[0]*600), (int)(v[1]*400)), 4, Scalar(255, 255, 255), thickness, lineType);
110     }
111
112     imshow("dst", img);
113     waitKey(0);
114 }
115
116 int main(int argc,char** argv[])
117 {
118     newSvmTest(400, 600, 500);
119     return 0;
120 }

原图

SVM预测

支持向量数据

参考:  百度文库(具体不标注了,都是公式和概念)

《机器学习》周志华老师

    https://wenku.baidu.com/view/8f48d70e581b6bd97f19eaaf.html(内积空间)

    https://wenku.baidu.com/view/8bee6e76b0717fd5360cdced.html(欧式空间)  

      http://open.163.com/movie/2013/3/T/0/M8PTB0GHI_M8PTBUHT0.html(网易公开课讲函数空间,讲的非常好!)

    http://blog.csdn.net/shijing_0214/article/details/51052208(这篇博客是对上面视频的总结,本来想自己总结的,感觉这篇博文总结的很好,所以自己偷懒不写了)

    http://blog.csdn.net/v_july_v/article/details/7624837(看了SMO感觉不错)

    http://blog.csdn.net/v_july_v/article/details/7624837(July不用说的大牛,写的非常详细,配合上面的资料就更容易理解)

    http://www.pami.sjtu.edu.cn/people/gpliu/document/libsvm_src.pdf(代码解释,还没看)

     http://blog.csdn.net/zhazhiqiang/article/details/20146243(很全的opencv实现SVM)

    http://blog.csdn.net/firefight/article/details/6400060(程序核心是参考这篇文章,此博客opencv版本太低,很多不适合)

    http://blog.csdn.net/changyuanchn/article/details/7540014(opencv SVM参数在这篇文章)

转载于:https://www.cnblogs.com/wjy-lulu/p/6979436.html

支持向量机(理论+opencv实现)相关推荐

  1. K-means算法(理论+opencv实现)

    写在前面:之前想分类图像的时候有看过k-means算法,当时一知半解的去使用,不懂原理不懂使用规则...显然最后失败了,然后看了<机器学习>这本书对k-means算法有了理论的认识,现在通 ...

  2. 支持向量机的基本思想_支持向量机理论详细推导

    支持向量机是一种二分类分类模型,基本模型是定义在特征空间上的间隔最大的线性分类器,由简单到复杂可分为: 线性可分支持向量机:适用于训练数据线性可分的情况,通过硬间隔最大化学习一个线性分类器,又称为硬间 ...

  3. 支持向量机理论(SVM)

    CS229 Lecture notes 支持向量机(Support Vector Machines) 本章的讲义主要讲述的是 支持向量机( Support Vector Machine ,缩写为 SV ...

  4. 影像组学视频学习笔记(11)-支持向量机(SVM)(理论)、Li‘s have a solution and plan.

    本笔记来源于B站Up主: 有Li 的影像组学系列教学视频 本节(11)主要介绍: SVM支持向量机(理论) 支持向量机 (support vector machine, SVM) 号称是鲁棒性(rob ...

  5. OpenCV车牌/数字识别

    opencv 数字识别 附完整代码 Opencv的应用之车牌识别       用的支持向量机 使用opencv进行数字识别       对学习还是有点帮助的 Tensorflow 实现 MNIST 手 ...

  6. 支持向量机SVM 参数选择

    http://ju.outofmemory.cn/entry/119152 http://www.cnblogs.com/zhizhan/p/4412343.html 支持向量机SVM是从线性可分情况 ...

  7. SVM(支持向量机)综述

    第一部分   引言 基于数据的机器学习是现代智能技术中的重要方面, 研究从观测数据(样本) 出发寻找规律, 利用这些规律对未来数据或无法观测的数据进行预测. 包括模式识别.神经网络等在内, 现有机器学 ...

  8. OpenCV级联分类器Cascade Classifier

    OpenCV级联分类器Cascade Classifier 级联分类器Cascade Classifier 目标 理论 OpenCV中的Haar级联检测 结果 级联分类器Cascade Classif ...

  9. 支持向量机SVM(Support Vector Machines)介绍

    支持向量机SVM是从线性可分情况下的最优分类面提出的.所谓最优分类,就是要求分类线不但能够将两类无错误的分开,而且两类之间的分类间隔最大,前者是保证经验风险最小(为0),而通过后面的讨论我们看到,使分 ...

最新文章

  1. ntoskrnl损坏
  2. 成为顶尖机器学习算法专家需要知道哪些算法?
  3. 【UWB】公式推导计算坐标值
  4. pytorch查看当前学习率
  5. 【README1】动态规划之解题思路
  6. 采用curl库在PHP程序之间传递数组
  7. CentOS7中MongoDB备份与恢复,配置远程访问
  8. Linux学习笔记014---文件及文件夹权限设置_以及文件、文件夹的删除_移动_复制操作
  9. 圣诞好礼之Grid视频
  10. python基础算法面试_【归纳】面试中常见的python基础知识
  11. 洛谷P3649 [APIO2014]回文串(回文自动机)
  12. Numpy安装、升级与卸载
  13. ueditor编辑器的坑(视频空白/保存无数据/无法删除/不能插入百度动态地图/有序列表显示问题)
  14. python单位根检验看结果_python做adf检验
  15. LAME 使用/参数说明, 很好的程序
  16. Java实现 LeetCode 383 赎金信
  17. elasticsearch启动常见错误
  18. 英特尔固态硬盘测试软件,AS SSD测试:IOPS值高达11万_Intel 520_固态硬盘评测-中关村在线...
  19. Java并发编程的艺术笔记-Java内存模型
  20. 12v电量显示制作方法_由分立器件设计的汽车12V电池电量指示器(上) | 电子懒人的基础硬件电路图讲解...

热门文章

  1. js --- for in 和 for of
  2. 黑暗城堡 最短路径生成树
  3. 磁盘分析工具Ncdu的简单使用和体验
  4. 基于虚拟账号的邮件系统
  5. 区块链技术指2.1 区块链技术
  6. OJ题目-使用+-|等符号表示数字,进行运算【C语言】
  7. System.arraycopy 和Arrays.copyOf
  8. javascript Date 格式化
  9. 各种语言下 static 详解
  10. 使用java.util.zip对字符串进行压缩和解压缩