【原文:http://www.cnblogs.com/justany/archive/2012/11/26/2788509.html】 目的 实际事物模型中,并非所有东西都是线性可分的。 需要寻找一种方法对线性不可分数据进行划分。 原理 ,我们推导出对于线性可分数据,最佳划分超平面应满足: 现在我们想引入
【原文:http://www.cnblogs.com/justany/archive/2012/11/26/2788509.html】
目的
- 实际事物模型中,并非所有东西都是线性可分的。
- 需要寻找一种方法对线性不可分数据进行划分。
原理
,我们推导出对于线性可分数据,最佳划分超平面应满足:
现在我们想引入一些东西,来表示那些被错分的数据点(比如噪点),对划分的影响。
如何来表示这些影响呢?
被错分的点,离自己应当存在的区域越远,就代表了,这个点“错”得越严重。
所以我们引入,为对应样本离同类区域的距离。
接下来的问题是,如何将这种错的程度,转换为和原模型相同的度量呢?
我们再引入一个常量C,表示和原模型度量的转换关系,用C对
进行加权和,来表征错分点对原模型的影响,这样我们得到新的最优化问题模型:
关于参数C的选择, 明显的取决于训练样本的分布情况。 尽管并不存在一个普遍的答案,但是记住下面几点规则还是有用的:
- C比较大时分类错误率较小,但是间隔也较小。 在这种情形下, 错分类对模型函数产生较大的影响,既然优化的目的是为了最小化这个模型函数,那么错分类的情形必然会受到抑制。
- C比较小时间隔较大,但是分类错误率也较大。 在这种情形下,模型函数中错分类之和这一项对优化过程的影响变小,优化过程将更加关注于寻找到一个能产生较大间隔的超平面。
说白了,C的大小表征了,错分数据对原模型的影响程度。于是C越大,优化时越关注错分问题。反之越关注能否产生一个较大间隔的超平面。
开始使用
#include <iostream><span> #include </span><opencv2><span> #include </span><opencv2><span> #include </span><opencv2> <span>#define</span> NTRAINING_SAMPLES 100 <span>//</span><span> 每类训练样本的数量</span> <span>#define</span> FRAC_LINEAR_SEP 0.9f <span>//</span><span> 线性可分部分的样本组成比例</span> <span>using</span> <span>namespace</span><span> cv; </span><span>using</span> <span>namespace</span><span> std; </span><span>int</span><span> main(){ </span><span>//</span><span> 用于显示的数据</span> <span>const</span> <span>int</span> WIDTH = <span>512</span>, HEIGHT = <span>512</span><span>; Mat I </span>=<span> Mat::zeros(HEIGHT, WIDTH, CV_8UC3); </span><span>/*</span><span> 1. 随即产生训练数据 </span><span>*/</span><span> Mat trainData(</span><span>2</span>*NTRAINING_SAMPLES, <span>2</span><span>, CV_32FC1); Mat labels (</span><span>2</span>*NTRAINING_SAMPLES, <span>1</span><span>, CV_32FC1); RNG rng(</span><span>100</span>); <span>//</span><span> 生成随即数 </span><span>//</span><span> 设置线性可分的训练数据</span> <span>int</span> nLinearSamples = (<span>int</span>) (FRAC_LINEAR_SEP *<span> NTRAINING_SAMPLES); </span><span>//</span><span> 生成分类1的随机点</span> Mat trainClass = trainData.rowRange(<span>0</span><span>, nLinearSamples); </span><span>//</span><span> 点的x坐标在[0, 0.4)之间</span> Mat c = trainClass.colRange(<span>0</span>, <span>1</span><span>); rng.fill(c, RNG::UNIFORM, Scalar(</span><span>1</span>), Scalar(<span>0.4</span> *<span> WIDTH)); </span><span>//</span><span> 点的y坐标在[0, 1)之间</span> c = trainClass.colRange(<span>1</span>,<span>2</span><span>); rng.fill(c, RNG::UNIFORM, Scalar(</span><span>1</span><span>), Scalar(HEIGHT)); </span><span>//</span><span> 生成分类2的随机点</span> trainClass = trainData.rowRange(<span>2</span>*NTRAINING_SAMPLES-nLinearSamples, <span>2</span>*<span>NTRAINING_SAMPLES); </span><span>//</span><span> 点的x坐标在[0.6, 1]之间</span> c = trainClass.colRange(<span>0</span> , <span>1</span><span>); rng.fill(c, RNG::UNIFORM, Scalar(</span><span>0.6</span>*<span>WIDTH), Scalar(WIDTH)); </span><span>//</span><span> 点的y坐标在[0, 1)之间</span> c = trainClass.colRange(<span>1</span>,<span>2</span><span>); rng.fill(c, RNG::UNIFORM, Scalar(</span><span>1</span><span>), Scalar(HEIGHT)); </span><span>/*</span><span> 设置非线性可分的训练数据 </span><span>*/</span> <span>//</span><span> 生成分类1和分类2的随机点</span> trainClass = trainData.rowRange( nLinearSamples, <span>2</span>*NTRAINING_SAMPLES-<span>nLinearSamples); </span><span>//</span><span> 点的x坐标在[0.4, 0.6)之间</span> c = trainClass.colRange(<span>0</span>,<span>1</span><span>); rng.fill(c, RNG::UNIFORM, Scalar(</span><span>0.4</span>*WIDTH), Scalar(<span>0.6</span>*<span>WIDTH)); </span><span>//</span><span> 点的y坐标在[0, 1)之间</span> c = trainClass.colRange(<span>1</span>,<span>2</span><span>); rng.fill(c, RNG::UNIFORM, Scalar(</span><span>1</span><span>), Scalar(HEIGHT)); </span><span>/*</span><span>*/</span><span> labels.rowRange( </span><span>0</span>, NTRAINING_SAMPLES).setTo(<span>1</span>); <span>//</span><span> Class 1</span> labels.rowRange(NTRAINING_SAMPLES, <span>2</span>*NTRAINING_SAMPLES).setTo(<span>2</span>); <span>//</span><span> Class 2</span> <span>/*</span><span> 设置支持向量机参数 </span><span>*/</span><span> CvSVMParams </span><span>params</span><span>; </span><span>params</span>.svm_type =<span> SVM::C_SVC; </span><span>params</span>.C = <span>0.1</span><span>; </span><span>params</span>.kernel_type =<span> SVM::LINEAR; </span><span>params</span>.term_crit = TermCriteria(CV_TERMCRIT_ITER, (<span>int</span>)1e7, 1e-<span>6</span><span>); </span><span>/*</span><span> 3. 训练支持向量机 </span><span>*/</span><span> cout </span>"<span>Starting training process</span><span>"</span> endl; CvSVM svm; svm.train(trainData, labels, Mat(), Mat(), <span>params</span><span>); cout </span>"<span>Finished training process</span><span>"</span> endl; <span>/*</span><span> 4. 显示划分区域 </span><span>*/</span><span> Vec3b green(</span><span>0</span>,<span>100</span>,<span>0</span>), blue (<span>100</span>,<span>0</span>,<span>0</span><span>); </span><span>for</span> (<span>int</span> i = <span>0</span>; i i) <span>for</span> (<span>int</span> j = <span>0</span>; j j){ Mat sampleMat = (Mat_float>(<span>1</span>,<span>2</span>) i, j); <span>float</span> response =<span> svm.predict(sampleMat); </span><span>if</span> (response == <span>1</span>) I.at<vec3b>(j, i) =<span> green; </span><span>else</span> <span>if</span> (response == <span>2</span>) I.at<vec3b>(j, i) =<span> blue; } </span><span>/*</span><span> 5. 显示训练数据 </span><span>*/</span> <span>int</span> thick = -<span>1</span><span>; </span><span>int</span> lineType = <span>8</span><span>; </span><span>float</span><span> px, py; </span><span>//</span><span> 分类1</span> <span>for</span> (<span>int</span> i = <span>0</span>; i i){ px = trainData.atfloat>(i,<span>0</span><span>); py </span>= trainData.atfloat>(i,<span>1</span><span>); circle(I, Point( (</span><span>int</span>) px, (<span>int</span>) py ), <span>3</span>, Scalar(<span>0</span>, <span>255</span>, <span>0</span><span>), thick, lineType); } </span><span>//</span><span> 分类2</span> <span>for</span> (<span>int</span> i = NTRAINING_SAMPLES; i 2*NTRAINING_SAMPLES; ++<span>i){ px </span>= trainData.atfloat>(i,<span>0</span><span>); py </span>= trainData.atfloat>(i,<span>1</span><span>); circle(I, Point( (</span><span>int</span>) px, (<span>int</span>) py ), <span>3</span>, Scalar(<span>255</span>, <span>0</span>, <span>0</span><span>), thick, lineType); } </span><span>/*</span><span> 6. 显示支持向量 */</span> thick = <span>2</span><span>; lineType </span>= <span>8</span><span>; </span><span>int</span> x =<span> svm.get_support_vector_count(); </span><span>for</span> (<span>int</span> i = <span>0</span>; i i) { <span>const</span> <span>float</span>* v =<span> svm.get_support_vector(i); circle( I, Point( (</span><span>int</span>) v[<span>0</span>], (<span>int</span>) v[<span>1</span>]), <span>6</span>, Scalar(<span>128</span>, <span>128</span>, <span>128</span><span>), thick, lineType); } imwrite(</span><span>"</span><span>result.png</span><span>"</span>, I); <span>//</span><span> 保存图片</span> imshow(<span>"</span><span>SVM线性不可分数据划分</span><span>"</span>, I); <span>//</span><span> 显示给用户</span> waitKey(<span>0</span><span>); }</span></vec3b></vec3b></opencv2></opencv2></opencv2></iostream>
设置SVM参数
这里的参数设置可以参考一下的API。
<span>CvSVMParams</span> <span>params</span><span>;</span> <span>params</span><span>.</span><span>svm_type</span> <span>=</span> <span>SVM</span><span>::</span><span>C_SVC</span><span>;</span> <span>params</span><span>.</span><span>C</span> <span>=</span> <span>0.1</span><span>;</span> <span>params</span><span>.</span><span>kernel_type</span> <span>=</span> <span>SVM</span><span>::</span><span>LINEAR</span><span>;</span> <span>params</span><span>.</span><span>term_crit</span> <span>=</span> <span>TermCriteria</span><span>(</span><span>CV_TERMCRIT_ITER</span><span>,</span> <span>(</span><span>int</span><span>)</span><span>1e7</span><span>,</span> <span>1e-6</span><span>);</span>
可以看到,这次使用的是C类支持向量分类机。其参数C的值为0.1。
结果
- 程序创建了一张图像,在其中显示了训练样本,其中一个类显示为浅绿色圆圈,另一个类显示为浅蓝色圆圈。
- 训练得到SVM,并将图像的每一个像素分类。 分类的结果将图像分为蓝绿两部分,中间线就是最优分割超平面。由于样本非线性可分, 自然就有一些被错分类的样本。 一些绿色点被划分到蓝色区域, 一些蓝色点被划分到绿色区域。
- 最后支持向量通过灰色边框加重显示。
被山寨的原文
Support Vector Machines for Non-Linearly Separable Data . OpenCV.org

PDF文件作为一种通用的文件格式,被广泛应用于各种应用场景,如电子书、报表、合同等等。在开发过程中,我们常常需要对PDF文件进行生成、编辑、读取等操作。而PHP作为一种脚本语言,也能够轻松地完成这些任务。本文将介绍使用PHP处理PDF文件的方法。一、生成PDF文件生成PDF文件有许多方法,其中最常见的是使用PDF库。PDF库是一种生成PDF文档的工具,它为

Python中的支持向量机(SupportVectorMachine,SVM)是一个强大的有监督学习算法,可以用来解决分类和回归问题。SVM在处理高维度数据和非线性问题的时候表现出色,被广泛地应用于数据挖掘、图像分类、文本分类、生物信息学等领域。在本文中,我们将介绍在Python中使用SVM进行分类的实例。我们将使用scikit-learn库中的SVM模

CakePHP是一个开源的Web应用程序框架,它基于PHP语言构建,可以简化Web应用程序的开发过程。在CakePHP中,处理文件上传是一个常见的需求,无论是上传头像、图片还是文档,都需要在程序中实现相应的功能。本文将介绍CakePHP中如何处理文件上传的方法和一些注意事项。在Controller中处理上传文件在CakePHP中,上传文件的处理通常在Cont

CakePHP是一个流行的PHP开发框架,它可以帮助开发者快速构建高质量的Web应用程序。随着全球化的发展,越来越多的应用需要支持多语言,CakePHP也提供了相应的支持。本文将介绍CakePHP如何处理多语言。一、多语言支持多语言支持是CakePHP的一项重要功能。从版本2.0开始,CakePHP支持gettext文件格式,该

随着现代Web应用不断发展,PHP作为其中最流行的编程语言之一,被广泛地应用于网站开发中。但在开发过程中,经常会遇到空值错误,而这些错误会导致应用程序抛出异常,进而影响用户的使用体验。因此,在PHP开发过程中,如何检测和处理空值错误,是程序员们需要掌握的重要技能。一、什么是空值错误在PHP开发过程中,空值错误通常指的是两种情况:变量未初始化和变

在进行JavaFX应用程序开发的过程中,我们常常会遇到JavaFX线程卡顿错误。这种错误的严重程度不同,可能会对程序的稳定性和性能产生不利的影响。为了保证程序的正常运行,我们需要了解JavaFX线程卡顿错误的原因和解决方法,以及如何预防这种错误的发生。一、JavaFX线程卡顿错误的原因JavaFX是一个多线程的UI应用程序框架,它允许程序在后台线程中执行长时

随着Excel文件在商业领域和日常生活中的不断普及和应用,我们经常需要使用PHP处理Excel文件,例如数据的导入导出,数据的筛选和排序等。因此,本文将介绍如何使用PHP进行Excel文件处理。安装PHPExcel库PHPExcel是一款强大的PHP操作Excel文件的开源库,其支持读取、写入Excel文件,并提供了许多便捷的操作方法。在使用之前需要先安装P

在企业级应用程序中,分布式系统已经成为一个常见的架构模型。分布式系统由多个处理单元(节点)组成,这些节点协同工作以完成复杂的任务。在分布式系统中,事务处理是一个必不可少的组件,因为它能够确保所有节点协同工作的结果一致性。本文将介绍如何构建基于SpringBoot的分布式事务处理。一、什么是分布式事务处理?在单节点系统中,事务处理通常是一个简单的过程。当应用


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

WebStorm Mac版
好用的JavaScript开发工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能