支持向量机 (SVM):初学者指南

照片由 Unsplash上的 vackground.com提供

一、说明

        SVM(支持向量机)简单而优雅用于分类和回归的监督机器学习方法。该算法试图找到一个超平面,将数据分为不同的类,并具有尽可能最大的边距。本篇我们将介绍如果最大边距不存在的时候,如何创造最大边距。

二、让我们逐步了解 SVM 

        假设我们有一维湿度数据,红点代表不下雨的日子,蓝点代表下雨的日子。

虚拟一维分类数据。图片由作者提供。

      

        根据我们拥有的一维观测数据,我们可以确定阈值。该阈值将充当分类器。由于我们的数据是一维的,分类器将有一个阈值。如果我们的数据是二维的,我们会使用一条线。

        观察到的数据(最近的数据点)与分类器阈值之间的最短距离称为边距。能够提供最大margin的阈值称为Maximal Margin Classifier (Hyperplane)。在我们的例子中,它将位于双方最接近数据的中点。

最大边际分类器。图片由作者提供。

       

        最大保证金在实践中不太适用。因为它对异常值没有抵抗力。想象一下,我们有一个具有蓝色值的离群红点。在这种情况下,分类器将非常接近蓝点,远离红点。

对异常值敏感。图片由作者提供。

为了改善这一点,我们应该允许异常值和错误分类。我们在系统中引入偏差(并减少方差)。现在,边距称为软边距。使用软间隔的分类器称为支持向量分类器或软间隔分类器。边缘上和软边缘内的数据点称为支持向量。

支持向量。图片由作者提供。

        我们使用交叉验证来确定软边距应该在哪里。

        在 2D 数据中,支持向量分类器是一条线。在 3D 中,它是一个平面。在 4 个或更多维度中,支持向量分类器是一个超平面。从技术上讲,所有 SVC 都是超平面,但在 2D 情况下更容易将它们称为平面。

2D 和 3D。资料来源: https: 

//www.analyticsvidhya.com/blog/2021/05/support-vector-machines/和https://www.sciencedirect.com/topics/computer-science/support-vector-machine

        正如我们在上面看到的,支持向量分类器可以处理异常值并允许错误分类。但是,我们如何处理如下所示的重叠数据呢?

数据重叠。图片由作者提供。

        这就是支持向量机发挥作用的地方。让我们为问题添加另一个维度。我们有特征 X,作为新的维度,我们取 X 的平方并将其绘制在 y 轴上。

由于现在的数据是二维的,我们可以画一条支持向量分类器线。

将问题二维化。图片由作者提供。

        支持向量机获取低维数据,将其移至更高维度,并找到支持向量分类器。

        与我们上面所做的类似,支持向量机使用核函数来查找更高维度的支持向量分类器。核函数是一种函数,它采用原始输入空间中的两个输入数据点,并计算变换后(高维)特征空间中它们对应的特征向量的内积。

内部产品。图片由作者提供。

        核函数允许 SVM 在变换后的特征空间中运行,而无需显式计算变换后的特征向量,这对于大型数据集或复杂的变换来说计算成本可能很高。相反,核函数直接在原始输入空间中计算特征向量之间的内积。这称为内核技巧

三、多项式核

        多项式核用于将输入数据从低维空间变换到高维空间,在高维空间中使用线性决策边界更容易分离类。

        多项式核。

        a和b是两个不同的观测值,r是多项式系数,d是多项式的次数。假设d为 2,r为 1/2。

数学。

        我们最终得到一个点积。第一项(ab)是 x 轴,第二项()是 y 轴。因此,我们需要做的就是计算每对点之间的点积。例如更高维度中两点之间的关系;a = 9,b = 14 => (9 x 114 + 1/2)² = 16000,25。

四、径向内核 (RBF)

        径向核在无限维度中查找支持向量分类器。

        它为距离测试点较近的点分配较高的权重,为较远的点(如最近的邻居)分配较低的权重。较远的观察对数据点的分类影响相对较小。

内核函数。

        它计算两个数据之间的平方距离。Gamma 由交叉验证确定,它会缩放平方距离,这意味着它会缩放两个点彼此之间的影响。在此公式中,随着两点之间的距离增加,该值将接近于零。

        当类之间的决策边界是非线性且复杂的时,径向核特别有用,因为它可以捕获输入特征之间的复杂关系。

五、Python实现

        我们可以使用支持向量机sklearn.

from sklearn.svm import SVC

具有不同内核的 SVC。来源

SVC接受一些参数:

  • C是正则化参数。较大的值会使模型在训练数据上犯更多错误(错误分类)。因此,它的目的是有一个更好的概括。默认值为 1。
  • kernel设置核函数。默认为rbf。其他选择是:Linearpolysigmoidprecompulated。此外,您还可以传递自己的内核函数。
  • degree指定多项式核的次数。仅当内核是多项式时它才可用。默认值为 3。
  • gamma控制核函数的形状。它可用于rbfpolysigmoid内核,较小的 gamma 值使决策边界更平滑,较大的值使决策边界更复杂。默认值是比例,等于 1 / (n_features x X.var())。auto是 1 / n_features。或者您可以传递一个浮点值。
  • coef0仅用于 poly 和 sigmoid 内核。它控制多项式核函数中高阶项的影响。默认值为 0。
  • shrinking控制是否使用收缩启发式。这是一个加速启发式过程。
  • tol是停止标准的容差。当目标函数的变化小于tol时,优化过程将停止。
  • class_weight平衡分类问题中类别的权重。可以将其设置为平衡,以根据课程频率自动调整权重。默认值为“无”。
  • max_iter是迭代极限。-1 表示无限制(默认)。
  • probability指定是否启用概率估计。当它设置为 True 时,估计器将估计类概率,而不仅仅是返回预测的类标签。当probability设置为 True 时,可以使用predict_proba该类的方法来获取新数据点的类标签的估计概率。SVC
  • cache_size用于设置SVM算法使用的内核缓存的大小。当训练样本数量非常大或者内核计算成本很高时,内核缓存会很有用。通过将核评估存储在缓存中,SVM 算法可以在计算正则化参数 C 的不同值的决策函数时重用结果。

SVC 使用具有不同参数的 RBF 内核。来源

一个简单的实现:

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC# cancer data
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, random_state=42)# parameters
params = {'C': 1.0, 'kernel': 'rbf', 'gamma': 'scale', 
'probability': False, 'cache_size': 200}# training
svc = SVC(**params)
svc.fit(X_train, y_train)# we can use svc's own score function
score = svc.score(X_test, y_test)
print("Accuracy on test set: {:.2f}".format(score))
#Accuracy on test set: 0.95

六、回归

        我们也可以在回归问题中使用支持向量机。

from sklearn.svm import SVR

  • epsilon是指定回归线周围容差大小的参数。回归线由 SVR 算法确定,使其在一定的误差范围内拟合训练数据,该误差范围由参数定义epsilon
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error# the California Housing dataset
california = fetch_california_housing()
X_train, X_test, y_train, y_test = train_test_split(california.data, california.target, random_state=42)# training
svr = SVR(kernel='rbf', C=1.0, epsilon=0.1)
svr.fit(X_train, y_train)# Evaluate the model on the testing data
y_pred = svr.predict(X_test)
mse = mean_squared_error(y_test, y_pred)print("MSE on test set: {:.2f}".format(mse))
#MSE on test set: 1.35

        我们还可以使用 来绘制边界matplotlib

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.svm import SVC# Load the Iris dataset
iris = load_iris()# Extract the first two features (sepal length and sepal width)
X = iris.data[:, :2]
y = iris.target# Create an SVM classifier
svm = SVC(kernel='linear', C=1.0)
svm.fit(X, y)# Create a mesh of points to plot in
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),np.arange(y_min, y_max, 0.02))# Plot the decision boundary
Z = svm.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)# Plot the training points
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.xticks(())
plt.yticks(())
plt.title('SVM decision boundary for Iris dataset')plt.show()

边界。图片由作者提供。

SVM 是一种相对较慢的方法。

import time
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split# Load the breast cancer dataset
data = load_breast_cancer()
X, y = data.data, data.target# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)# Fit a logistic regression model and time it
start_time = time.time()
lr = LogisticRegression(max_iter=1000)
lr.fit(X_train, y_train)
end_time = time.time()
lr_runtime = end_time - start_time# Fit an SVM model and time it
start_time = time.time()
svm = SVC(kernel='linear', C=1.0)
svm.fit(X_train, y_train)
end_time = time.time()
svm_runtime = end_time - start_time# Print the runtimes
print("Logistic regression runtime: {:.3f} seconds".format(lr_runtime))
print("SVM runtime: {:.3f} seconds".format(svm_runtime))"""
Logistic regression runtime: 0.112 seconds
SVM runtime: 0.547 seconds
"""

支持向量机 (SVM) 可能会很慢,原因如下:

  • SVM 是计算密集型的:SVM 涉及解决凸优化问题,对于具有许多特征的大型数据集来说,计算成本可能很高。SVM 的时间复杂度通常至少为 O(n²),其中 n 是数据点的数量,对于非线性内核来说,时间复杂度可能要高得多。
  • 用于调整超参数的交叉验证:SVM需要调整超参数,例如正则化参数C和核超参数,这涉及使用交叉验证来评估不同的超参数设置。这可能非常耗时,尤其是对于大型数据集或复杂模型。
  • 大量支持向量:对于非线性SVM,支持向量的数量会随着数据集的大小或模型的复杂性而快速增加。这可能会减慢预测时间,尤其是在模型需要频繁重新训练的情况下。

我们可以通过尝试以下一些方法来加速 SVM:

  • 使用线性核:线性 SVM 的训练速度比非线性 SVM 更快,因为优化问题更简单。如果您的数据是线性可分的或者不需要高度复杂的模型,请考虑使用线性核。
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC, LinearSVC
import time# Load MNIST digits dataset
mnist = fetch_openml('mnist_784', version=1)
data, target = mnist['data'], mnist['target']
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=42)# Train linear SVM
start_time = time.time()
linear_svc = LinearSVC()
linear_svc.fit(X_train, y_train)
linear_train_time = time.time() - start_time# Train non-linear SVM with RBF kernel
start_time = time.time()
rbf_svc = SVC(kernel='rbf')
rbf_svc.fit(X_train, y_train)
rbf_train_time = time.time() - start_timeprint('Linear SVM training time:', linear_train_time)
print('Non-linear SVM training time:', rbf_train_time)"""
Linear SVM training time: 109.03955698013306
Non-linear SVM training time: 165.98812198638916
"""
  • 使用较小的数据集:如果您的数据集非常大,请考虑使用较小的数据子集进行训练。您可以使用随机抽样或分层抽样等技术来确保子集代表完整数据集。
  • 使用特征选择:如果您的数据集具有许多特征,请考虑使用特征选择技术来减少特征数量。这可以降低问题的维度并加快训练速度。
  • 使用较小的值C:正则化参数C控制最大化边际和最小化分类误差之间的权衡。较小的值C可以产生具有较少支持向量的更简单的模型,这可以加速训练和预测。
import time
from sklearn.datasets import load_breast_cancer
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split# Load the breast cancer dataset
data = load_breast_cancer()
X, y = data.data, data.target# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)for C in [0.1, 1, 10]:start_time = time.time()svm = SVC(kernel='linear', C=C, random_state=42)svm.fit(X_train, y_train)train_time = time.time() - start_timeprint('Training time with C={}: {:.2f}s'.format(C, train_time))"""
Training time with C=0.1: 0.08s
Training time with C=1: 0.55s
Training time with C=10: 0.90s
"""
  • 使用缓存:SVM 涉及计算数据点对之间的内积,这可能会导致计算成本高昂。Scikit-learn 的 SVM 实现包括一个缓存,用于存储常用数据点的内积值,这可以加快训练和预测速度。您可以使用参数调整缓存的大小cache_size
from sklearn.datasets import load_breast_cancer
from sklearn.svm import SVC
import time# Load the dataset
X, y = load_breast_cancer(return_X_y=True)# Train the model without a cache
start_time = time.time()
clf = SVC(kernel='linear', cache_size=1).fit(X, y)
end_time = time.time()
print(f"Training time without cache: {end_time - start_time:.3f} seconds")# Train the model with a cache of 200 MB
start_time = time.time()
clf_cache = SVC(kernel='linear', cache_size=200, max_iter=10000).fit(X, y)
end_time = time.time()
print(f"Training time with cache: {end_time - start_time:.3f} seconds")"""
Training time without cache: 0.535 seconds
Training time with cache: 0.014 seconds
"""

七、结论

        一般来说,SVM 适用于特征数量与样本数量相比相对较少且不同类之间有明显分离余量的分类任务。SVM 还可以处理高维数据以及特征和目标变量之间的非线性关系。然而,SVM 可能不适合非常大的数据集,因为它们可能是计算密集型的并且需要大量内存。

参考文章:

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

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

相关文章

Bun 1.0.7 版本发布,实现多个 Node.js 兼容改进

导读Bun 是一个集打包工具、转译器和包管理器于一体的 JavaScript 运行时,由 Jarred Sumner 发布了 1.0.7 版本。本次更新实现了对 Node.js 运行时的多项兼容性改进,并修复了近 60 个 bug。 根据发布说明,本版本对 “bun install” 命令进行…

11.Z-Stack协议栈使用

f8wConfig.cfg文件 选择信道、设置PAN ID 选择信道 #define DEFAULT_CHANLIST 0x00000800 DEFAULT_CHANLIST 表明Zigbee模块要工作的网络,当有多个信道参数值进行或操作之后,把结果作为 DEFAULT_CHANLIST值 对于路由器、终端、协调器的意义&#xff1…

二、Hadoop分布式系统基础架构

1、分布式 分布式体系中,会存在众多服务器,会造成混乱等情况。那如何让众多服务器一起工作,高效且不出现问题呢? 2、调度 (1)架构 在大数据体系中,分布式的调度主要有2类架构模式&#xff1a…

AI:62-基于深度学习的人体CT影像肺癌的识别与分类

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

Docker学习——③

文章目录 1、Docker Registry(镜像仓库)1.1 什么是 Docker Registry?1.2 镜像仓库分类1.3 镜像仓库工作机制1.4 常用的镜像仓库 2、镜像仓库命令3、镜像命令[部分]4、容器命令[部分]4.1 docker run4.2 docker ps 5、CentOS 搭建一个 nginx 服…

selenium自动化测试入门 —— python unittest单元测试框架

unittest又名PyUnit, Python单元测试框架(The Python unit testing framework),简称为PyUnit。自从 Python 2.1 版本后,PyUnit成为 Python标准库的一部分。 为什么需要使用unittest单元测试框架? 当我们写…

CC1101 一款低功耗sub- 1ghz收发器芯片 适用于无线遥控智能家居

产品描述 CC1101是一个低成本的sub- 1ghz收发器,专为极低功耗的无线应用而设计。 该电路主要用于工业、科学和医学)和SRD (Short Range Device)频带,在315,433,868和915兆赫,但可以轻松可编程用于其他操作频率在300-348 MHz、387-464 MHz,以及779-928 MHz频段。射…

数据抽取+dataworks的使用+ADB的应用

一,大数据处理之数据抽取 1,什么是数据抽取 在大数据领域中,数据抽取是指从原始数据源中提取所需的数据子集或特定数据项的过程, 数据抽取是数据预处理的重要步骤,它为后续的数据分析和建模提供了基础。 2&#xff…

暴力递归转动态规划(十三)

题目 给定3个参数,N,M,K 怪兽有N滴血,等着英雄来砍自己 英雄每一次打击,都会让怪兽流失[0~M]的血量 到底流失多少?每一次在[0~M]上等概率的获得一个值 求K次打击之后,英雄把怪兽砍死的概率。 暴…

数据结构:Map和Set(1)

搜索树 概念 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树 这棵树的中序遍历结果是有序的 接下来我们来模拟一棵二叉搜索树&#xff0c…

AD9371 官方例程裸机SW 和 HDL配置概述(二)

AD9371 系列快速入口 AD9371ZCU102 移植到 ZCU106 : AD9371 官方例程构建及单音信号收发 ad9371_tx_jesd -->util_ad9371_xcvr接口映射: AD9371 官方例程之 tx_jesd 与 xcvr接口映射 AD9371 官方例程 时钟间的关系与生成 : AD9371 官方…

Electron[3] 基础配置准备和Electron入门案例

1 背景 上一篇文章已经分享了,如何准备Electron的基础环境了。但是博客刚发才一天,就发现有人问问题了。经过实践发现,严格按照作者的博客教程走是不会有问题的,其中包括安装的环境版本等都要一致。因为昨天发的博客,…

使用Jsoup库编写程序

Jsoup库编写的Kotlin网络爬虫程序 kotlin import org.jsoup.Jsoup import org.jsoup.nodes.Document import org.jsoup.nodes.Element import org.jsoup.select.Elements import java.net.HttpURLConnection import java.net.URL fun main(args: Array<String>) { v…

Zephyr-7B-β :类GPT的高速推理LLM

Zephyr 是一系列语言模型&#xff0c;经过训练可以充当有用的助手。 Zephyr-7B-β 是该系列中的第二个模型&#xff0c;是 Mistralai/Mistral-7B-v0.1 的微调版本&#xff0c;使用直接偏好优化 (DPO) 在公开可用的合成数据集上进行训练 。 我们发现&#xff0c;删除这些数据集的…

BIOS开发笔记 - CMOS

CMOS原来指的是一种生产电子电路的工艺,在PC上一般指的是RTC电路单元,因为早期它是由这种工艺生产出来的,所以又把RTC称作了CMOS。 RTC(Real Time Clock)即实时时钟,用于保存记录时间和日期,也可以用来做定时开机功能。RTC靠一组独立的电源给它供电,这样设计的目的就是…

Win系统强制删除文件/文件夹

Win系统强制删除文件/文件夹 前言系统磁盘清理360强制删除NPM删除 前言 Win系统的用户删除文件/文件夹时&#xff0c;可能由于权限问题导致文件无法正常删除&#xff0c;下文介绍解决方案。当常规的删除不起作用时&#xff0c;可使用如下方案进行删除&#xff0c;包含系统磁盘…

大数据商城人流数据分析与可视化 - python 大数据分析 计算机竞赛

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于大数据的基站数据分析与可视化 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度…

若依分离版——配置多数据源(mysql和oracle),实现一个方法操作多个数据源

目录 一、若依平台配置 二、编写oracle数据库访问的各类文件 三. 一个方法操作多个数据源 一、若依平台配置 1、在ruoyi-admin的pom.xml添加oracle依赖 <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <v…

JVM 各个参数详解

在一些规模稍大的应用中&#xff0c;Java虚拟机&#xff08;JVM&#xff09;的内存设置尤为重要&#xff0c;想在项目中取得好的效率&#xff0c;GC&#xff08;垃圾回收&#xff09;的设置是第一步。 PermGen space&#xff1a;全称是Permanent Generation space.就是说是永久…

ZZ308 物联网应用与服务赛题第B套

2023年全国职业院校技能大赛 中职组 物联网应用与服务 任 务 书 &#xff08;B卷&#xff09; 赛位号&#xff1a;______________ 竞赛须知 一、注意事项 1.检查硬件设备、电脑设备是否正常。检查竞赛所需的各项设备、软件和竞赛材料等&#xff1b; 2.竞赛任务中所使用的…