第三节:支持向量机分类预测

news2024/11/28 23:05:09

0、介绍

        监督学习(英语:Supervised learning)是机器学习中最为常见、应用最为广泛的分支之一。本次实验将带你了解监督学习中运用十分广泛的支持向量机,并学会使用 scikit-learn 来构建预测模型,用于解决实际问题。

知识点

  • 理论基础
  • 线性分类
  • 非线性分类

1、线性支持向量机

在上一节关于线性模型的课程中,我们学习了通过感知机构建一个线性分类器,完成二分类问题。

感知机的学习过程由误分类驱动,即当感知机寻找到没有实例被错误分类时,就确定了分割超平面。这样虽然可以解决一些二分类问题,但是训练出来的模型往往容易出现过拟合。

如上图所示,当感知机在进行分类时,为了照顾左下角的两个红色标记样本,分割线会呈现出如图所示的走向。你应该通过观察就能发现,这条分割线不是特别合理。

于是,Vapnik 于 1963 年提出了支持向量机理论,并将其用于解决线性分类问题。支持向量机也被看成是感知机的延伸。简单来讲,支持向量机就是通过找出一个最大间隔超平面来完成分类。

如图所示,中间的实线是我们找到的分割超平面。这个超平面并不是随手一画,它必须满足两个类别中距离直线最近的样本点,与实线的距离一样且最大。这里的最大,也就是上面提到的最大间隔超平面。

许多朋友在一开始接触支持向量机时,对它这个奇怪的名字比较疑惑。其实,支持向量机中的「支持向量」指的是上图中,距离分割超平面最近的样本点,即两条虚线上的一个实心点和两个空心点。

接下来我们就来通过 scikit-learn 对上面的红蓝样本数据分别进行线性支持向量机和感知机分类实验。

 首先,我们需要先导入数据文件,这里使用到了  Pandas。如果你没有用过也不必担心,我们只是使用了其中导入 CSV 文件的一个方法。

import pandas as pd  # 导入 pandas 模块
import warnings
warnings.filterwarnings('ignore')

# 读取 csv 数据文件
df = pd.read_csv(
    "https://labfile.oss.aliyuncs.com/courses/866/data.csv", header=0)
df.head()

你可以直接通过 df.head() 语句查看一下这个数据集头部,对里面的数据组成初步熟悉一下。

xyclass
00.1786810.3006820
10.2020330.3201880
20.1755680.2900420
30.1568860.2847220
40.1444320.3024550

我们可以看到,有两个类别。其中 0 即表示上面图中的蓝色样本点,1 对应着红色样本点。

和上一节课的过程相似,下面导入分割模块,将整个数据集划分为训练集和测试集两部分,其中训练集占 70%。

from sklearn.model_selection import train_test_split  # 导入数据集划分模块

# 读取特征值及目标值
feature = df[["x", "y"]]
target = df["class"]

# 对数据集进行分割
train_feature, test_feature, train_target, test_target = train_test_split(
    feature, target, test_size=0.3)

接下来,导入线性支持向量机分类器。

from sklearn.svm import LinearSVC  # 导入线性支持向量机分类器

# 构建线性支持向量机分类模型
model_svc = LinearSVC()
model_svc.fit(train_feature, train_target)

# LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
#           intercept_scaling=1, loss='squared_hinge', max_iter=1000,
#           multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,
#           verbose=0)

然后,我们对模型在测试集上的准确度进行评估,之前使用了 accuracy_score ,这里使用模型带有的 score 方法效果是一样的

# 支持向量机分类准确度
model_svc.score(test_feature, test_target)
# 1.0

可以看出,线性支持向量机分类准确率还不错。我们使用前面相似的方法来绘制出分类器的决策边界。

import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline

# 创建一个绘图矩阵方便显示决策边界线
X = feature.values
x_min, x_max = X[:, 0].min() - 0.1, X[:, 0].max() + 0.1
y_min, y_max = X[:, 1].min() - 0.1, X[:, 1].max() + 0.1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
                     np.arange(y_min, y_max, 0.02))

fig, ax = plt.subplots()
# 绘制决策边界
Z = model_svc.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
ax.contourf(xx, yy, Z, cmap=plt.cm.Paired)
# 绘制训练和测试数据
ax.scatter(train_feature.values[:, 0], train_feature.values[:, 1], c=train_target)
ax.scatter(test_feature.values[:, 0], test_feature.values[:, 1], c=test_target)

# <matplotlib.collections.PathCollection at 0x7f8ad52d1c10>

2、非线性支持向量机

        通过上面的内容,你应该对线性分类有所了解,并可以使用支持向量机构建一个简单的线性分类器了。而在实际生活中,我们大部分情况面对的却是非线性分类问题,因为实际数据往往都不会让你通过一个水平超平面就能完美分类。

        上图展现的就是一个非线性分类问题,而支持向量机就是解决非线性分类的有力武器。那么支持向量机是如何实现非线性分类呢?

        这里,支持向量机引入了核函数来解决非线性分类的问题。简单来讲,通过核函数,我们可以将特征向量映射到高维空间中,然后再高维空间中找到最大间隔分割超平面完成分类。而映射到高维空间这一步骤也相当于将非线性分类问题转化为线性分类问题

如上图所示:

  1. 第一张图中,红蓝球无法进行线性分类。
  2. 使用核函数将特征映射到高维空间,类似于在桌子上拍一巴掌使小球都飞起来了。
  3. 在高维空间完成线性分类后,再将超平面重新投影到原空间。

将特征映射到高维空间的过程中,我们常常会用到多种核函数,包括:线性核函数、多项式核函数、高斯径向基核函数等。其中,最常用的就算是高斯径向基核函数了,也简称为 RBF 核

接下来,我们就通过 scikit-learn 来完成一个非线性分类实例。这次,我们选择了 digits 手写数字数据集。digits 数据集无需通过外部下载,可以直接由 scikit-learn 提供的 datasets.load_digits() 方法导入。该数据集的详细信息如下:

方法描述
('images', (1797L, 8L, 8L))数据集包含 1797 张影像,影像大小为 8x8
('data', (1797L, 64L))data 将 8x8 像素根据其灰度值转换为矩阵
('target', (1797L,))记录 1797 张影像各自代表的数字

第一步,导入数据并进行初步观察。

from sklearn import datasets  # 导入数据集模块

# 载入数据集
digits = datasets.load_digits()

# 绘制数据集前 5 个手写数字的灰度图
for index, image in enumerate(digits.images[:5]):
    plt.subplot(2, 5, index+1)
    plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest')

 可以用 digits.target[:5] 查看前五张手写数字对应的实际标签。

digits.target[:5]
# array([0, 1, 2, 3, 4])

        通常,我们在处理图像问题时,都是将图像的每一个像素转换为灰度值或按比例缩放的灰度值。有了数值,就可以构建和图像像素大小相同的矩阵了。在这里,digits 已经预置了每一张图像对应的矩阵,并包含在 digits.images 方法中。

我们可以通过 digits.images[1] 输出第 1 张手写数字对应的 8x8 矩阵。很方便地,scikit-learn 已经将 8x8 矩阵转换成了方便作为特征变量输入 64x1 的矩阵,并放在了 digits.data 中。你可以使用 digits.data[1]查看。

digits.data[1]
# 输出如下
array([ 0.,  0.,  0., 12., 13.,  5.,  0.,  0.,  0.,  0.,  0., 11., 16.,
        9.,  0.,  0.,  0.,  0.,  3., 15., 16.,  6.,  0.,  0.,  0.,  7.,
       15., 16., 16.,  2.,  0.,  0.,  0.,  0.,  1., 16., 16.,  3.,  0.,
        0.,  0.,  0.,  1., 16., 16.,  6.,  0.,  0.,  0.,  0.,  1., 16.,
       16.,  6.,  0.,  0.,  0.,  0.,  0., 11., 16., 10.,  0.,  0.])

如果你连续学习了前面的小节,你应该对接下来的实验步骤比较熟悉了。下面,我们需要划分训练集和测试集,然后针对测试集进行预测并评估预测精准度。

from sklearn.svm import SVC  # 导入非线性支持向量机分类器
from sklearn.metrics import accuracy_score  # 导入评估模块

feature = digits.data  # 指定特征
target = digits.target  # 指定目标值

# 划分数据集,将其中 70% 划为训练集,另 30% 作为测试集
train_feature, test_feature, train_target, test_target = train_test_split(
    feature, target, test_size=0.33)

model = SVC()  # 建立模型
model.fit(train_feature, train_target)  # 模型训练
results = model.predict(test_feature)  # 模型预测

scores = accuracy_score(test_target, results)  # 评估预测精准度
scores
# 0.9781144781144782

        最后,模型预测准确度为 97.8%。由于每一次运行时,数据集都会被重新划分,所以你训练的准确度甚至会低于 97.8%。如果你还想提高一下准确度,准确度为什么这么低,让支持向量机的分类效果更好,可以通过调整参数来做到。

        不要忘记了,我们在建立模型的时候使用的是默认参数。

model
# 输出如下
SVC(C=1.0, break_ties=False, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovr', degree=3, gamma='scale', kernel='rbf',
    max_iter=-1, probability=False, random_state=None, shrinking=True,
    tol=0.001, verbose=False)

        上面输出了默认模型的参数。我们可以看到,该模型的确使用了最常用的 RBF 高斯径向基核函数,这没有问题。问题出在了 gamma 参数,gamma 是核函数的因数,这里选择了 auto 自动(gamma当前的默认值“auto”将在0.22版本中更改为“scale”)。自动即表示 gamma 的取值为 1 / 特征数量,这里为 1/64。

你可以尝试将 gamma 参数的值改的更小一些,比如 0.001。重新建立模型

model = SVC(gamma=0.001)  # 重新建立模型
model.fit(train_feature, train_target)  # 模型训练
results = model.predict(test_feature)  # 模型预测

scores = accuracy_score(test_target, results)  # 评估预测精准度
scores
# 0.9932659932659933

        可以看到,这一次的预测准确度已经达到 99.3% 了,结果非常理想。所以说,会用 scikit-learn 建立模型只是机器学习过程中最基础的一步,更加重要的是理解模型的参数,并学会调参使得模型的预测性能更优。

小练习

通过  官方文档 了解 scikit-learn 中支持向量机分类器 sklearn.svm.SVC 中包含的参数,并尝试修改它们查看结果变化。

实验总结

支持向量机是机器学习中非常实用的模型之一。它理论基础完善,分类结果出色,深受数据科学家的喜欢。希望能通过本次实验,掌握支持向量机的基本原理,并学会使用 scikit-learn 构建一个支持向量机分类模型。

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

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

相关文章

都什么年代了,还在用Excel和ACCESS做应用系统?快来学Eversheet

表格用的越久&#xff0c;就越头疼 稍微有规模的企业&#xff0c;各种表格都会多如牛毛&#xff0c;一堆堆的&#xff0c;有时候这里一张&#xff0c;那里一张&#xff0c;容易整乱&#xff0c;更容易丢失。不管你是用WPS还是用Excel&#xff0c;有些问题你还是依旧解决不了。…

【VM服务管家】VM4.x算法模块开发_4.1 开发配置类

目录 4.1.1 算法开发&#xff1a;算法模块的开发流程4.1.2 参数操作&#xff1a;获取与设置模块参数的方法4.1.3 文件交互&#xff1a;文件交互操作的配置方法4.1.4 输出显示&#xff1a;设置输出并显示在VM界面的方法4.1.5 模板配置&#xff1a;模板配置界面的实现方法4.1.6 命…

中文译英文 模型

Helsinki-NLP/opus-mt-zh-en Hugging FaceWe’re on a journey to advance and democratize artificial intelligence through open source and open science.https://huggingface.co/Helsinki-NLP/opus-mt-zh-en?text%E6%88%91%E5%8F%AB%E6%B2%83%E5%B0%94%E5%A4%AB%E5%86%8…

【Java入门合集】第一章Java概述

【Java入门合集】第一章Java概述 博主&#xff1a;命运之光 专栏&#xff1a;JAVA入门 学习目标 1.理解JVM、JRE、JDK的概念&#xff1b; 2.掌握Java开发环境的搭建,环境变量的配置&#xff1b; 3.掌握Java程序的编写、编译和运行&#xff1b; 4.学会编写第一个Java程序&#x…

Python 科研绘图可视化(后处理)Matplotlib - RGBAxes

Introduction 科研可视化是将数据和信息转化为可视化形式的过程&#xff0c;旨在通过图形化展示数据和信息&#xff0c;使得科研工作者能够更好地理解和分析数据&#xff0c;并从中发现新的知识和洞见。科研可视化可以应用于各种领域&#xff0c;如生物学、物理学、计算机科学…

一文带你入门C++类和对象【十万字详解,一篇足够了】

本文字数较多&#xff0c;建议电脑端访问。不多废话&#xff0c;正文开始 文章目录 ———————————————【类和对象 筑基篇】 ———————————————一、前言二、面向过程与面向对象三、结构体与类1、C中结构体的变化2、C中结构体的具体使用3、结构体 --&…

3.6 Linux shell脚本编程(概念、变量、语句)

目录 shell脚本概述 shell脚本编写步骤 第一个shell脚本文件 shell脚本变量 变量的介绍 变量的作用 变量的命名要求 变量的分类 用户自定义变量 取值 用户自定义变量-数组 只读变量 位置变量与预定义变量 环境变量 shell语句 shell程序 说明性语句&#xff08…

MATLAB连续时间信号的实现和时域基本运算(八)

1、实验目的&#xff1a; 1&#xff09;熟悉常用连续时间信号的实现方法&#xff1b; 2&#xff09;掌握连续时间信号的时域基本运算&#xff1b; 3&#xff09;掌握实现基本函数及其运算的函数的使用方法&#xff1b; 4&#xff09;加深对信号基本运算的理解。 2、实验内容&am…

【VM服务管家】VM4.0平台SDK_2.4 结果获取类

目录 2.4.1 数据结果&#xff1a;通过流程输出或模块输出获取数据结果的方法2.4.2 流程运行&#xff1a;所有流程运行结束的回调方法2.4.3 模块回调&#xff1a;所有模块运行结束的回调方法2.4.4 加密狗回调&#xff1a;获取加密狗状态的回调方法2.4.5 方案加载&#xff1a;方案…

STM32物联网实战开发(4)——基本定时器

我使用的是正点原子的阿波罗F429开发板&#xff0c;他有14个定时器&#xff0c;本次实验使用STM32F429的基本定时器6作定时&#xff0c;在中断中每隔1秒翻转LED电平状态。 1.CubeMX初始化定时器 先开启定时器6 再对定时器6的参数进行配置&#xff0c;将定时器6定时时间配置为…

记一次SSRF漏洞的学习和利用

导语&#xff1a;本文主要记录一次我们在复盘嘶吼网站渗透报告时遇到的一个SSRF漏洞。 1.前言 本文主要记录一次我们在复盘嘶吼网站渗透报告时遇到的一个SSRF漏洞。此漏洞并结合腾讯云的API接口&#xff0c;可以获取大量嘶吼服务器的敏感信息。利用这些敏感信息&#xff0c;又…

阿里测试8年,肝到P8只剩他了····

在阿里工作了8年&#xff0c;工作压力大&#xff0c;节奏快&#xff0c;但是从技术上确实得到了成长&#xff0c;尤其是当你维护与大促相关的系统的时候&#xff0c;熬到P7也费了不少心思&#xff0c;小编也是个爱学习的人&#xff0c;把这几年的工作经验整理成了一份完整的笔记…

玩转ChatGPT提示词 持续更新·······

导语&#xff1a; 众所周知&#xff0c;在AI的世界里&#xff0c;提示词就是和AI沟通语言的桥梁&#xff0c;提示关键词常用于AI对话及AI绘画等相关场景&#xff0c;通过准确的使用关键词&#xff0c;你就能更好的让AI辅助自己的工作&#xff0c;其中的成分重要性不言而喻&…

黑客教程,从零基础入门到精通

学前感言: 1.这是一条坚持的道路,三分钟的热情可以放弃往下看了. 2.多练多想,不要离开了教程什么都不会了.最好看完教程自己独立完成技术方面的开发. 3.有时多google,baidu,我们往往都遇不到好心的大神,谁会无聊天天给你做解答. 4.遇到实在搞不懂的,可以先放放,以后再来解决. …

c++标准模板(STL)(std::array)(三)

定义于头文件 <array> template< class T, std::size_t N > struct array;(C11 起 std::array 是封装固定大小数组的容器。 此容器是一个聚合类型&#xff0c;其语义等同于保有一个 C 风格数组 T[N] 作为其唯一非静态数据成员的结构体。不同于 C 风格数组…

C#非常实用的技巧

1、解压和压缩 .NET Framework 4.5以上版本&#xff1a; string zipFilePath "C:\path\to\file.zip";string destFolder "C:\path\to\destination\folder";using (var archive ZipFile.OpenRead(zipFilePath)){foreach (var entry in archive.Entries…

【Python】【进阶篇】14、Django创建第一个项目

目录 Django创建第一个项目1. 第一个项目BookStore1) BookStore项目创建 2. Django项目配置文件1) manage.py文件2) __init__.py文件3) settings.py文件4) urls.py文件5) wsgi.py文件 Django创建第一个项目 在上一章中&#xff0c;我们完成了开发环境的搭建工作。 本章我们将学…

网络安全基础入门学习路线

在大多数的思维里总觉得学习网络安全得先收集资料、学习编程、学习计算机基础&#xff0c;这样不是不可以&#xff0c;但是这样学效率太低了&#xff01; 你要知道网络安全是一门技术&#xff0c;任何技术的学习一定是以实践为主的。也就是说很多的理论知识其实是可以在实践中…

【一起撸个DL框架】4 反向传播求梯度

CSDN个人主页&#xff1a;清风莫追 欢迎关注本专栏&#xff1a;《一起撸个DL框架》 文章目录 4 反向传播求梯度&#x1f965;4.1 简介4.2 导数与梯度4.3 链式法则4.4 示例&#xff1a;y2x1的梯度 4 反向传播求梯度&#x1f965; 4.1 简介 上一篇&#xff1a;【一起撸个DL框架】…

Python标准数据类型-String(字符串)

✅作者简介&#xff1a;CSDN内容合伙人、阿里云专家博主、51CTO专家博主、新星计划第三季python赛道Top1 &#x1f4c3;个人主页&#xff1a;hacker707的csdn博客 &#x1f525;系列专栏&#xff1a;零基础入门篇 &#x1f4ac;个人格言&#xff1a;不断的翻越一座又一座的高山…