机器学习 | 一文看懂SVM算法从原理到实现全解析

news2024/10/6 2:22:44

目录

初识SVM算法

SVM算法原理

SVM损失函数

SVM的核方法

数字识别器(实操)


初识SVM算法

支持向量机(Support Vector Machine,SVM)是一种经典的监督学习算法,用于解决二分类和多分类问题。其核心思想是通过在特征空间中找到一个最优的超平面来进行分类,并且间隔最大。

SVM能够执行线性或非线性分类、回归,甚至是异常值检测任务。它是机器学习领域最受欢迎的模型之一。SVM特别适用于中小型复杂数据集的分类。

超平面最大间隔介绍:下左图显示了三种可能的线性分类器的决策边界;右图中的实线代表SVM分类器的决策边界,不仅分离了两个类别,且尽可能远离最近的训练实例。

虚线所代表的模型表现非常糟糕,甚至都无法正确实现分类。其余两个模型在这个训练集上表现堪称完美,但是它们的决策边界与实例过于接近,导致在面对新实例时,表现可能不会太好。 

硬间隔和软间隔

硬间隔分类:在上面我们使用超平面进行分割数据的过程中,如果我们严格地让所有实例都不在最大间隔之间,并且位于正确的一边,这就是硬间隔分类。

硬间隔分类有两个问题,首先,它只在数据是线性可分离的时候才有效;其次,它对异常值非常敏感。

当有一个额外异常值的鸢尾花数据:左图的数据根本找不出硬间隔,而右图最终显示的决策边界与我们之前所看到的无异常值时的决策边界也大不相同,可能无法很好地泛化。

软间隔分类:要避免这些问题,最好使用更灵活的模型。目标是尽可能在保持最大间隔宽阔和限制间隔违例(即位于最大间隔之上,甚至在错误的一边的实例)之间找到良好的平衡,这就是软间隔分类。

在Scikit-Learn的SVM类中,可以通过超参数C来控制这个平衡:C值越小,则间隔越宽,但是间隔违例也会越多。上图显示了在一个非线性可分离数据集上,两个软间隔SVM分类器各自的决策边界和间隔。

左边使用了高C值,分类器的错误样本(间隔违例)较少,但是间隔也较小。

右边使用了低C值,间隔大了很多,但是位于间隔上的实例也更多。看起来第二个分类器的泛化效果更好,因为大多数间隔违例实际上都位于决策边界正确的一边,所以即便是在该训练集上,它做出的错误预测也会更少。

接下来通过一个具体的案例来实现SVM算法,这段代码使用了scikit-learn库中的支持向量机(Support Vector Machine,SVM)实现来进行分类任务:

from sklearn import svm

x = [[0, 0], [1, 1]]
y = [0, 1]

ss = svm.SVC()
ss.fit(x, y)
result = ss.predict([[2, 2]])
print(result)

通过拟合得到一个最优的超平面来进行二分类任务,然后使用训练好的模型对新样本进行分类预测,并将预测结果打印出来:

SVM算法的优点

1)SVM方法既可以用于分类(二/多分类),也可用于回归和异常值检测。

2)SVM具有良好的鲁棒性,对未知数据拥有很强的泛化能力,特别是在数据量较少的情况下,相较其他传统机器学习算法具有更优的性能。

使用SVM作为模型时,通常采用如下流程

1)对样本数据进行归一化

2)应用核函数对样本进行映射(最常采用和核函数是RBF和Linear,在样本线性可分时,Linear效果要比RBF好)

3)用cross-validation和grid-search对超参数进行优选

4)用最优参数调练得到模型

5)测试

SVM算法原理

SVM通过优化一个凸二次规划问题来求解最佳的超平面,其中包括最小化模型的复杂度(即最小化权重的平方和),同时限制训练样本的误分类情况。这个优化问题可以使用拉格朗日乘子法来求解。对于非线性可分的情况,SVM可以通过核函数(Kernel Function)将输入特征映射到高维空间,使得原本线性不可分的数据在高维空间中变得线性可分。常用的核函数包括线性核、多项式核、高斯核等。

假设给定一个特征空间上的训练集为:

以上就是线性可分支持向量机的模型表达式。我们要去求出这样一个模型,或者说这样一个超平面y(x),它能够最优地分离两个集合。 

其实也就是我们要去求一组参数(w,b),使其构建的超平面函数能够最优地分离两个集合。如下就是一个最优超平面:

再比如下图的阴影部分是一个“过渡带”,“过渡带”的边界是集合中离超平面最近的样本点落在的地方:

SVM回归:让尽可能多的实例位于预测线上,同时限制间隔违例(也就是不在预测线距上的实例)。线距的宽度由超参数e控制:

SVM损失函数

支持向量机(SVM)在分类问题中使用的损失函数是"hinge loss"(铰链损失),它通常被用于最大间隔分类,即寻找能够最大化分类间隔的超平面。而在SVM中,我们主要讨论三种损失函数:

绿色:0/1损失

1)当正例的点落在y=0这个超平面的下边,说明是分类正确,无论距离超平面所远多近,误差都是0。

2)当这个正例的样本点落在y=0的上方的时候,说明分类错误,无论距离多远多近,误差都为1。

3)图像就是上图绿色线。

蓝色:SVMHinge损失函数

1)当一个正例的点落在y=1的直线上,距离超平面长度1,那么1-E=1,E=0,也就是说误差为0。

2)当它落在距离超平面0.5的地方,1-E=0.5,=0.5,也就是说误差为0.5。

3)当它落在y=0上的时候,距离为0,1-E=0,ε=1,误差为1。

4)这个点落在了y=0的上方,被误分到了负例中,距离算出来应该是负的,比如-0.5,那么1-=-0.5,E=-1.5.误差为1.5。

5)以此类推,画在二维坐标上就是上图中蓝色那根线了。

红色:Logistic损失函数

1)损失函数的公式为:ln(1+e^-yi)

2)当yi=0时,损失等于In2,这样真丑,所以我们给这个损失函数除以ln2。

3)这样到yi=0时,损失为1,即损失函数过(0,1),即点上图中的红色线。

SVM的核方法

核函数:是将原始输入空间映射到新的特征空间,从而,使得原本线性不可分的样本可能在核空间可分。核函数并不是SVM特有的,核函数可以和其他算法也进行结合,只是核函数与SVM结合的优势非常大。

下图所示的两类数据,分别分布为两个圆圈的形状,这样的数据本身就是线性不可分的,此时我们就要思考该如何把这两类数据分开:

接下来通过核方法进行举例说明:

下面这张图位于第一、二象限内。我们关注红色的门,以及“北京四合院”这几个字和下面的紫色的字。我们把红色的门上的点看成是“+"数据,字母上的点看成是“-"数据,它们的横、纵坐标是两个特征。显然,在这个二维空间内,“+”,"-"两类数据不是线性可分的。

绿色的平面可以完美地分割红色和紫色,两类数据在三维空间中变成线性可分的了。

三维中的这个判决边界,再映射回二维空间中:是一条双曲线,它不是线性的。

核函数的作用:一个从低维空间到高维空间的映射,而这个映射可以把低维空间中线性不可分的两类点变成线性可分的。

常见核函数

线性核和多项式核

1)这两种核的作用也是首先在属性空间中找到一些点,把这些点当做base,核函数的作用就是找与该点距离和角度满足某种关系的样本点。

2)样本点与该点的夹角近乎垂直时,两个样本的欧式长度必须非常长才能保证满足线性核函数大于0;而当样本点与base点的方向相同时,长度就不必很长;而当方向相反时,核函数值就是负的,被判为反类。即,它在空间上划分出一个梭形,按照梭形来进行正反类划分。

RBF核

1)高斯核函数就是在属性空间中找到一些点,这些点可以是也可以不是样本点,把这些点当做base,以这些base为圆心向外扩展,扩展半径即为带宽,即可划分数据。

2)换句话说,在属性空间中找到一些超圆,用这些超圆来判定正反类。

Sigmoid核

1)同样地是定义一些base,

2)核函数就是将线性核函数经过一个tanh函数进行处理,把值域限制在了-1到1上。

总之,都是在定义距离,大于该距离,判为正,小于该距离,判为负。至于选择哪一种核函数,要根据具体的样本分布情况来确定,以下是使用的指导规则:

1)如果Feature的数量很大,甚至和样本数量差不多时,往往线性可分,这时选用LR或者线性核Linear。

2)如果Feature的数量很小,样本数量正常,不算多也不算少,这时选用RBF核。

3)如果Feature的数量很小,而样本的数量很大,这时手动添加一些Feature,使得线性可分,然后选用LR或者线性核Linear。

4)多项式核一般很少使用,效率不高,结果也不优于RBF。

5)Linear核参数少,速度快;RBF核参数多,分类结果非常依赖于参数,需要交叉验证或网格搜索最佳参数,比较耗时。

6)应用最广的应该就是RBF核,无论是小样本还是大样本,高维还是低维等情况,RBF核函数均适用。

数字识别器(实操)

MNIST(“修改后的国家标准与技术研究所")是计算机视觉事实上的"helloworld"数据集。自1999年发布以来,这一经典的手写图像数据集已成为分类算法基准测试的基础。随着新的机器学习技术的出现,MNIST仍然是研究人员和学习者的可靠资源。

本次 案例 中,我们的目标是从数万个手写图像的数据集中正确识别数字:

数据集介绍:数据文件train.csv和test.csv包含从o到9的手绘数字的灰度图像。

每个图像的高度为28个像素,宽度为28个像素,总共为784个像素。每个像素具有与其相关联的单个像素值,指示该像素的亮度或暗度,较高的数字意味着较暗。该像素值是0到255之间的整数,包括0和255。训练数据集(train.csv)有785列。第一列称为“标签”,是用户绘制的数字。其余列包含关联图像的像素值。

训练集中的每个像素列都具有像pixelx这样的名称,其中x是0到783之间的整数,包括0和783。为了在图像上定位该像素,假设我们已经将x分解为×=i*28+j,其中i和j是0到27之间的整数,包括0和27。然后,pixelx位于28x28矩阵的第i行和第j列上(索引为零)。

例如,pixel31表示从左边开始的第四列中的像素,以及从顶部开始的第二行,如下面的asci图中所示。在视觉上,如果我们省略“像素”前缀,像素组成图像如下:

以下是案例实现的具体过程:

获取数据

导入相关要使用的第三方库,获取数据集当中的数据:

这里展示了图片资源给出的画面:

数据基本处理

接下来给图片数据进行归一化处理:

然后进行数据分割:

特征降维和模型优化

这里进行数据的特征工程:

# 3. 特征降维和模型训练
import time
from sklearn.decomposition import PCA

# 通过多次使用 PCA 确定最优模型
def n_components_analysis(n, x_train, y_train, x_test, y_test):
    # 记录开始时间
    start= time.time()  
    
    # PCA降维实现
    pca = PCA(n_components=n) 
    print("特征降维传递的参数为:{}".format(n))
    pca.fit(x_train) # 学习如何降维
    
    # 在训练集和测试集进行降维
    x_train_pca = pca.transform(x_train)
    x_test_pca = pca.transform(x_test)
    
    # 利用 SVM 进行模型训练(这里使用常见的svc)
    print("开始使用SVC进行训练")
    svc = svm.SVC()
    svc.fit(x_train_pca, y_train.ravel())
    
    # 获取accuracy结果
    acc = svc.score(x_test_pca, y_test)
    
    # 记录结束时间
    end = time.time()
    
    print(f"[n_components={n}]准确率为:{acc * 100:.4f}%,耗时{end - start:.2f}s\r\n")
    
    return acc

传递多个数值找到最合理的模型参数:

确定最优模型

SVM基本综述

SVM是一种二类分类模型。

它的基本模型是在特征空间中寻找间隔最大化的分离超平面的线性分类器。

1)当训练样本线性可分时,通过硬间隔最大化,学习一个线性分类器,即线性可分支持向量机;

2)当练数据近似线性可分时,引入松弛变量,通过软间隔最大化,学习一个线性分类器,即线性支持向量机;

3)当训练数据线性不可分时,通过使用核技巧及软间隔最大化,学习非线性支持向量机。

SVM优缺点

优点:

1)高维空间中非常高效。

2)即使在数据维度比样本数量大的情况下仍然有效。

3)在决策函数(称为支持向量)中使用训练集的子集,因此它也是高效利用内存的。

4)通用性:不同的核函数与特定的决策函数一一对应。

SVM的缺点:

1)如果特征数量比样本数量大得多,在选择核函数时要避免过拟合。

2)对缺失数据敏感。

3)对于核函数的高维映射解释力不强。

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

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

相关文章

Pymysql之Cursor常用API

Cursor常用API 1、cursor.execute(query, argsNone):执行sql语句。 参数: query (str):sql语句。 args (tuple, list or dict):sql语句中如果有变量,或者格式化输出,会在这里填充数据。 Returns:返…

编程实例分享,手表养护维修软件钟表维修开单管理系统教程

编程实例分享,手表养护维修软件钟表维修开单管理系统教程 一、前言 以下教程以 佳易王钟表维护维修管理系统软件V16.0为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 左侧为导航栏, 1、系统设置:可以设置打…

代码随想录算法训练营DAY15 | 二叉树 (2)

一、LeetCode 102 二叉树的层序遍历 题目链接: 102.二叉树的层序遍历https://leetcode.cn/problems/binary-tree-level-order-traversal/ 思路:利用队列的先进先出特性,在处理本层节点的同时将下层节点入队,每次处理一层的节点&…

C#中的浅度和深度复制(C#如何复制一个对象)

文章目录 浅度和深度复制浅度复制深度复制如何选择 浅度和深度复制 在C#中,浅度复制(Shallow Copy)和深度复制(Deep Copy)是两种不同的对象复制方式,满足不同的应用场景需求,它们主要区别在于处…

【JavaWeb】头条新闻纯JavaWeb项目实现 项目搭建 数据库工具类导入 跨域问题 Postman 第一期 (前端Vue3+Vite)

文章目录 一、项目简介1.1 微头条业务简介1.2 技术栈介绍 二、项目部署三、准备工具类3.1 异步响应规范格式类3.2 MD5加密工具类3.3 JDBCUtil连接池工具类3.4 JwtHelper工具类3.4 JSON转换的WEBUtil工具类 四、准备各层的接口和实现类4.1 准备实体类和VO对象4.2 DAO层接口和实现…

Guitar Pro正版多少钱 Guitar Pro购买后永久使用吗

相信很多玩吉他的小伙伴都听说过Guitar Pro这款软件,Guitar Pro是一款传奇的吉他谱软件,可以用来打谱,看谱,midi音序制作等等,同时做为一款吉他学习辅助软件有着强大的优势,那大家知道Guitar Pro正版多少钱…

渗透测试-信息打点与架构分析细节梳理

渗透测试-信息打点与架构分析细节梳理 为了保障信息安全,我在正文中会去除除靶场环境的其他任何可能的敏感信息 什么是网站架构 网站架构包括网站的方方面面,下面是常见的内容: 前端(Front-End): 使用Reac…

算法学习——LeetCode力扣哈希表篇1

算法学习——LeetCode力扣哈希表篇1 242. 有效的字母异位词 242. 有效的字母异位词 - 力扣(LeetCode) 描述 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 注意:若 s 和 t 中每个字符出现的次数都相同…

请查收,你的2023京东零售技术年度好文

新春佳节,万象更新!京东零售技术在2023年度发布文章内容145篇,全年阅读量超过20万次~衷心感谢每一位读者一直以来的关注和支持。 在新春到来之际,我们精选年度好文分享给大家,希望大家温故知新&#xff0c…

基于 NXP S32K344 的汽车通用评估板方案

S32K3xx 系列是 NXP 基于 ARMCortex-M7 的汽车工业级 MCU,符合 ISO26262 ASIL-D 汽车功能安全等级,支持 ASIL B/D 安全应用,提供了一个可扩展的平台,具有下一代安全性、可扩展性、连接性和低功耗特性。适用于可能会在严酷环境下工…

政安晨:机器学习快速入门(四){pandas与scikit-learn} {随机森林}

咱们将在这篇文章中使用更复杂的机器学习算法。 随机森林 基本定义 随机森林(Random Forest)是一种机器学习算法,属于集成学习(ensemble learning)的一种。它是通过构建多个决策树(即森林)来进行预测和分类的。 随机森林的主要特点是采用了…

「云原生可观测团队」获选「InfoQ 年度技术内容贡献奖」

随着云原生、人工智能逐渐成为各行各业的创新生产力工具。可以预见,我们即将进入全新的智能化时代。随着数据成为新型生产要素,云和 AI 正走向深度融合。云原生通过提供大规模多元算力的高效供给,可观测成为业务创新的核心基础设施&#xff0…

Future和FutureTask

Future和FutureTask Future类Future主要方法get()get(long timeout,TimeUnit unit)cancel()isDone()isCancelled() 用线程池的submit方法返回Future对象用FutureTask来创建Future Future类 FutureTask叫未来任务,可以将一个复杂的任务剔除出去交给另外一个线程来完…

基于LLM的Agent的兴起及其潜力:综述

原文链接:https://arxiv.org/pdf/2309.07864v1.pdf 1. Introduction LLM-based Agent的基本构成。本文认为,构成LLM-based Agent的核心部件有三个: brain: 主要目标有2个—信息记忆、信息处理perception: 主要目标在于让agent能够感受到更…

0207作业

继承:是 C中类的一个重要特性,它允许一个类从另一个类中继承成员变量和成员函数。通过继承,可以在子类中重用父类的代码,并可以根据需要进行扩展和修改。继承关系形成了类的层次结构。 虚继承:是一种特殊的继承方式&a…

林浩然与杨凌芸的Java奇缘:final关键字的三次浪漫邂逅

林浩然与杨凌芸的Java奇缘:final关键字的三次浪漫邂逅 Lin Haoran and Yang Lingyun’s Java Romance: Three Romantic Encounters with the “final” Keyword 在一个名叫“编程乐园”的世界里,住着两位才子佳人——男主角林浩然和女主角杨凌芸。他们不…

【翻译】 Processing的安卓项目构建(译者用的是Android Studio)

原文链接:https://github.com/processing/processing-android/wiki/Building-Processing-for-Android,版本Apr 2, 2023 译者声明:这个文档是开源公开的,协议是GNU协议。译者自己得使用这个文档,所以才翻译的&#xff0…

Windows Server 2019 DHCP服务器搭建

系列文章目录 目录 系列文章目录 文章目录 前言 一、DHCP服务器是什么? 二、配置服务器 1.实验环境搭建 1)实验服务器配置和客户端 2)实验环境 2.服务器配置 ​编辑 文章目录 Windows Server 2003 Web服务器搭建Windows Server 2003 FTP服务器搭建Windows S…

【Java 数据结构】反射

反射 1 定义2 用途(了解)3 反射基本信息4 反射相关的类(重要)4.1 Class类(反射机制的起源 )4.1.1 Class类中的相关方法(方法的使用方法在后边的示例当中) 4.2 反射示例4.2.1 获得Class对象的三种方式4.2.2 反射的使用 5、反射优点和缺点 1 定义 Java的反…

YOLOv8改进 更换轻量级网络结构

一、GhostNet论文 论文地址:1911.11907.pdf (arxiv.org) 二、 GhostNet结构 GhostNet是一种高效的目标检测网络,具有较低的计算复杂度和较高的准确性。该网络采用了轻量级的架构,可以在计算资源有限的设备上运行,并能够快速地实时检测图像中的目标物体。 GhostNet基于Mo…