根据给定的男女生身高体重数据,经过【数据准备、数据转换、标签准备、训练、预测】过程,能够成功预测出给定的任意身高体重应该属于男生还是女生 # 1 思想 分类器 # 2 如何? 寻求一个最优的超平面 分类 # 3 核:line # 4 数据:样本 # 5 训练 SVM_create train predict # svm本质 寻求一个最优的超平面 分类 # svm 核: line # 身高体重 训练 预测
#男女生身高分类
import cv2
import numpy as np
import matplotlib.pyplot as plt
# svm 对于数据的要求: 所有的数据都要有label
# [155,48] -- 0 女生 [152,53] ---1 男生
# 监督学习 0 负样本 1 正样本
#函数原型:vstack(tup) 参数tup可以是元组,列表,或者numpy数组,返回结果为numpy的数组
#作用:它是垂直(按照行顺序)的把数组给堆叠起来。
#1.准备数据
woman = np.array([[155,48],[159,50],[164,53],[168,56],[172,60]]) #女生数据
man = np.array([[152,53],[156,55],[160,56],[172,64],[176,65]]) #男生数据
#2.data转换
# data = np.vstack(woman,man) #报错
data = np.vstack((woman,man)) #将两个训练样本用行堆积
data = np.array(data,dtype='float32') #改成float32类型
#3.准备标签
label = np.array([[0],[0],[0],[0],[0],[1],[1],[1],[1],[1]]) #0-->女 1-->男
#4.训练
#创建svm
svm = cv2.ml.SVM_create()
#设置svm属性
svm.setType(cv2.ml.SVM_C_SVC)
svm.setKernel(cv2.ml.SVM_LINEAR)
svm.setC(0.01)
#训练
result = svm.train(data,cv2.ml.ROW_SAMPLE,label)
#5.预测
pre_data = np.vstack([[167,55],[162,57]])
pre_data = np.array(pre_data,dtype='float32')
print("pre_data:\n",pre_data)
(par1,par2) = svm.predict(pre_data) #结果存储在par2中
print("par2:\n",par2)
输出:
pre_data:
[[167. 55.]
[162. 57.]]
par2:
[[0.]
[1.]]
#随机生成预测数据+图形化显示预测结果
result = svm.train(data,cv2.ml.ROW_SAMPLE,label)
pre_data1 = np.random.rand(10,1)*20+np.ones((10,1))*160 #身高:[160,180)
pre_data1 = np.array(pre_data1,dtype='float32')
pre_data2 = np.random.rand(10,1)*40+np.ones((10,1))*40 #体重:[40,80)
pre_data2 = np.array(pre_data2,dtype='float32')
pre_data = np.hstack((pre_data1,pre_data2)) #将两组数据进行列堆积,新起一列
pre_data = np.array(pre_data,dtype='float32')
print("pre_data\n",pre_data)
(par1,res) = svm.predict(pre_data) #进行svm预测
print("预测结果res\n",res)
res = np.hstack((res,res)) #进行列堆积,新起一列,使其与测试数据型号一致,便于比较赋值
print("预测堆积后结果res\n",res)
#0-->女 1-->男
pre0 = pre_data[res<0.5] #比较赋值后全变成了一维数组
pre1 = pre_data[res>=0.5]
print("pre0:\n",pre0) #输出女生(一维数组数据)
print("pre1:\n",pre1) #输出男生(一维数组数据)
pre0 = np.reshape(pre0,(int(pre0.shape[0]/2),2)) #重新改变数组形状,使其图形化输出
pre1 = np.reshape(pre1,(int(pre1.shape[0]/2),2))
plt.figure(1)
plt.plot(pre0[:,0],pre0[:,1],'o')
plt.plot(pre1[:,0],pre1[:,1],'o')
plt.show()
输出:
pre_data
[[172.5421 45.893223]
[163.69073 46.986614]
[169.27026 73.5821 ]
[176.9799 52.51847 ]
[164.13753 79.184845]
[160.08942 59.03401 ]
[161.24686 51.76255 ]
[168.38326 55.96825 ]
[164.8569 46.203136]
[175.61798 73.08636 ]]
预测结果res
[[0.]
[0.]
[1.]
[0.]
[1.]
[1.]
[0.]
[0.]
[0.]
[1.]]
预测堆积后结果res
[[0. 0.]
[0. 0.]
[1. 1.]
[0. 0.]
[1. 1.]
[1. 1.]
[0. 0.]
[0. 0.]
[0. 0.]
[1. 1.]]
pre0:
[172.5421 45.893223 163.69073 46.986614 176.9799 52.51847
161.24686 51.76255 168.38326 55.96825 164.8569 46.203136]
pre1:
[169.27026 73.5821 164.13753 79.184845 160.08942 59.03401
175.61798 73.08636 ]