【机器学习】python使用支持向量机SVM

2023-11-17

【机器学习】python使用支持向量机SVM

准备:    

    数据集

    导入SVM模块

步骤:

    1.读取数据集

    2.划分训练样本与测试样本

    3.训练SVM分类器

    4.计算分类准确率

    5.绘制图像

    

    关于SVM的原理知识,在【机器学习】支持向量机中讲过,欲知详情,可戳:

    https://blog.csdn.net/u012679707/article/details/80501358

    在Matlab中可以使用工具箱中的svm算法,具体实例在之前的人脸识别matlab实现中讲过,可戳:

    https://blog.csdn.net/u012679707/article/details/78152713

    因为Python中的sklearn库也集成了SVM算法,所以Python中一样可以使用支持向量机做分类。

    【注意】本文的运行环境是windows+Pycharm+python3.6。

    Scikit-Learn库基本实现了所有的机器学习算法,具体使用详见官方文档说明:

    http://scikit-learn.org/stable/auto_examples/index.html#support-vector-machines

    因为本文是基于sklearn包,所以需先在python中下载sklearn包,网上有很多教程,在此不再叙述。

    数据集

    本文用的数据集为Iris.data可从UCI数据库中下载,http://archive.ics.uci.edu/ml/datasets/Iris

    Iris.data的数据格式如下:共5列,前4列为样本特征,第5列为类别,分别有三种类别Iris-setosa, Iris-versicolor, Iris-virginica

    注意:因为在分类中类别标签必须为数字量,所以应将Iris.data中的第5列的类别(字符串)转换为num.

        

导入SVM模块

    首先在使用SVM时,需先从sklearn包中导入SVM模块。

from sklearn import svm

1.读取数据集

#1.读取数据集
path='F:/Python_Project/SVM/data/Iris.data'
data=np.loadtxt(path, dtype=float, delimiter=',', converters={4:Iris_label} )
#converters={4:Iris_label}中“4”指的是第5列:将第5列的str转化为label(number)

    定义的转换函数为:可实现将类别Iris-setosa, Iris-versicolor, Iris-virginica映射成 0,1,2。

#define converts(字典)
def Iris_label(s):
    it={b'Iris-setosa':0, b'Iris-versicolor':1, b'Iris-virginica':2 }
    return it[s]

    读取文件用的是loadtxt函数,其声明如下:

def  loadtxt(fname, dtype=float, comments='#', delimiter=None,converters=None, skiprows=0, usecols=None, unpack=False, ndmin=0)

    常用的参数有:

        fname: 文件路径,例 path='F:/Python_Project/SVM/data/Iris.data'

   dtype:样本的数据类型 例dtype=float

          delimiter:分隔符。例 delimiter=','

          converters:将数据列与转换函数进行映射字典。例 converters={4:Iris_label}含义是将第5列的数据对应转换函数进行转换。

          usecols:选取数据的列。


2.划分训练样本与测试样本

#2.划分数据与标签
x,y=np.split(data,indices_or_sections=(4,),axis=1) #x为数据,y为标签
x=x[:,0:2] #为便于后边画图显示,只选取前两维度。若不用画图,可选取前四列x[:,0:4]
train_data,test_data,train_label,test_label =sklearn.model_selection.train_test_split(x,y, random_state=1, train_size=0.6,test_size=0.4)
       1. split(数据,分割位置,轴=1(水平分割) or 0(垂直分割))。

  2.  sklearn.model_selection.train_test_split随机划分训练集与测试集。train_test_split(train_data,train_label,test_size=数字, random_state=0)

  参数解释:

      train_data:所要划分的样本特征集

      train_label:所要划分的样本类别

      test_size:样本占比,如果是整数的话就是样本的数量.(注意:)

                   --  test_size:测试样本占比。 默认情况下,该值设置为0.25。 默认值将在版本0.21中更改。 只有train_size没有指定时, 

                        它将保持0.25,否则它将补充指定的train_size,例如train_size=0.6,则test_size默认为0.4。

                   -- train_size:训练样本占比。

      random_state:是随机数的种子。

      随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。

3.训练SVM分类器

#3.训练svm分类器
classifier=svm.SVC(C=2,kernel='rbf',gamma=10,decision_function_shape='ovr') # ovr:一对多策略
classifier.fit(train_data,train_label.ravel()) #ravel函数在降维时默认是行序优先

    kernel='linear'时,为线性核,C越大分类效果越好,但有可能会过拟合(defaul C=1)。

  kernel='rbf'时(default),为高斯核,gamma值越小,分类界面越连续;gamma值越大,分类界面越“散”,分类效果越好,但有可能会过拟合。

  decision_function_shape='ovr'时,为one v rest(一对多),即一个类别与其他类别进行划分,

  decision_function_shape='ovo'时,为one v one(一对一),即将类别两两之间进行划分,用二分类的方法模拟多分类的结果。

4.计算分类准确率

#4.计算svc分类器的准确率
print("训练集:",classifier.score(train_data,train_label))
print("测试集:",classifier.score(test_data,test_label))

    结果:

        

    还有另一种计算准确率的方法:

#也可直接调用accuracy_score方法计算准确率
from sklearn.metrics import accuracy_score
tra_label=classifier.predict(train_data) #训练集的预测标签
tes_label=classifier.predict(test_data) #测试集的预测标签
print("训练集:", accuracy_score(train_label,tra_label) )
print("测试集:", accuracy_score(test_label,tes_label) )

    实际上,classifier.score()内部也是先predict得到tes_label , 然后调用了accuracy_score(test_label,tes_label)方法来计算准确率的。

    可以查看一下内部决策函数,返回的是 样本到分类超平面的距离
#查看决策函数
print('train_decision_function:',classifier.decision_function(train_data)) # (90,3)
print('predict_result:',classifier.predict(train_data))

   (1) 若选用“ovr”(一对多),则每个样本会产生3个距离值(3为类别种类数)。如下

        

           

    (2)若选用“ovo”(一对一),则每个样本会产生3*(3-1)/2=3 个距离值,即 :距离值个数=类别数*(类别数-1)/2。结果如下:

        

        

5.绘制图像

    确定坐标轴范围、字体、背景颜色

#5.绘制图形
#确定坐标轴范围
x1_min, x1_max=x[:,0].min(), x[:,0].max() #第0维特征的范围
x2_min, x2_max=x[:,1].min(), x[:,1].max() #第1维特征的范围
x1,x2=np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j ] #生成网络采样点
grid_test=np.stack((x1.flat,x2.flat) ,axis=1) #测试点
#指定默认字体
matplotlib.rcParams['font.sans-serif']=['SimHei']
#设置颜色
cm_light=matplotlib.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
cm_dark=matplotlib.colors.ListedColormap(['g','r','b'] )

grid_hat = classifier.predict(grid_test)       # 预测分类值
grid_hat = grid_hat.reshape(x1.shape)  # 使之与输入的形状相同

    这里用到了mgrid()函数,该函数的作用这里简单介绍一下:

   假设假设目标函数F(x,y)=x+y。x轴范围1~3,y轴范围4~6,当绘制图像时主要分四步进行:

  【step1:x扩展】(朝右扩展):

       [1 1 1]

   [2 2 2]

   [3 3 3]

  【step2:y扩展】(朝下扩展):

   [4 5 6]

   [4 5 6]

   [4 5 6]

  【step3:定位(xi,yi)】:

   [(1,4) (1,5) (1,6)]

   [(2,4) (2,5) (2,6)]

   [(3,4) (3,5) (3,6)]

  【step4:将(xi,yi)代入F(x,y)=x+y】

  因此这里x1, x2 = np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j]后的结果为:

  

  再通过stack()函数,axis=1,生成测试点

  

    绘图:

plt.pcolormesh(x1, x2, grid_hat, cmap=cm_light)     # 预测值的显示
plt.scatter(x[:, 0], x[:, 1], c=y[:,0], s=30,cmap=cm_dark)  # 样本
plt.scatter(test_data[:,0],test_data[:,1], c=test_label[:,0],s=30,edgecolors='k', zorder=2,cmap=cm_dark) #圈中测试集样本点
plt.xlabel('花萼长度', fontsize=13)
plt.ylabel('花萼宽度', fontsize=13)
plt.xlim(x1_min,x1_max)
plt.ylim(x2_min,x2_max)
plt.title('鸢尾花SVM二特征分类')
plt.show()
           pcolormesh(x,y,z,cmap)这里参数代入x1,x2,grid_hat,cmap=cm_light绘制的是背景。

      scatter中edgecolors是指描绘点的边缘色彩,s指描绘点的大小,cmap指点的颜色。

      xlim指图的边界。

     pcolormesh(x,y,z,cmap)绘制的背景如下:即将坐标系下的点都进行一个分类。

plt.pcolormesh(x1, x2, grid_hat, cmap=cm_light)     # 预测值的显示

                

                所有样本点的分类结果:

                    

                将测试点从中圈出来:

                        


    完整代码如下:

# -*- coding:utf-8 -*-
"""
@author:Lisa
@file:svm_Iris.py
@func:Use SVM to achieve Iris flower classification
@time:2018/5/30 0030上午 9:58
"""
from sklearn import svm
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import sklearn
from sklearn.model_selection import train_test_split

#define converts(字典)
def Iris_label(s):
    it={b'Iris-setosa':0, b'Iris-versicolor':1, b'Iris-virginica':2 }
    return it[s]


#1.读取数据集
path='F:/Python_Project/SVM/data/Iris.data'
data=np.loadtxt(path, dtype=float, delimiter=',', converters={4:Iris_label} )
#converters={4:Iris_label}中“4”指的是第5列:将第5列的str转化为label(number)
#print(data.shape)

#2.划分数据与标签
x,y=np.split(data,indices_or_sections=(4,),axis=1) #x为数据,y为标签
x=x[:,0:2]
train_data,test_data,train_label,test_label =train_test_split(x,y, random_state=1, train_size=0.6,test_size=0.4) #sklearn.model_selection.
#print(train_data.shape)

#3.训练svm分类器
classifier=svm.SVC(C=2,kernel='rbf',gamma=10,decision_function_shape='ovo') # ovr:一对多策略
classifier.fit(train_data,train_label.ravel()) #ravel函数在降维时默认是行序优先

#4.计算svc分类器的准确率
print("训练集:",classifier.score(train_data,train_label))
print("测试集:",classifier.score(test_data,test_label))

#也可直接调用accuracy_score方法计算准确率
from sklearn.metrics import accuracy_score
tra_label=classifier.predict(train_data) #训练集的预测标签
tes_label=classifier.predict(test_data) #测试集的预测标签
print("训练集:", accuracy_score(train_label,tra_label) )
print("测试集:", accuracy_score(test_label,tes_label) )

#查看决策函数
print('train_decision_function:\n',classifier.decision_function(train_data)) # (90,3)
print('predict_result:\n',classifier.predict(train_data))

#5.绘制图形
#确定坐标轴范围
x1_min, x1_max=x[:,0].min(), x[:,0].max() #第0维特征的范围
x2_min, x2_max=x[:,1].min(), x[:,1].max() #第1维特征的范围
x1,x2=np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j ] #生成网络采样点
grid_test=np.stack((x1.flat,x2.flat) ,axis=1) #测试点
#指定默认字体
matplotlib.rcParams['font.sans-serif']=['SimHei']
#设置颜色
cm_light=matplotlib.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
cm_dark=matplotlib.colors.ListedColormap(['g','r','b'] )

grid_hat = classifier.predict(grid_test)       # 预测分类值
grid_hat = grid_hat.reshape(x1.shape)  # 使之与输入的形状相同

plt.pcolormesh(x1, x2, grid_hat, cmap=cm_light)     # 预测值的显示
plt.scatter(x[:, 0], x[:, 1], c=y[:,0], s=30,cmap=cm_dark)  # 样本
plt.scatter(test_data[:,0],test_data[:,1], c=test_label[:,0],s=30,edgecolors='k', zorder=2,cmap=cm_dark) #圈中测试集样本点
plt.xlabel('花萼长度', fontsize=13)
plt.ylabel('花萼宽度', fontsize=13)
plt.xlim(x1_min,x1_max)
plt.ylim(x2_min,x2_max)
plt.title('鸢尾花SVM二特征分类')
plt.show()
 -------------------------------------------         END      -------------------------------------

参考:

Python中的支持向量机SVM的使用(有实例) http://www.cnblogs.com/luyaoblog/p/6775342.html(非常好)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【机器学习】python使用支持向量机SVM 的相关文章

  • JavaScript全解析——循环结构语句

    循环控制 控制程序重复执行若干次相同或似的逻辑 理解并正确使用循环控制 需要搞清楚循环的3个要素 起始值 变化量 终止条件 起始值循环的起点 可以是 任意数据类型值 变化量是指 改变起始值的方式 终止条件 布尔类型值 它是循环停止的边界 w
  • springboot多版本管理

    达到的版本控制效果如下 1 api版本定义在url中 采用 api 项目名 pro v4 接口名 的形式 2 api版本号通过注解进行定义 3 如果请求中不指定api版本号则返回最新版本 4 版本的自动适配 如果请求的api版本不存在 则返

随机推荐