OpenCV——SVM学习(一)

1、SVM支持向量机的概念

SVM是一个分类器Support Vector Machines,定义为一个能够将不同类样本在样本空间分隔的超平面,即给定一些标记好的训练样本,SVM算法输出一个最优化的分隔超平面。

2、初步学习

2.1理解SVM
参考自
http://blog.csdn.net/c406495762/article/details/78072313
http://blog.csdn.net/chunxiao2008/article/details/50266025
这2个讲的很好
这里写出我看这个时觉得讲的比较好的一些重点。

  1. 给一个要求:你需要在下面的特征区别较明显的两个样本之间插入一根棍子,这个棍子可以把两个样本明显地分开。
    这里写图片描述
  2. 给一个更高的要求:在样本的数量变多以后,你这根棍子依然能够比较好的将两类样本分开,使分类变得可靠。
    这里写图片描述
    于是提出了SVM,这个SVM能使棍子离两个样本的距离达到最大,以保证在样本越来越多时分类也能比较可靠。
  3. 再给一个更高的要求,这些样本没有明显的规律可以区分了,你找不到一条棍子将这两类样本分开。那怎么办?“拍一掌(核函数),让样本飞起来,拿出一张纸(超平面)”,这样就能达到下面的效果。
    这里写图片描述

2.2线性可分和线性不可分的概念
当一个分类问题,数据是线性可分的,也就是用一根棍就可以将两种小球分开的时候,我们只要将棍的位置放在让小球距离棍的距离最大化的位置即可,寻找这个最大间隔的过程,就叫做最优化。但是,现实往往是很残酷的,一般的数据是线性不可分的,也就是找不到一个棍将两种小球很好的分类。这个时候,我们就需要像大侠一样,将小球拍起,用一张纸代替小棍将小球进行分类。想要让数据飞起,我们需要的东西就是核函数(kernel),用于切分小球的纸,就是超平面。

2.3线性SVM
作者从线性可分的二分类问题讲解了这个概念。
这里写图片描述 这里写图片描述
如图两个类别是线性可分的,而且可以将两个类别分开的直线不止一条。这里的直线叫做决策面,每个决策面对应一个线性分类器。虽然从分类结果上看,两个分类器的效果是相同的。但是他们的性能是有差距的。在它们的决策面不变的情况下,添加了一个橙色的样本。可以观察到,(1)分类器依然能实现正确分类,而(2)分类器则出现了分类错误,所以得到这么一个结论,说分类器(1)的性能优于分类器(2)。这就是SVM的思想。它的依据就是分类器B的分类间隔比分类器C的分类间隔大。这里涉及到第一个SVM独有的概念”分类间隔”。在保证决策面方向不变且不会出现错分样本的情况下移动决策面,会在原来的决策面两侧找到两个极限位置(越过该位置就会产生错分现象),如虚线所示。虚线的位置由决策面的方向和距离原决策面最近的几个样本的位置决定。而这两条平行虚线正中间的分界线就是在保持当前决策面方向不变的前提下的最优决策面。两条虚线之间的垂直距离就是这个最优决策面对应的分类间隔。显然每一个可能把数据集正确分开的方向都有一个最优决策面(有些方向无论如何移动决策面的位置也不可能将两类样本完全分开),而不同方向的最优决策面的分类间隔通常是不同的,那个具有“最大间隔”的决策面就是SVM要寻找的最优解。而这个真正的最优解对应的两侧虚线所穿过的样本点,就是SVM中的支持样本点,称为”支持向量”。

2.4线性可分的情况
分类函数为
这里写图片描述
这里的f(x)表达的就是超平面,f(x)大于0的点对应y=1的数据,f(x)小于0的点对应y=-1的数据。数据点离超平面越远,就越能够确信这个数据是属于哪一类的.
有两个支撑着中间的分界超平面的超平面,称为gap。它们到分界超平面的距离相等。这两个gap上必定会有一些数据点。如果没有,我们就可以进一步扩大margin了。这些经过gap的数据点,就是支持向量(Support Vector)(它们支持了中间的超平面)。很显然,只有支持向量才决定超平面,其他的数据点不影响超平面的确定。
这是一个十分优良的特性。假设有100万个数据点,支持向量100个,我们实际上只需要用这100个支持向量进行计算!!!这将大大提高存储和计算的性能。

3、代码学习

3.1代码1学习
这里给出两个样本[1,1,1]和[2,4,3],做二分类,标签为0和1
最后给出一个测试样本,判断它是属于哪一类。

#include <opencv2/opencv.hpp>
#include <iostream>
#include "math.h"

using namespace cv;
using namespace std;

int main(int argc, char** argv[])
{
   
	//训练需要用到的数据
	int labels[2] = {
    0, 1 };
	float trainingData[2][3] = {
    {
    1, 1, 1 }, {
    2, 4, 3 } };
	//转为Mat
	Mat trainingDataMat(2, 3, CV_32FC1, trainingData);
	Mat labelsMat(2, 1, CV_32SC1, labels);
	//训练的初始化
	Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
	svm->setType(cv::ml::SVM::C_SVC);
	svm->setKernel(cv::ml::SVM
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值