opencv进阶07-支持向量机cv2.ml.SVM_create()简介及示例

news2024/11/13 10:15:39

支持向量机(Support Vector Machine,SVM)是一种二分类模型,目标是寻找一个标准(称为超平面)对样本数据进行分割,分割的原则是确保分类最优化(类别之间的间隔最大)。当数据集较小时,使用支持向量机进行分类非常有效。支持向量机是最好的现成分类器之一,这里所谓的“现成”是指分类器不加修改即可直接使用。

在对原始数据分类的过程中,可能无法使用线性方法实现分割。支持向量机在分类时,把无法线性分割的数据映射到高维空间,然后在高维空间找到分类最优的线性分类器。

Python 提供了不同的实现支持向量机的库(例如 sk-learn 库、LIBSVM 库等),OpenCV 也提供了对支持向量机的支持,对于上述库,基本都可以直接使用,无须深入了解支持向量机的原理。

理论基础

  1. 分类
    某 IT 企业在 2017 年通过笔试、面试的形式招聘了一批员工。2018 年,企业针对这批员工在过去一年的实际表现进行了测评,将他们的实际表现分别确定为 A 级(优秀)和 B 级(良好)。这批员工的笔试成绩、面试成绩和等级如图 21-1 所示,图中横坐标是笔试成绩,纵坐标
    是面试成绩,位于右上角的圆点表示测评成绩是 A 级,位于左下角的小方块表示测评成绩是 B级。

在这里插入图片描述
当然,公司肯定希望招聘到的员工都是 A 类(表现为 A 级)的。关键是如何根据笔试和面试成绩确定哪些员工可能是未来的 A 类员工呢?或者说,如何根据笔试和面试成绩确保招聘的员工是潜在的优秀员工?偷懒的做法是将笔试和面试的成绩标准都定得较高,但这样做可能会漏掉某些优秀的员工。

所以,要合理地确定笔试和面试的成绩标准,确保能够准确高效地招到 A 类员工。例如,在图 21-2 中,分别使用直线对笔试和面试成绩进行了 3 种不同形式的划分,将成绩位于直线左下方的员工划分为 B 类,将成绩位于右上方的员工划分为 A 类。

在这里插入图片描述
2. 分类器

在图 21-2 中用于划分不同类别的直线,就是分类器。在构造分类器时,非常重要的一项工作就是找到最优分类器。

那么,图 21-2 中的三个分类器,哪一个更好呢?从直观上,我们可以发现图 21-2 中右上角的分类器和右下角的分类器都偏向了某一个分类(即与其中一个分类的间距更小),而左下角的分类器实现了“均分”。而左下角的分类器,尽量让两个分类离自己一样远,这样就为每个分类都预留了等量的扩展空间,即使有新的靠近边界的点进来,也能够按照位置划分到对应的分类内。

以上述划分为例,说明如何找到支持向量机:在已有数据中,找到离分类器最近的点,确保它们离分类器尽可能地远。这里,离分类器最近的点到分类器的距离称为间隔(margin)。我们希望间隔尽可能地大,这样分类器在处理数据时,就会更准确。

例如,在图 21-3 中,左下角分类器的间隔最大。离分类器最近的那些点叫作支持向量(support vector)。正是这些支持向量,决定了分类器所在的位置。

在这里插入图片描述

3. 将不可分变为可分
上例的数据非常简单,我们可以使用一条直线(线性分类器)轻易地对其进行划分。而现实中的大多数问题,往往是非常复杂的,不可能像上例一样简单地完成划分。

通常情况下,支持向量机会将不那么容易分类的数据通过函数映射变为可分类的。

举个例子,假设我们不小心将豌豆和小米混在了一起。豌豆的个头很大,直径在 10 mm 左右;小米个头小,直径在 1mm 左右。如果想把它们分开,直接使用直线是不行的。此时,我们可以使用直径为 3 mm 的筛子,将豌豆和小米区分开。在某种意义上,这个筛子就是映射操作,它将豌豆和小米有效地分开了。

支持向量机在处理数据时,如果在低维空间内无法完成分类,就会自动将数据映射到高维空间,使其变为(线性)可分的。简单地讲,就是对当前数据进行函数映射操作。

如图 21-4 所示,在分类时,通过函数 f 的映射,让左图中本来不能用线性分类器分类的数据变为右图中线性可分的数据。当然,在实际操作中,也可能将数据由低维空间向高维空间转换。

在这里插入图片描述
大家也许会担心,数据由低维空间转换到高维空间后运算量会呈几何级增加,但实际上,支持向量机能够通过核函数有效地降低计算复杂度。

4. 概念总结

尽管上面分析的是二维数据,但实际上支持向量机可以处理任何维度的数据。在不同的维度下,支持向量机都会尽可能寻找类似于二维空间中的直线的线性分类器。

例如,在二维空间,支持向量机会寻找一条能够划分当前数据的直线;在三维空间,支持向量机会寻找一个能够划分当前数据的平面(plane);在更高维的空间,支持向量机会尝试寻找一个能够划分当前数据的超平面(hyperplane)。

一般情况下,把能够可以被一条直线(更一般的情况,即一个超平面)分割的数据称为线性可分的数据,所以超平面是线性分类器
“支持向量机”是由“支持向量”和“机器”构成的。

  • “支持向量”是离分类器最近的那些点,这些点位于最大“间隔”上。通常情况下,分类仅依靠这些点完成,而与其他点无关。

  • “机器”指的是分类器。

综上所述,支持向量机是一种基于关键点的分类算法

SVM 案例介绍

在使用支持向量机模块时,需要先使用函数 cv2.ml.SVM_create()生成用于后续训练的空分类器模型。该函数的语法格式为:

svm = cv2.ml.SVM_create( )

获取了空分类器 svm 后,针对该模型使用 svm.train()函数对训练数据进行训练,其语法格式为:

训练结果= svm.train(训练数据,训练数据排列格式,训练数据的标签)

式中参数的含义如下:

  • 训练数据:表示原始数据,用来训练分类器。例如,前面讲的招聘的例子中,员工的笔试成绩、面试成绩都是原始的训练数据,可以用来训练支持向量机。
  • 训练数据排列格式:原始数据的排列形式
    有按行排列(cv2.ml.ROW_SAMPLE,每一条训练数据占一行)和按列排列(cv2.ml.COL_SAMPLE,每一条训练数据占一列)两种形式,根据数据的实际排列情况选择对应的参数即可。
  • 训练数据的标签:原始数据的标签。
  • 训练结果:训练结果的返回值。

例如,用于训练的数据为 data,其对应的标签为 label,每一条数据按行排列,对分类器模型 svm 进行训练,所使用的语句为:

返回值 = svm.train(data,cv2.ml.ROW_SAMPLE,label)

完成对分类器的训练后,使用 svm.predict()函数即可使用训练好的分类器模型对测试数据进行分类,其语法格式为:

(返回值,返回结果) = svm.predict(测试数据)

以上是支持向量机模块的基本使用方法。在实际使用中,可能会根据需要对其中的参数进行调整。OpenCV 支持对多个参数的自定义,例如:可以通过 setType()函数设置类别,通过setKernel()函数设置核类型,通过 setC()函数设置支持向量机的参数 C(惩罚系数,即对误差的宽容度,默认值为 0)。

示例:已知老员工的笔试成绩、面试成绩及对应的等级表现,根据新入职员工的笔试成绩、面试成绩预测其可能的表现。

根据题目要求,首先构造一组随机数,并将其划分为两类,然后使用 OpenCV 自带的支持向量机模块完成训练和分类工作,最后将运算结果显示出来。具体步骤如下。

  1. 生成模拟数据
    首先,模拟生成入职一年后表现为 A 级的员工入职时的笔试和面试成绩。构造 20 组笔试和面试成绩都分布在[95, 100)区间的数据对:
a = np.random.randint(95,100, (20, 2)).astype(np.float32)

上述模拟成绩,在一年后对应的工作表现为 A 级。
接下来,模拟生成入职一年后表现为 B 级的员工入职时的笔试和面试成绩。构造 20 组笔试和面试成绩都分布在[90, 95)区间的数据对:

b = np.random.randint(90,95, (20, 2)).astype(np.float32)

上述模拟成绩,在一年后对应的工作表现为 B 级。
最后,将两组数据合并,并使用 numpy.array 对其进行类型转换:

data = np.vstack((a,b))
data = np.array(data,dtype='float32')
  1. 构造分组标签
    首先,为对应表现为 A 级的分布在[95, 100)区间的数据,构造标签“0”:
aLabel=np.zeros((20,1))

接下来,为对应表现为 B 级的分布在[90, 95)区间的数据,构造标签“1”:

bLabel=np.ones((20,1))

最后,将上述标签合并,并使用 numpy.array 对其进行类型转换:

label = np.vstack((aLabel, bLabel))
label = np.array(label,dtype='int32')
  1. 训练
    用支持向量机模块对已知的数据和其对应的标签进行训练:
svm = cv2.ml.SVM_create()
result = svm.train(data,cv2.ml.ROW_SAMPLE,label)
  1. 分类
    生成两个随机的数据对(笔试成绩,面试成绩)用于测试。可以用随机数,也可以直接指定两个数字。
    这里,我们想观察一下笔试和面试成绩差别较大的数据如何分类。用如下语句生成成绩:
test = np.vstack([[98,90],[90,99]])
test = np.array(test,dtype='float32')

然后,使用函数 svm.predict()对随机成绩分类:

(p1,p2) = svm.predict(test)
  1. 显示分类结果
    将基础数据(训练数据)、用于测试的数据(测试数据)在图像上显示出来:
plt.scatter(a[:,0], a[:,1], 80, 'g', 'o')
plt.scatter(b[:,0], b[:,1], 80, 'b', 's')
plt.scatter(test[:,0], test[:,1], 80, 'r', '*')
plt.show()

将测试数据及预测分类结果显示出来:

print(test)
print(p2)

整体代码如下:

import cv2
import numpy as np
import matplotlib.pyplot as plt
# 第 1 步 准备数据
# 表现为 A 级的员工的笔试、面试成绩
a = np.random.randint(95,100, (20, 2)).astype(np.float32)
# 表现为 B 级的员工的笔试、面试成绩
b = np.random.randint(90,95, (20, 2)).astype(np.float32)
# 合并数据
data = np.vstack((a,b))
data = np.array(data,dtype='float32')
# 第 2 步 建立分组标签,0 代表 A 级,1 代表 B 级
#aLabel 对应着 a 的标签,为类型 0-等级 A
aLabel=np.zeros((20,1))
#bLabel 对应着 b 的标签,为类型 1-等级 B
bLabel=np.ones((20,1))
# 合并标签
label = np.vstack((aLabel, bLabel))
label = np.array(label,dtype='int32')
# 第 3 步 训练
# 用 ml 机器学习模块 SVM_create() 创建 svm
svm = cv2.ml.SVM_create()
# 属性设置,直接采用默认值即可
#svm.setType(cv2.ml.SVM_C_SVC) # svm type
#svm.setKernel(cv2.ml.SVM_LINEAR) # line
#svm.setC(0.01)
# 训练
result = svm.train(data,cv2.ml.ROW_SAMPLE,label)
# 第 4 步 预测
# 生成两个随机的笔试成绩和面试成绩数据对
test = np.vstack([[98,90],[90,99]])
test = np.array(test,dtype='float32')
# 预测
(p1,p2) = svm.predict(test)
# 第 5 步 观察结果
# 可视化
plt.scatter(a[:,0], a[:,1], 80, 'g', 'o')
plt.scatter(b[:,0], b[:,1], 80, 'b', 's')
plt.scatter(test[:,0], test[:,1], 80, 'r', '*')
plt.show()
# 打印原始测试数据 test,预测结果
print(test)
print(p2)

同时,程序会在控制台输出如下运行结果:

[[98. 90.]
[90. 99.]]
[[1.]
[1.]]

运行结果表明:

  • 笔试成绩为 98 分,面试成绩为 90 分,对应的分类为 1,即该员工一年后的测评可能为B 级(表现良好)。

  • 笔试成绩为 90 分,面试成绩为 99 分,对应的分类为 1,即该员工一年后的测评可能为B 级(表现良好)。

因为我们采用随机方式生成数据,所以每次运行时所生成的数据会有所不同,运行结果也就会有所差异。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/888579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

你信吗,40%的受访者表示ChatGPT会做出比自己更好的投资决策

注意:本信息仅供参考,发布该内容旨在传递更多信息的目的,并不意味着赞同其观点或证实其说法。 调查显示,很大一部分受访者认为人工智能可以比他们更好地选择股票。 对于许多人来说,人工智能仍处于相对初始阶段&#x…

Python程序设计——元组、集合和字典

可以使用元组存储一个固定的元素列表,使用集合存储和快速访问不重复的元素、使用字典存储键值对并使用这些关键字来快速访问元素。 一、元组 元组跟列表类似,但是元组中的元素是固定的;也就是说,一旦一个元组被创建,就无法对元组中的元素进行…

部署mysql到win10电脑上

中间出现了很多问题, 记录一下 我这边是去官网下载的 ,链接:https://dev.mysql.com/downloads/mysql/ 我这边选了不是最新版本的MySQL,因为第一次安装8.1.0版本的,死活运行不起来,直接卸载安重装了&#x…

Python web实战之Django的国际化和本地化详解

关键词:Django、Python、Web开发、国际化(i18n)、本地化(l10n) 今天我要和大家分享一下 Python Web 开发中的一个重要话题——Django 的国际化和本地化。 1. 国际化和本地化 你有没有想过如何让你的网站在全球范围内…

ssm蜀都天香酒楼网站设计与实现

ssm蜀都天香酒楼的网站设计与实现028 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘要 近年来,信息化管理行业的不断兴起,使得人们的日常生活越来越离不开计算机和互联网技术。首…

DAY06_SpringBoot—简介基础配置yaml多环境开发配置整合第三方技术

目录 一 SpringBoot简介1. 入门案例问题导入1.1 入门案例开发步骤1.2 基于SpringBoot官网创建项目1.3 SpringBoot项目快速启动 2. SpringBoot概述问题导入2.1 起步依赖2.2 辅助功能 二 基础配置1. 配置文件格式问题导入1.1 修改服务器端口1.2 自动提示功能消失解决方案1.3 Spri…

7. CSS(四)

目录 一、浮动 (一)传统网页布局的三种方式 (二)标准流(普通流/文档流) (三)为什么需要浮动? (四)什么是浮动 (五)浮…

【BASH】回顾与知识点梳理(三十二)

【BASH】回顾与知识点梳理 三十二 三十二. SELinux 初探32.1 什么是 SELinux当初设计的目标:避免资源的误用传统的文件权限与账号关系:自主式访问控制, DAC以政策规则订定特定进程读取特定文件:委任式访问控制, MAC 32.2 SELinux 的运作模式安…

[Go版]算法通关村第十二关青铜——不简单的字符串转换问题

目录 题目:转换成小写字母思路分析:大写字母ASCII码 32 小写字母ASCII码Go代码Go代码-优化: 大写字母ASCII码 | 32 小写字母ASCII码 题目:字符串转换整数(atoi)思路分析:去除首部空格 明确正负 读取数…

使用Java实现拼音模糊搜索功能(支持拼音、首字母、多音字、谐音字、汉字、阿拉伯数字)

&#x1f34e; 介绍 Java实现的简单的工具类支持(拼音, 多音字, 谐音字, 汉字, 阿拉伯数字) 对标阿里钉钉的上方搜索栏实现的 &#x1f349; 对应依赖 <!-- https://mvnrepository.com/artifact/com.github.open-android/pinyin4j --> <dependency><groupId&g…

视觉大模型综述

万字长文带你全面解读视觉大模型细数近期涌现的优秀视觉大模型工作https://mp.weixin.qq.com/s/jLQaguLejx9zXjZjaJWx-Q深入了解视觉语言模型 - 知乎人类学习本质上是多模态 (multi-modal) 的&#xff0c;因为联合利用多种感官有助于我们更好地理解和分析新信息。理所当然地&am…

uniapp 顶部头部样式

<u-navbartitle"商城":safeAreaInsetTop"true"><view slot"left"><image src"/static/logo.png" mode"" class"u-w-50 u-h-50"></image></view></u-navbar>

TIA博途_通过EXCEL快速给PLC程序段添加注释信息的方法示例

通过EXCEL快速给PLC程序段添加注释信息的方法示例 如下图所示,以OB1为例,正常情况下,我们可以在博途中直接输入各个程序段的注释信息, 但是如果程序段较多的话,逐个输入的话效率不高,此时可以参考下面这种通过EXCEL进行快速添加的方法。 如下图所示,选中某个OB或FC、FB块…

蓝牙资讯|2023年Q2蓝牙耳机市场报告发布,苹果依然占据第一

市场调查机构 Canalys 发布最新报告&#xff0c;2023 年第二季度全球个人智能音频设备&#xff08;包括 TWS, 无线头戴&#xff0c;无线颈挂&#xff09;下滑了 2%&#xff0c;出货量达到 9568 万部&#xff0c;基本追平去年同期。其中&#xff0c;真无线耳机&#xff08;TWS&a…

出现ffmpeg.dll丢失的修复方法分享,教你快速修复ffmpeg.dll文件

当你使用或尝试运行与FFmpeg相关的应用程序时&#xff0c;可能会遇到一个常见的问题&#xff0c;ffmpeg.dll文件丢失。这个动态链接库文件对于正常运行FFmpeg应用程序至关重要。在本文中&#xff0c;我们将详细探讨为什么会出现ffmpeg.dll丢失的情况&#xff0c;并提供一些修复…

互联网账号被封禁解决办法,以qq为例

百度搜索&#xff1a;互联网信息服务投诉平台 电脑端浏览器&#xff1a;打开 ts.isc.org.cn 推荐使用360极速浏览器 谷歌浏览器 提交完成后&#xff0c;将投诉码保存&#xff0c;可以在“查询评价”处用投诉码查询进度

什么是可视化编程?为什么它如此重要?

可视化编程&#xff0c;又叫可视化程序设计&#xff0c;一直以来就是备受讨论的“热门技术”。一方面&#xff0c;程序员抵触它&#xff0c;觉得它不如用代码开发。另一方面&#xff0c;对于产品经理等稍微懂点开发的业余人员&#xff0c;它确实能提供价值。所以&#xff0c;它…

第十课:Qt 字符编码和中文乱码相关问题

功能描述&#xff1a;最全的 Qt 字符编码相关知识以及中文乱码的原因与解决办法 一、字符编码种类 ASCII 码 美国人对信息交流的编码&#xff0c;包括 26 个字母&#xff08;大小写&#xff09;、数字和标点符号等&#xff0c;用一个字节&#xff08;8 位&#xff09;表示这些…

【Matter】基于Ubuntu 22.04搭建matter开发环境:chip-tool 配网之 matter-over-wifi

前言 主要是记录一下学习过程&#xff0c;梳理下思路&#xff0c;抛转~ 官方的开发环境&#xff0c;基于Linux版本&#xff0c;官方的环境是基于树莓派环境的&#xff0c;原理其实也比较明了&#xff0c;目的也比较明确&#xff0c;就是达到Linux 主机和wifi 路由在同一局域网…