支持向量机是智能算法中的一个重要内容,在OpenCV中的使用是很简单的,直接调用cv2.ml系列函数即可。本文通过一个二维的数据来演示一下SVM的使用。

SVM基本使用流程

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

svm = cv2.ml.SVM_create()

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

训练结果 = svm.train(训练数据,训练数据排练格式,训练数据的标签)
  • 训练数据:表示原始数据,用来训练分类器。例如前面说到的研究生录取,初试成绩、面试成绩都是原始的训练数据。
  • 训练数据排练格式:原始数据的排列形式有按行排列(cv2.ml.ROW_SAMPLE,每一条训练数据占一行)和按列排列(cv2.ml.COL_SAMPLE,每一条训练数据占一列),两种,根据数据的排列情况合理选择即可。
  • 训练数据的标签:原始数据的标签
  • 训练结果:训练结果的返回值

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

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

以上为基本使用方法,在实际使用中,会对参数进行适当调整。例如使用setType()函数设置类别,用setKernel()函数设置核类型,用setC()函数设置支持向量机的参数C(惩罚系数,对错误的宽容度,默认为0)。

SVM案例演示

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

1、生成原始的训练数据

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

a = np.random.randint(95,100,(200,2).astype(np.float32))

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

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

最后,将两组数据进行合并,并使用numpy.array对其进行类型转换:

data = np.vstack((a,b))
data = np.array(data,dtype='float32')
2、构造分组标签

首先,将分布在[95,100)区间的数据,构造标签“0”:

aLabel = np.zeros((20,1))

将分布在[90,95)区间的数据,构造标签“1”:

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

最后,将两组数据进行合并,并使用numpy.array对其进行类型转换:

label = np.vstack((aLabel,bLabel))
label = np.array(label,dtype='int32')
3、训练

用支持向量机模块对已知的数据和其对应的标签进行训练。

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()

完整代码:

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 = 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([[99,90],[90,99]]) #0-A级 1-B级
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)

运行结果:

SVM可视化

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

根据上面分类,可知:

笔试99,面试90为B类

笔试90,面试99为B类


博主个人公众号
版权声明 ▶ 本网站名称:陶小桃Blog
▶ 本文链接:https://www.52txr.cn/2022/CVSVM2.html
▶ 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行核实删除。
▶ 转载本站文章需要遵守:商业转载请联系站长,非商业转载请注明出处!!

最后修改:2022 年 05 月 25 日
如果觉得我的文章对你有用,请随意赞赏