关于支持向量机的一份介绍

server/2024/9/24 5:41:16/

在这篇文章中,我将介绍与支持向量机有关的东西,我们知道支持向量机主要分两类,就是线性支持向量机支持向量机这两种(当然还有其他的,如多类支持向量机、 Nu-Support Vector Regression等),因此我将介绍它俩的联系与区别,但首先将会详细介绍它俩有关的知识及python实现。

一、 线性支持向量机

1.1 概念

线性支持向量机(Linear Support Vector Machine, Linear SVM)是一种用于分类和回归分析的监督学习模型,特别适用于数据在特征空间中是线性可分的情况。

线性SVM原本可用于进行二分类任务,但如果进行“一对多”等处理后,也可进行多分类任务。

下图就是iris数据集进行SVM后的图像:

1.2 数学模型

关于线性SVM的数学模型可以分为三来来看,分别是决策函数、原问题以及对偶问题。

(1)决策函数

线性SVM的决策函数是用来预测新输入样本所属类别的函数。在求解线性SVM的对偶问题之后,我们得到一系列拉格朗日乘子 αi,这些乘子用于构建最终的决策函数。其中拉格朗日乘子是对偶问题里的,暂且不谈。

我们知道SVM是用于划分类别的,所以我们可以用一个线性组合来描述:

我们将其记为:(W,b)。这样就会诞生一个空间中任意点到超平面的距离r。

然后我们假设这个超平面能正确分类样本,即方才的线性组合>0时,有yi = +1;反之小于0时,有yi = -1。

那么我将这个线性组合重写下就是:

如果用sign函数来表示,可以是这样:

(2)原问题

首先我们知道SVM问题就是一个优化问题,旨在数据线性可分的情况下去寻找一个最优的超平面将之划分,并使间隔最大化。

其中,距离超平面最近的几个训练样本使得其决策函数成立,它们就被称为是“支持向量”。而两个异类支持向量到超平面的和就是“间隔”。

为了间隔最大化,就有了原问题,所以可以写出以下式子:

(3)对偶问题

关于刚才的问题,我们要知道如果直接就用那些式子去找最优超平面会很复杂,所以我们我们需要对偶问题来帮助我们。而在对偶问题中就需要拉格朗日乘子,关于这个乘子,我们则需要了解下拉格朗日函数。

假如我们有目标函数f(x,y),我们要找到它的极值,但同时又存在一个g(x,y)=c(c为常数)来对其进行约束的话,我们就可以构造一个新函数来解决,这个新函数就是拉格朗日函数,表达式如下:

其中的λ(lambda)就是拉格朗日乘子。

而要解决这个式子就需要让其梯度为0,如下:

然后有:

最后就可分别求得x、y、λ的值了。

那么我们就来求取在对偶条件下的线性SVM的模型:

我们已知拉格朗日函数的形式,那么我们将相应的函数带入即可。首先是目标函数,因为我们要求取一个最优超平面,所以将刚才的原问题中的模型带入到f(x,y)的位置;然后是约束函数,因为要让间隔最大化,所以需要约束条件如此确保间隔的最大化;接下来是常数C,一般在没有先验条件的前提下,我们都会使用1作为默认值。(当C越大,模型越倾向于减少分类错误,C越小,模型的泛化能力越强)

那么就有了最后的模型:

1.3 python实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score# 加载Iris数据集
iris = load_iris()
X = iris.data[:, :2]  # 只取前两个特征:花萼长度和花萼宽度
y = iris.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 创建SVM模型
svm = SVC(kernel='linear', C=1)
# 训练模型
svm.fit(X_train, y_train)
y_pre = svm.predict(X_test)
accuracy = accuracy_score(y_test, y_pre)
print("Accuracy is: {}".format(accuracy))# 绘制决策边界
def plot_decision_boundary(model, X, y):# 创建网格x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),np.arange(y_min, y_max, 0.01))# 预测网格中的类别Z = model.predict(np.c_[xx.ravel(), yy.ravel()])Z = Z.reshape(xx.shape)# 绘制背景色plt.contourf(xx, yy, Z, alpha=0.8)# 绘制训练数据点markers = ['o', 's', '^']for i, label in enumerate(np.unique(y)):plt.scatter(X[y == label, 0], X[y == label, 1], marker=markers[i], label=iris.target_names[label])# 绘制决策边界plt.contour(xx, yy, Z, colors='k', levels=[-1, 0, 1], linestyles=['--', '-', '--'])# 图像设置plt.title('Iris Dataset with SVM Decision Boundary')plt.xlabel('Sepal Length (cm)')plt.ylabel('Sepal Width (cm)')plt.legend()plt.show()# 绘制决策边界
plot_decision_boundary(svm, X, y)

二、 核支持向量机

1.1 概念

核SVM利用核函数(Kernel Function)将输入数据映射到一个更高维的空间,在这个高维空间中,原本非线性可分的数据变得线性可分。

同样的,我给出一个用iris进行SVM分类后的图像,如下图:(其代码随后给出)

1.2 数学模型

我们来看核SVM的数学模型,其基本形式与线性的十分相似,我们令Φ(x)来表示将x映射后的特征向量,于是之前的模型就发生了改变,便成为:f(x) = w^T\phi (x)+b的形式。然后其对偶问题也就变为:

最后经过一些重写、化简等就变为:

f(x)=w^T\phi (x)+b \\=\sum_{i=1}^{m} \alpha i yi\phi (x)+b\\=\sum_{i=1}^{m}\alpha i yi\kappa (x,xi)+b

而这里的函数κ()就是“核函数”(kernal function)。

而关于核函数其实存在多种选择,因为我自己也对其不够了解,所以只在此给出西瓜书上的常用核函数表,如下:

1.3 联系

在我们初步了解二者的概念后,我们就可以知道,其实KSVM(核SVM)就是线性SVM在原本处理不了的非线性数据上做出的一个拓展,旨在增加维度而能实现让SVM进行分类。

1.4 区别

适用范围:在线性SVM中,它适用于处理线性可分的数据集,即可以通过一个超平面(在二维空间中是一条直线,在高维空间中是一个超平面)来分隔不同类别的数据点;而KSVM中,它适用于处理非线性可分的数据集,即数据不能通过一个简单的超平面来分隔。在这种情况下,数据可能需要被映射到一个更高维的空间,才能找到一个合适的分隔超平面。

计算复杂度:线性SVM的复杂度相对较低,而KSVM因为核函数的缘故,计算复杂度较高。

实际应用:在线性可分数据集上,线性SVM通常比KSVM更快并且更简单。例如,在文本分类或一些简单的图像识别任务中,数据可能是线性可分的;在非线性可分数据集上,KSVM能够更好地捕捉数据中的复杂关系。例如,在手写数字识别、生物信息学等领域,数据通常是非线性可分的,KSVM能够提供更高的准确率。

1.5 python代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.svm import SVC
from mpl_toolkits.mplot3d import Axes3D# 加载Iris数据集
iris = datasets.load_iris()
X = iris.data[:, :3]  # 使用前三个特征
y = iris.target
# 使用线性核的支持向量机
svm = SVC(kernel='linear')
svm.fit(X, y)
# 创建3D图形
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')  # 使用add_subplot代替Axes3D
ax.view_init(elev=-152, azim=-26)  # 设置视角
# 掩码
mask_0 = y == 0
mask_1 = y == 1
mask_2 = y == 2
# 绘制散点图
ax.scatter(X[mask_0, 0], X[mask_0, 1], X[mask_0, 2], c='b', s=60, label="Setosa")
ax.scatter(X[mask_1, 0], X[mask_1, 1], X[mask_1, 2], c='r', marker='^', s=60, label="Versicolour")
ax.scatter(X[mask_2, 0], X[mask_2, 1], X[mask_2, 2], c='g', marker='s', s=60, label="Virginica")
# 设置坐标轴标签
ax.set_xlabel("Sepal length")
ax.set_ylabel("Sepal width")
ax.set_zlabel("Petal length")
# 添加图例
ax.legend()
# 绘制决策平面
w = svm.coef_[0]
a = -w[0] / w[2]
b = -w[1] / w[2]
xx, yy = np.meshgrid(np.linspace(X[:, 0].min(), X[:, 0].max(), 50),np.linspace(X[:, 1].min(), X[:, 1].max(), 50))
zz = (-svm.intercept_[0] - a * xx - b * yy) / w[2]# 画出平面
surf = ax.plot_surface(xx, yy, zz, rstride=1, cstride=1, color='none',alpha=0.3, edgecolor='darkblue')
# 显示图形
plt.show()

三、 补足

此外,我们会发现在分类时偶尔会有些数据点分类错误或是在间隔内,那么我们就可以称它为“软间隔”,那么我可以在这里完整描述下关于软间隔的含义:它适用于不完全线性可分的数据集,允许一定的误差。并通过调整C来控制惩罚程度,以达到最好的泛化能力。而于此相对的,硬间隔的含义就是:适用于 完全线性可分的数据集,不允许任何训练样本出现在间隔内或是被错误地分类。

因为在现实中大多不能做到硬间隔的分类,所以我们我们需要软间隔,更需要关于它而对原有的SVM模型进行修改,比如加入损失函数,引入松弛变量等,这样就能得到常说的“软间隔SVM”。

SVM处了能处理分类问题还能进行回归,这样就是“支持向量回归”了,即Support Vector Regression。

关于SVM的东西还有很多,我将在之后继续介绍。

此上


http://www.ppmy.cn/server/121193.html

相关文章

李沐 模型选择、过拟合和欠拟合相关代码【动手学深度学习v2】

多项式回归 生成数据集 给定x,我们将使用以下三阶多项式来生成训练和测试数据的标签: y=5+1.2x−3.4+5.6+ϵ where ϵ∼( ). 噪声项ϵ服从均值为0且标准差为0.1的正态分布。 在优化

R18 NES 之SSB-less SCell operation for inter-band CA

在TR 21.918 Summary of Rel-18 Work Items 中可以看到SSB-less SCell operation for inter-band CA 是Network energy savings for NR 的一部分,其中还包括cell DTX/DRX 等等其他内容。 网络节能是 5G/NR 成功的关键,可以减少对环境的影响(温室气体排放)并节省运营成本。R…

后端常用的mybatis-plus方法以及配合querywapper使用

目录 一、插入数据 save方法 二、删除操作 removeById方法 三、更新操作 updateById方法 四、查询操作 selectById方法 五、条件构造器QueryWrapper的更多用法 1.比较操作符 2.逻辑操作符 3.模糊查询 4.空值判断 一、插入数据 save方法 save(T entity):向数据库中插入…

Java项目实战II基于Java+Spring Boot+MySQL的大型商场应急预案管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、论文参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在快节奏的…

【Redis】Linux下安装配置及通过C++访问Redis

文章目录 一、Linux Centos 7.0版本下的安装及配置二、通过C访问Redis 一、Linux Centos 7.0版本下的安装及配置 通过源来安装,此次安装的版本为 redis 5.0 的,要通过其他源进行安装,首先安装 scl 源 yum install centos-release-scl-rh再安…

系统架构设计师:系统架构设计

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师:系统架构设计前言软件架构设计与生命周期SA 实现阶段主要关注的内容A…

基于量子通讯进行安全认证

8月16日,中国银行的一项发明专利“安全认证方法、装置、电子设备及计算机存储介质”授权公告。其申请于2022年6月29日,公布于2022年9月20日。据悉,该发明中应用了量子通讯/量子随机数相关技术。 事实上,近年来,有多家银行探索研究量子技术。在多家银行的2024半年报中,就…

SVN泄露 CTFHUB 解题笔记

参考大佬链接CTFHub | SVN泄露_ctfhubsvn泄露-CSDN博客 先下载插件 然后把GIT;里面的代码 乱盘上去 python2 不知道需不需要 先装了 再说。。。我的是裸机~ 开始作妖模式 Ubuntu 22.10 | Installati.one 上面一行的代码 链接 下面 插件 GITHUB页面下面的代码 d…