支持向量机

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

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

理论基础

又来了。。简单介绍一下基本原理

  1. 分类
    企业通过笔试,面使的形式招聘员工,分为A级,B级,图中横坐标是笔试成绩,纵坐标是面试成绩,右上角的圆点表示A 级,左下角的就是B级。

    公司希望找收到的都是A 类,关键是如果根据两个成绩确定哪个员工可能是未来的A类员工。虽然可以将成绩标准定的很高,但这样会失去一些优秀员工。所以合理指定成绩标准是很重要的
  2. 分类器

再上图中,用于划分不同类别的直线就是分类器。构造分类器时,找到最优分类器就非常重要。

上图中,右上和右下的分类器都偏向了某一个分类,左下的分类器实现了均分,左下的分类器尽量让两个分类离自己一样远,这样就为每个分类都预留了等量的扩展空间,即使有新的靠近边界的点进来,也可以按照位置划分到对应的分类内。

在已有数据中,找到离分类器最近的点,确保他们离分类器尽可能的远。 这里,离分类器最近的点到分类器的距离称为间隔,我们希望间隔尽可能的大,这样分类器在处理数据时,就会更加准确**。离分类器最近的哪些点就叫支持向量**,这些支持向量决定了分类器所在的位置。

  1. 将不可分变为可分
    上例是非常简单的,用一条直线(线性分类器)就可以完成划分,现实中大多数问题就更加复杂,支持向量机会将不那么容易分类的数据通过函数映射变为可分类的。

例如:豌豆和小米混起来,如果分开他们直线肯定就不行,可以使用直径合适的筛子。这个筛子就是映射操作,可以将豌豆小米有效的分离。支持向量机处理数据时,如果在低纬空间内无法完成分类,就会自动将数据映射到高维空间,使之变成线性可分的。简单来说就是对当前数据进行函数映射操作。


支持向量机可以通过核函数有效降低计算复杂度。

  1. 总结
    实际上支持向量机可以处理任何维度的数据,在不同维度下,支持向量机都会尽可能寻找类似于二维空间中的直线的线性分类器。例如三维中就会寻找一个可以划分数据的平面,更高维中,就寻找一个可以划分当前数据的超平面。一般来说,把可以被一条直线(或者超平面)分割的数据称为线性可分的数据,所以超平面是线性分类器。

支持向量机是由支持向量和机器构成:

  • 支持向量就是离分类器最近的那些点,这些点位于最大间隔上,分类仅依靠这些点,与其他点无关
  • 机器 就是分类器。。

支持向量机 就是一种基于关键点的分类算法。。

SVM 案例介绍

使用支持向量机模块时,需要先使用 svm = cv2.ml.SVM_create() 生成后续训练的空分类器。获取空训练器后,针对该模型使用 训练结果= svm.train(训练数据,训练数据排列格式,训练数据的标签) 对训练数据进行训练。

  • 训练数据:表示原始数据,用来训练分类器。
  • 排列格式,原始数据的排列形式按行排序(cv2.ml.ROW_SAMPLE,每一条训练数据占一行) ,按列排序(cv2.,ml.COL_SAMPLE,每一条数据占一列)两种形式,根据实际选择
  • 训练数据的标签,原始数据的标签
  • 训练结果

完成分类的训练后,使用 svm.predict() 函数即可完成训练好的分类器模型对测试数据进行分类(返回值,返回结果) = svm.predict(测试数据)

这就是基本使用方法,当然实际中还需要对其中的参数进行调整。例如:可以通过 setType()函数设置类别,通过setKernel()函数设置核类型,通过 setC()函数设置支持向量机的参数 C(惩罚系数,即对误差的宽容度,默认值为 0)。

举个栗子

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.]]


可看到,测试的两个都是 B 类。

K 均值聚类

预测一个离散值时,做的工作就是分类。当我们要预测一个连续值时,做的工作就是回归。

机器学习模型还可以将训练集中的数据划分为若干个组,每个组称为一个簇。这些自动形成的簇,可能对应不同的潜在概念,例如,运动员面子可以划分为篮球苗子,长跑苗子等。这种学习方式就是 聚类。特点就是学习过程中不需要用标签对训练样本进行标注。也就是说,学习过程可以根据现有训练集自动完成分类。

根据训练数据是否有标签,将机器学习划分为监督学习和无监督学习。前面的K 近邻,支持向量机都是监督学习,提供有标签的数据给算法学习,然后对数据分类,而聚类是无监督学习,不知道分类标签,直接对数据分类。

例如,100个豆子,已知其中40个绿豆,40个大豆,将剩下的20个分类就是监督学习,如果我们仅知道这些豆子由两个品种,但不知道具体是什么品种,此时可以根据豆子的大小,颜色属性,或根据两者组合属性,将其划分为两个类型,这个过程中没有使用已知标签,也同样完成了分类,这时的分类就是一种无监督学习。

理论基础

分豆子

6粒豆子混在一起,不知道豆子类别,按照大小分为两类。测得这些豆子直径大小,1,2,3,10,20,30.标记为 A ,B ,C, D, E, F, 进行分类操作。

  1. 随机选择两个参考豆子,例如选取 A, B 作为分类参考豆子
  2. 计算每粒豆子的直径与 A 和 B 的距离。距离哪个豆子近就将新豆子划分在哪个豆子所在的组。不用想第一组只有A ,剩下五个都是B 。
  3. 分别计算第一组豆子和第二组豆子的直径平均值,然后将各个豆子按照与直径平均值的距离大小分组。第一组平均值 AV1 = 1 ,第二组 AV2= (2+3+10+20+30)/5= 13

    划分为 AV1 组,豆子 A ,B ,C . AV2 组,豆子 D,E,F 。
  4. 重复第三步,知道分组稳定不在变化,即可确定分组完成。

经过一次后还是这个结果,我们就认为分组完成,将直径小的一组称为小豆子,另一组称为大豆子。实际处理中可能需要进行多轮的迭代才能实现数据的收敛,分类不在变化。

K 均值聚类的基本步骤

K均值聚类是一种将数据划分为 k 个簇的简单的聚类算法,该算法不断提取当前分类的中心点,并最终在分类稳定时完成聚类。本质来看就是一种迭代算法。

  1. 随机选取k 个点作为分类的中心点。也可以随机生成 K 个并不存在于原始数据中的数据点作为分类中心点。
  2. 将每个数据点放到离他们最近的中心点所在的类中,
  3. 重新计算各个分类的数据点的平均值,将该平均值作为新的分类中心点。
  4. 重复步骤2,3 知道分类稳定。

K 均值聚类模块

retval, bestLabels, centers=cv2.kmeans(data, K, bestLabels, criteria, attempts, flags)

  • data 输入的待处理数据集合,应该是 np.float32 类型,每个特征放在单独的一列中。
  • K 分出的簇的个数,就是分类的个数,一般就是 K =2 表示二分类。
  • bestLabels 表示计算后各个数据点最终分类标签(索引),实际调用时,设置为None。
  • criteria 算法迭代的终止条件。当达到最大循环数目或者指定的精度阈值时,算法停止继续分类迭代计算。这个参数由三个子参数构成:type, max_iter , eps。type 终止类型,有三种情况。cv2.TERM_CRITERIA_EPS:精度满足 eps 时,停止迭代。。cv2.TERM_CRITERIA_MAX_ITER:迭代次数超过阈值 max_iter 时,停止迭代。。cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER:上述两个条件中的任意一个满足时,停止迭代。
  • max_iter 最大迭代次数
  • eps 精确的阈值
  • attempts 让算法使用不同的初始值进行 attempts 次尝试
  • flags 表示选择初始中心点的方法,cv2.KMEANS_RANDOM_CENTERS:随机选取中心点。cv2.KMEANS_PP_CENTERS:基于中心化算法选取中心点。cv2.KMEANS_USE_INITIAL_LABELS:使用用户输入的数据作为第一次分类中心点;如果算法需要尝试多次(attempts 值大于 1 时),后续尝试都是使用随机值或者半随机值作为第一次分类中心点。
  • retval 返回的距离值(也称为密度值或紧密度),返回各个点到相应中心距离的平方和。
  • bestLabels 各个数据点额最终分类标签(索引)
  • centers,每个分类的中心点数据。

示例

# 随机生成两组数组
# 生成 60 个值在[0,50]内的 xiaoMI 直径数据
xiaoMI = np.random.randint(0,50,60)
# 生成 60 个值在[200,250]内的 daMI 直径数据
daMI = np.random.randint(200,250,60)
# 将 xiaoMI 和 daMI 组合为 MI
MI = np.hstack((xiaoMI,daMI))         # 转换为一列
# 使用 reshape 函数将其转换为(120,1)
MI = MI.reshape((120,1))
# 将 MI 转换为 float32 类型
MI = np.float32(MI)
# 调用 kmeans 模块
# 设置参数 criteria 的值,type, max_iter , eps
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.)
# 设置参数 flags 的值
flags = cv2.KMEANS_RANDOM_CENTERS    # 随机选取中心点
# 调用函数 kmeans
retval,bestLabels,centers = cv2.kmeans(MI,2,None,criteria,10,flags)# # 打印返回值
# print(retval)
# print(bestLabels)
# print(centers)# 获取分类结果
XM = MI[bestLabels==0]
DM = MI[bestLabels==1]
# 绘制分类结果
# 绘制原始数据
plt.plot(XM,'ro')                      # 用不同的颜色表示分类
plt.plot(DM,'bo')
# 绘制中心点,中心点是随机的,并且并不是原数据中的点,毕竟经过多次平均怎么可能还是源数据中的。
plt.plot(centers[0],'gx')
plt.plot(centers[1],'gx')
plt.show()

# 读取待处理图像
img = cv2.imread('5.jpg')
# 使用 reshape 将一个像素点的 RGB 值作为一个单元处理,,感觉就是将三个当作一个了,
data = img.reshape((-1,3))
# 转换为 kmeans 可以处理的类型
data = np.float32(data)
# 调用 kmeans 模块
print(data.shape)     # (353500, 3)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 2            # 决定了展示的灰度级
ret,label,center=cv2.kmeans(data,K,None,criteria,10,cv2.KMEANS_RANDOM_CENTERS)
# 转换为 uint8 数据类型,将每个像素点都赋值为当前分类的中心点像素值
# 将 center 的值转换为 uint8
center = np.uint8(center)
# 使用 center 内的值替换原像素点的值
res1 = center[label.flatten()]        # 这个索引,,试试center[[0,0]] 就知道了。。
# 使用 reshape 调整替换后的图像
res2 = res1.reshape((img.shape))
# 显示处理结果
cv2.imshow('img',img)
cv2.imshow('res2',res2)
cv2.waitKey(0)
cv2.destroyAllWindows()

opencv入门:支持向量机,K均值聚类相关推荐

  1. Python,OpenCV中的K均值聚类——K-Means Cluster

    Python,OpenCV中的K均值聚类 1. 效果图 2. 原理 2.1 什么是K均值聚类? 2.2 K均值聚类过程 2.3 cv2.kmeans(z, 2, None, criteria, 10, ...

  2. OpenCV学习笔记(十七)——K均值聚类

    当我们要预测的是一个离散值时,做的工作就是"分类".机器学习模型还可以将训练集中的数据划分为若干个组,每个组被称为一个"簇(cluster)".它的重要特点是在 ...

  3. Python OpenCV应用K均值聚类进行颜色量化

    Python OpenCV应用K均值聚类进行颜色量化 1. 效果图 2. 颜色量化是什么? 3. MiniBatchKMeans & KMeans 4. 源码 参考 在这篇博客文章中,我将向您 ...

  4. OpenCV k均值聚类kmeans clustering的实例(附完整代码)

    OpenCV k均值聚类kmeans clustering的实例 OpenCV k均值聚类kmeans clustering的实例 OpenCV k均值聚类kmeans clustering的实例 # ...

  5. Kmeans K均值聚类,OpenCV实现

    Clustering 聚类 kmeans  k均值聚类 Finds centers of clusters and groups input samples around the clusters. ...

  6. k均值聚类算法python_K均值和其他聚类算法:Python快速入门

    k均值聚类算法python This post was originally published here 这篇文章最初发表在这里 Clustering is the grouping of obje ...

  7. K均值聚类的理解和实现

    目录 1. 距离的测度 1.1 欧式距离 1.2 马氏距离 1.2.1 利用马氏距离对数据进行归一化 1.2.2 利用马氏距离进行分类 2. K均值的基本理论 2.1 K均值的原理和实现 2.2 K均 ...

  8. Udacity机器人软件工程师课程笔记(二十一) - 对点云进行集群可视化 - 聚类的分割 - K-means|K均值聚类, DBSCAN算法

    聚类的分割 1.K-均值聚类 (1)K-均值聚类介绍 k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心 ...

  9. matlab传递闭包动态聚类图,用SPSS制作3D散点图全方位动态展示K均值聚类效果

    SPSS系统聚类输出的树状图广受用户喜爱,二阶聚类也可以输出一系列美观的可视化图形用来观察聚类效果,但我们发现Kmeans均值聚类没有提供可视化程度高的图形,那怎么办,我们自己来制作. 数据小兵推荐使 ...

最新文章

  1. 识别、触达、转化、评估!百度云用ABC四招颠覆营销不可能
  2. 波兰极客用一张软盘运行Linux系统,用的还是最新内核!
  3. python 主语_前深度学习时代--FFM模型的原理与Python实现
  4. Spring Caching集成Ehcache
  5. 堆/栈/动态存储方式/静态存储方式
  6. math.js:灵活强大的JavaScript数学库
  7. 文字阴影-CSS Text-Shadow
  8. Navicat for MySQL远程连接的时候报错mysql 1130的解决方法
  9. 剑指offer(数值的整数次方)
  10. python webkit内核_GitHub - yunate/wke: 基于Webkit精简的纯C接口的浏览器内核,可用于桌面UI、浏览器。...
  11. 电脑罗盘时钟html怎么设置成桌面,抖音时钟屏保怎么设置 罗盘时钟屏保设置方法...
  12. 智能三路CAN总线路由器集线器助力灵活组网
  13. BUUCTF之[Zer0pts2020]Can you guess it? basename函数绕过
  14. display-flex详解
  15. 飞腾S2500平台PCIe SWITCH下热插拔验证
  16. Ubuntu 22 04 LTS gcc 安装失败
  17. 阿里云dns 接口调用/代码
  18. 托马斯插件_托马斯·爱迪生讨厌的营销策略
  19. 想学爬虫的同学看过来,手把手教你利用Python网络爬虫获取APP推广信息
  20. Iphone Installous IPA file folder location

热门文章

  1. 关于EasyX和graphics.h的那些事(上)
  2. ARCGIS地图导出问题
  3. 蓝桥杯算法提高 快乐司机
  4. 效率神器----QuickLook
  5. 电子配线架何去何从?
  6. JDK1.8新特性Lambda表达式入门
  7. 用Python快速制作海报级地图!
  8. 了解一下国标和行标的代号
  9. JavaCard开发环境搭建
  10. android app2sd+无法安装应用的解决办法。