机器学习——支持向量机(SVM)

机器学习——支持向量机(SVM)

文章目录

  • 前言
  • 一、SVM算法原理
    • 1.1. SVM介绍
    • 1.2. 核函数(Kernel)介绍
    • 1.3. 算法和核函数的选择
    • 1.4. 算法步骤
    • 1.5. 分类和回归的选择
  • 二、代码实现(SVM)
    • 1. SVR(回归)
    • 2. 回归结果可视化
    • 3. SVC(分类)
    • 3. 分类结果可视化
    • 4. 非线性分类
  • 总结


前言

支持向量机(SVM)是一种常见的机器学习方法,常用于分类(线性和非线性分类问题),回归问题。本文将详细介绍一下支持向量机算法


在这里插入图片描述

一、SVM算法原理

1.1. SVM介绍

支持向量机(Support Vector Machine,SVM)是一种常用的机器学习算法,SVM可以用于线性和非线性分类问题,回归以及异常值检测
其基本原理是通过在特征空间中找到一个超平面,将不同类别的样本分开,并且使得离超平面最近的样本点到超平面的距离最大化

以一个二维平面为例,判定边界是一个超平面(在本图中其实是一条线,但是可以将它想象为一个平面乃至更高维形式在二维平面的映射),它是由支持向量所确定的(支持向量是离判定边界最近的样本点,它们决定了判定边界的位置)。
间隔的正中就是判定边界,间隔距离体现了两类数据的差异大小

在这里插入图片描述

若严格地规定所有的样本点都不在“缓冲区”,都正确的在两边,称为硬间隔分类; 但是在一般情况下,不易实现,这里有两个问题:
第一,它只对线性可分的数据起作用。第二,有异常值的干扰。

为了避免这些问题,可使用软间隔分类
在保持“缓冲区”尽可能大和避免间隔违规之间找到一个良好的平衡,在sklearn中的SVM类,可以使用超参数 C(惩罚系数),控制了模型的复杂度和容错能力。较小的C值会导致容错能力较高(即更宽的缓冲区),可能会产生更多的错误分类(即间隔违规);较大的C值会导致容错能力较低,可能会产生更少的错误分类。

在这里插入图片描述

1.2. 核函数(Kernel)介绍

为什么要引入核函数呢? 因为在SVM中,有时候很难找出一条线或一个超平面来分割数据集,这时候我们就需要升维(把无法线性分割的样本映射到高纬度空间,在高维空间实现分割)

核函数是特征转换函数,它可以将数据映射到高维特征空间中,从而更好地处理非线性关系。
核函数的作用是通过计算两个样本之间的相似度(内积)来替代显式地进行特征映射,从而避免了高维空间的计算开销。

在SVM中,核函数的选择非常重要,它决定了模型能够学习的函数空间。常见的核函数包括:

  1. 线性核函数(Linear Kernel):最简单的核函数,它在原始特征空间中直接计算内积,适用于线性可分的情况。K(X,y) = (X^T) * y

  2. 多项式核函数(Polynomial Kernel):通过多项式函数将数据映射到高维空间,可以处理一定程度的非线性关系。(可拟合出复杂的分割超平面,但可选参数太多,阶数高后计算困难,不稳定) K(X,y) = ( (X^T) * y + c ) ^ d , 其中 c 为常数,d 为多项式的阶数。

  3. 高斯核函数(Gaussian Kernel):也称为径向基函数(Radial Basis Function,RBF),通过高斯分布将数据映射到无穷维的特征空间,可以处理更复杂的非线性关系。形式为 K(x,y) = exp( -|| x-y || ^2 / (2 σ ^2) ) 。
    || x - y || 表示向量 x 和 y 之间的欧氏距离,即它们各个维度差值的平方和的平方根。
    σ 是高斯核函数的参数,控制了样本之间相似度的衰减速度。σ 越小,样本之间的相似度下降得越快;σ 越大,样本之间的相似度下降得越慢。

  4. sigmoid核函数(Sigmoid Kernel):通过sigmoid函数将数据映射到高维空间,适用于二分类问题。 σ(x) = 1 / (1 + exp(-x))

1.3. 算法和核函数的选择

假设特征数为N,训练数据集的样本个数为W,可按如下规则选择算法:

  1. 若N相对W较大,使用逻辑回归或线性核函数的SVM算法

  2. 若N较小,W中等大小(W为N的十倍左右),可使用高斯核函数的SVM算法

  3. 若N较小,W较大(W为N的五十倍以上),可以使用多项式核函数、高斯核函数的SVM算法

总之 ,数据大的问题,选择复杂一些的模型,反之,选择简单模型。

有关逻辑回归算法的更多信息,请看
机器学习——逻辑回归(LR)

1.4. 算法步骤

SVM算法可以分为以下几个步骤:

  1. 数据预处理:将数据集划分为训练集和测试集,并进行特征缩放(对数据进行标准化)。

  2. 构建模型:选择合适的核函数和惩罚系数,构建SVM模型。

  3. 训练模型:使用训练集对模型进行训练,通过最大化间隔来找到最优的超平面。

  4. 预测:使用训练好的模型对测试集进行预测。

1.5. 分类和回归的选择

通常情况下,当标签值是离散型变量时,我们将问题视为分类问题,而当标签值是连续性变量时,我们将问题视为回归问题。

在支持向量机(SVM)算法中,SVC用于分类,SVR用来做回归

  1. 在分类问题中,我们的目标是将输入数据分为不同的离散类别。常见的分类算法包括逻辑回归、决策树、随机森林和支持向量机等。

  2. 在回归问题中,我们的目标是预测连续性变量的值。回归问题涉及到对输入数据进行建模,以预测一个或多个连续的输出变量。常见的回归算法包括线性回归、决策树回归、支持向量回归和神经网络等。

二、代码实现(SVM)

1. SVR(回归)

使用波士顿房价数据集,其标签值是一个连续型变量,故用SVR来做回归问题

波士顿房价数据集介绍:
在这里插入图片描述

#加载波士顿房价数据集
from sklearn.datasets import load_boston
boston = load_boston()
x = boston.data
y = boston.target#数据的划分
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x,y,random_state=42)#标准化
from sklearn import preprocessing
scaler = preprocessing.StandardScaler().fit(x_train)
#保证train数据与test数据是在统一的距离标准下进行的标准化
x_train = scaler.transform(x_train)
x_test = scaler.transform(x_test)#SVM构建
from sklearn.svm import SVR
#使用多项式核函数
model = SVR(kernel= "poly",degree= 3 ,C=5)
model.fit(x_train,y_train)
#检查得分
print(model.score(x_test,y_test))
# print(model.predict(x_test))#使用高斯核函数
model2 = SVR(kernel="rbf",gamma=0.01,C=5)
# print(model2)
model2.fit(x_train,y_train)
print(model2.score(x_test,y_test))#使用sigmoid核函数
model = SVR(kernel= "sigmoid",gamma=0.01 ,C=5)
model.fit(x_train,y_train)
#检查得分
print(model.score(x_test,y_test))
# print(model.predict(x_test))#使用网格搜索
import numpy as np
from sklearn.model_selection import GridSearchCV
params = {"kernel": ["rbf","sigmoid","poly","linear"],"C": np.arange(1,6),"gamma": np.arange(0,0.5,0.001),"degree":np.arange(1,5)
}
grid_searchcv = GridSearchCV(SVR(),param_grid= params,cv= 5)
grid_searchcv.fit(x_train,y_train)
print(grid_searchcv.best_params_)
print(grid_searchcv.best_score_)
#print(grid_searchcv.cv_results_)
print(grid_searchcv.best_index_)
print(grid_searchcv.best_estimator_)
best_clf = grid_searchcv.best_estimator_
best_clf.fit(x_train,y_train)
print(best_clf.score(x_test,y_test))#结果
{'C': 5, 'degree': 1, 'gamma': 0.058, 'kernel': 'rbf'}
0.7854834638941114
24232
SVR(C=5, degree=1, gamma=0.058)
0.7698971297133513

2. 回归结果可视化

from sklearn.svm import SVR
best_clf = SVR(kernel= "rbf",degree= 1 ,C=5,gamma=0.058)
best_clf.fit(x_train,y_train)import matplotlib.pyplot as plt
# 使用最佳模型进行预测
y_pred = best_clf.predict(x_test)# 绘制预测值与真实值之间的散点图
plt.scatter(y_test, y_pred)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'k--', lw=2)
plt.xlabel('True Values')
plt.ylabel('Predicted Values')
plt.title('SVM Regression - True Values vs Predicted Values')
plt.show()

在这里插入图片描述

在图中,如果点分布在对角线附近,则表示预测值与真实值较为接近,说明模型的回归效果较好。反之则不好

3. SVC(分类)

使用鸢尾花数据集,因为其标签值为离散型变量,故用SVC来做分类问题

#加载iris数据集
from sklearn.datasets import load_iris
iris = load_iris()
x = iris.data
y = iris.target#数据的划分
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x,y,random_state=42)#标准化
from sklearn import preprocessing
scaler = preprocessing.StandardScaler().fit(x_train)
#保证train数据与test数据是在统一的距离标准下进行的标准化
x_train = scaler.transform(x_train)
x_test = scaler.transform(x_test)#使用网格搜索
from sklearn.svm import SVC
import numpy as np
from sklearn.model_selection import GridSearchCV
params = {"kernel": ["rbf","sigmoid","poly","linear"],"C": np.arange(1,6),"gamma": np.arange(0,0.5,0.001),"degree":np.arange(1,4)
}
grid_searchcv = GridSearchCV(SVC(),param_grid= params,cv= 5)
grid_searchcv.fit(x_train,y_train)
print(grid_searchcv.best_params_)
print(grid_searchcv.best_score_)
print(grid_searchcv.best_index_)
print(grid_searchcv.best_estimator_)
best_clf = grid_searchcv.best_estimator_
best_clf.fit(x_train,y_train)
print(best_clf.score(x_test,y_test))
print(best_clf.predict(x_test))#结果
{'C': 1, 'degree': 1, 'gamma': 0.133, 'kernel': 'poly'}
0.9640316205533598
534
SVC(C=1, degree=1, gamma=0.133, kernel='poly')
1.0
[1 0 2 1 1 0 1 2 1 1 2 0 0 0 0 1 2 1 1 2 0 2 0 2 2 2 2 2 0 0 0 0 1 0 0 2 10]

3. 分类结果可视化

因为鸢尾花数据集有四个特征,所以为了方便可视化,要将数据集进行降维

# 使用PCA进行降维
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
x_pca = pca.fit_transform(x)
#数据的划分
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x_pca,y,random_state=42)#标准化
from sklearn import preprocessing
scaler = preprocessing.StandardScaler().fit(x_train)
#保证train数据与test数据是在统一的距离标准下进行的标准化
x_train = scaler.transform(x_train)
x_test = scaler.transform(x_test)import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
best_clf = SVC(degree= 1,C= 1,gamma= 0.133,kernel="poly")
best_clf.fit(x_train,y_train)
# 使用最佳模型进行预测
y_pred = best_clf.predict(x_test)# 绘制散点图
sc = plt.scatter(x_test[:, 0], x_test[:, 1], c=y_pred)
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.title('SVM Classification - Predicted Classes')
handles, labels = sc.legend_elements()
plt.legend(handles, labels)
plt.show()# 绘制决策边界图
h = 0.02  # 步长
x_min, x_max = x_test[:, 0].min() - 1, x_test[:, 0].max() + 1
y_min, y_max = x_test[:, 1].min() - 1, x_test[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = best_clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.8)
plt.scatter(x_test[:, 0], x_test[:, 1], c=y_pred)
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.title('SVM Classification - Decision Boundary')
plt.show()

在这里插入图片描述

在这里插入图片描述

4. 非线性分类

from sklearn.datasets import make_moons
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
plt.style.use("ggplot")
# 生成非线性分类数据
X, y = make_moons(n_samples=200, noise=0.05,random_state=41)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 创建SVM模型并指定核函数
svm = SVC(kernel='rbf', random_state=42)
svm.fit(X_train, y_train)
y_pred = svm.predict(X_test)# 计算分类准确率
accuracy = accuracy_score(y_test, y_pred)
# print( accuracy)# 绘制分类结果
sc= plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred, cmap='viridis')
plt.xlabel('X1')
plt.ylabel('X2')
plt.title('Nonlinear Classification')
handles,labels =sc.legend_elements()
plt.legend(handles,labels)
plt.show()

在这里插入图片描述

绘制决策边界图

# 绘制决策边界图
def plot_juecebianjie(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() + 1h = 0.02  # 步长# 生成网格点坐标矩阵xx, yy = np.meshgrid(np.arange(x_min, x_max, h),np.arange(y_min, y_max, h))# 使用模型进行预测Z = model.predict(np.c_[xx.ravel(), yy.ravel()])Z = Z.reshape(xx.shape)# 绘制等高线图plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral, alpha=0.6)# 绘制数据点sc= plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)plt.xlabel('X1')plt.ylabel('X2')plt.title('Decision Boundary')handles,labels = sc.legend_elements()plt.legend(handles,labels)plt.show()# 调用函数
plot_juecebianjie(svm, X_test, y_pred)

在这里插入图片描述


总结

本文在SVM算法原理介绍中:从开始的SVM介绍,到Kernel的介绍,再到算法和核函数的选择,之后就是算法的步骤,以及分类和回归的选择;在代码实现中:亦是分别对SVM中的回归(SVR)和分类(SVC)用代码实现,并可视化结果。

关关雎鸠,在河之洲

–2023-9-4 筑基篇

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【矩阵分解】PCA - 主成分分析中的数学原理

前言 本文主要对PCA主成分分析中的数学原理进行介绍,将不涉及或很少涉及代码实现或应用,阅读前请确保已了解基本的机器学习相关知识。 文章概述 PCA主成分分析属于矩阵分解算法中的入门算法,通过分解特征矩阵来实现降维。 本文主要内容&a…

硬件学习件Cadence day13 PCB设计中一些设置, 铜皮到钻孔的距离设置, 差分线的设置,板层信息表

1. 设置铺铜中铜皮到钻口,连线的距离。 1. 打开设置界面 2. 设计界面 调整到 铜皮设置界面 2. 高速线的设置 (差分对传输线的设置) 1. 打开设置界面 2. 来到 差分线设置界面 3. 把界面往右看, 设置差分线的之间距离,…

(二十四)大数据实战——Flume数据流监控之Ganglia的安装与部署

前言 本节内容我们主要介绍一下Flume数据流的监控工具Ganglia。Ganglia是一个开源的分布式系统性能监控工具。它被设计用于监视大规模的计算机群集(包括集群、网格和云环境),以便收集和展示系统和应用程序的性能数据。Ganglia 可以轻松地扩展…

【多线程】线程安全 问题

线程安全 问题 一. 线程不安全的典型例子二. 线程安全的概念三. 线程不安全的原因1. 线程调度的抢占式执行2. 修改共享数据3. 原子性4. 内存可见性5. 指令重排序 一. 线程不安全的典型例子 class ThreadDemo {static class Counter {public int count 0;void increase() {cou…

3D点云测量:计算三个平面的交点

文章目录 0. 测试效果1. 基本内容文章目录:3D视觉测量目录0. 测试效果 1. 基本内容 计算三个平面的交点需要找到满足所有三个平面方程的点。三个平面通常由它们的法向量和通过它们的点(或参数形式的方程)来定义。以下是计算三个平面的交点的一般步骤: 假设有三个平面,分别…

MyBatis-Plus排除不必要的字段

查询学生信息排除年龄列表 📚🔍 使用MyBatis-Plus排除某些字段。如果你想要进行查询,但又不需要包含某些字段,那么这个功能将非常适合你。🔍🎓📝 1. 学生信息查询-排除年龄列表 在使用 MyBat…

【Cisco Packet Tracer】管理方式,命令,接口trunk,VLAN

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …

【Redis】为什么要学 Redis

文章目录 前言一、Redis 为什么快二、Redis 的特性2.1 将数据储存到内存中2.2 可编程性2.3 可扩展性2.4 持久性2.5 支持集群2.6 高可用性 三、Redis 的应用场景四、不能使用 Redis 的场景 前言 关于为什么要学 Redis 这个问题,一个字就可以回答,那就是&…

Vue3+Ts+Vite项目(第一篇)——使用Vite创建Vue3项目

概述 保姆级详解,带你使用 Vite 创建 Vue3 项目,全程cv即可 文章目录 概述一、 安装 Vite二、 创建项目2.1 运行上述命令后,会让我们输入项目名称。可以写一个 vue3-study2.2 选择项目模板,此处选择 Vue,然后回车确定…

mysql课堂笔记 mac

目录 启动mac上的mysql 进入mysql mac windows 创建数据库 创建表 修改字段数据类型 修改字段名 增加字段 删除字段 启动mac上的mysql sudo /usr/local/mysql/support-files/mysql.server start 直接输入你的开机密码即可。 编辑 进入mysql mac sudo /usr/local…

深入浅出AXI协议(6)——传输属性

一、前言 在之前的文章中,我们介绍的主要内容是AXI协议的数据读写结构和读写响应结构,主要讲述了当遇到各种特殊情况时,AXI如何完成数据的读写操作,最后介绍了读写响应的4种类型。 在本文中,我们将介绍AXI协议的传输属性。 二、传…

【C++】day3学习成果:类

1.自行封装一个栈的类,包含私有成员属性:栈的数组、记录栈顶的变量 成员函数完成:构造函数、析构函数、拷贝构造函数、入栈、出栈、清空栈、判空、判满、获取栈顶元素、求栈的大小 头文件stack.h: #ifndef STACK_H #define STACK_H#include …

Linux常见指令

目录 前言 一、Linux下的基本指令 01. ls 指令 02. pwd 指令 03. cd 指令 04. touch 指令 05. mkdir 指令(重要) 06. rmdir 指令 && rm 指令(重要) 07. man 指令(重要) extra nano 08. cp 指…

并发聊天服务器编写

并发聊天服务器 package mainimport ("fmt""net""strings""time" )// 结构体 type Client struct {C chan string //用户发送数据的管道Name string //用户名Addr string //网络地址 }// 保存在线用户 cliAddr -->cli…

UNIX网络编程卷一 学习笔记 第三十一章 流

在大多数源自SVR 4的内核中,X/Open传输接口(X/Open Transport Interface,XTI,是独立于套接字API的另一个网络编程API)和网络协议通常就像终端IO系统那样也使用流系统(STREAMS system)实现。 我…

Selenium 隐藏浏览器指纹特征的几种方式

我们使用 Selenium 对网页进行爬虫时,如果不做任何处理直接进行爬取,会导致很多特征是暴露的 对一些做了反爬的网站,做了特征检测,用来阻止一些恶意爬虫 本篇文章将介绍几种常用的隐藏浏览器指纹特征的方式 1. 直接爬取 目标对…

基于微服务+Java+Spring Cloud +UniApp +MySql开发的智慧工地源码(物联网、人工智能、AI识别、危大工程)

智慧工地系统利用物联网、人工智能、云计算、大数据、移动互联网等新一代信息技术,通过工地中台、三维建模服务、视频AI分析服务等技术支撑,实现智慧工地高精度动态仿真,趋势分析、预测、模拟,建设智能化、标准化的智慧工地综合业…

vue3+ts项目打包后的本地访问

注意:打包之后不可直接点击html访问,需要给项目安装本地服务! 1、安装servenpm i -g serve 2、打包项目npm run build 生成dist文件夹 3、本地访问serve dist 运行service dist之后的控制台 可复制下方的地址运行打包后的项目,运行…

强大的JTAG边界扫描(5):FPGA边界扫描应用

文章目录 1. 获取芯片的BSDL文件2. 硬件连接3. 边界扫描测试4. 总结 上一篇文章,介绍了基于STM32F103的JTAG边界扫描应用,演示了TopJTAG Probe软件的应用,以及边界扫描的基本功能。本文介绍基于Xilinx FPGA的边界扫描应用,两者几乎…

opencv识别一张图片的多个红框,并截取红框的内容

需求 需要获取图片的红框的内容,实体的图片我就不放了 获取红框 先截取获得图片的多个轮廓 import cv2 import numpy as np # 加载图像并转换为灰度图像 image cv2.imread(image6.jpg) gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 应用高斯模糊以减…