支持向量机 (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_time

print('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_time
    print('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 可能不适合非常大的数据集,因为它们可能是计算密集型的并且需要大量内存。

参考文章:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Failed to connect to github.com port 443:connection timed out

解决办法: 步骤1: 在这里插入图片描述 步骤2: -步骤3 :在git终端中执行如下命令: git config --global http.proxy http:ip:port git config --global https.proxy http:ip:port git config --global http.proxy htt…

重磅发布 OpenAI 推出用户自定义版 ChatGPT

文章目录 重磅发布 OpenAI 推出用户自定义版 ChatGPT个人简介 重磅发布 OpenAI 推出用户自定义版 ChatGPT OpenAI 首届开发者大会 (OpenAI DevDay) 于北京时间 11 月 7 日凌晨 02:00 开始,大会上宣布了一系列平台更新。其中一个重要更新是用户可以创建他们自己的自定…

智慧农业:农林牧数据可视化监控平台

数字农业是一种现代农业方式,它将信息作为农业生产的重要元素,并利用现代信息技术进行农业生产过程的实时可视化、数字化设计和信息化管理。能将信息技术与农业生产的各个环节有机融合,对于改造传统农业和改变农业生产方式具有重要意义。 图扑…

SysML理论知识

概述 由来 长期以来系统工程师使用的建模语言、工具和技术种类很多,如行为图、IDEF0、N2图等,这些建模方法使用的符号和语义不同,彼此之间不能互操作和重用。系统工程正是由于缺乏一种强壮的标准的建模语言,从而限制系统工程师和…

Makefile 介绍

目录 一、Makefile 的规则 二、一个示例 三、make 是如何工作的 四、makefile 中使用变量 五、让 make 自动推导 六、另类风格的 makefile 七、清空目标文件的规则 make 命令执行时,需要一个 Makefile 文件,以告诉 make 命令需要怎么样的去编译和…

用Python实现朴素贝叶斯垃圾邮箱分类

一、实验目的 通过本实验,旨在使用朴素贝叶斯算法实现垃圾邮箱分类,并能够理解并掌握以下内容: 了解朴素贝叶斯算法的基本原理和应用场景。 学习如何对文本数据进行预处理,包括去除标点符号、转换为小写字母、分词等操作。 理解特…

git 生成公钥

1、通过命令 ssh-keygen 生成 SSH Key: ssh-keygen -t ed25519 -C "Gitee SSH Key" 三次回车 2、查看生成的 SSH 公钥和私钥: ls ~/.ssh/ 3、把公钥设置到git id_ed25519.pub 4、测试 ssh -T gitgitee.com 成功!!&…

Hive3 on Spark3配置

1、软件环境 1.1 大数据组件环境 大数据组件版本Hive3.1.2Sparkspark-3.0.0-bin-hadoop3.2 1.2 操作系统环境 OS版本MacOSMonterey 12.1Linux - CentOS7.6 2、大数据组件搭建 2.1 Hive环境搭建 1)Hive on Spark说明 Hive引擎包括:默认 mr、spark、…

从vue源码中看diff算法

一、v-for必须要指定key,其作用是什么? 在源码中有一个函数为,其中就是通过判断两个vnode的type和key进行判断,如果这两个属性相同,那么这两个vnode就是相同,所以在设置key的时候也不可以设置为object等无…

Fortigate SSL VPN路径遍历漏洞(CVE-2018-13379)

Fortigate SSL VPN路径遍历漏洞(CVE-2018-13379) 免责声明漏洞描述漏洞影响漏洞危害网络测绘Fofa: body"FortiToken clock drift detected" 漏洞复现1. 访问链接查看是否存在漏洞2. 查看用户名密码3. 登录后台 免责声明 仅用于技术交流,目的是…

Spring Cloud - 手写 Gateway 源码,实现自定义局部 FilterFactory

目录 一、FilterFactory 分析 1.1、前置知识 1.2、分析源码 1.2.1、整体分析 1.2.2、源码分析 1.3、手写源码 1.3.1、基础框架 1.3.2、实现自定义局部过滤器 1.3.3、加参数的自定义局部过滤器器 一、FilterFactory 分析 1.1、前置知识 前面的学习我们知道&#xff0c…

OpenAI开源全新解码器,极大提升Stable Diffusion性能

在11月7日OpenAI的首届开发者大会上,除了推出一系列重磅产品之外,还开源了两款产品,全新解码器Consistency Decoder(一致性解码器)和最新语音识别模型Whisper v3。 据悉,Consistency Decoder可以替代Stabl…

CROS错误 403 preflight 预检

预检 403 响应 Response for preflight 403 forbidden 如上图,配置了请求接口一直报错,前端看了没有什么问题,不知道哪里报错了,那么可能是后端没有设置跨域。(或者是设置了,但是可能需要换一种方式&#…

基于springboot实现致远汽车租赁平台管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现致远汽车租赁平台管理系统演示 摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统…

mysql 全文检索 demo

mysql5.6.7之后开始支持中文全文检索一直没用过,这次试试。 创建表 CREATE TABLE articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,title VARCHAR (200),body TEXT,FULLTEXT (title, body) WITH PARSER ngram ) ENGINE INNODB DEFAULT CHARSETut…

【配置】如何在打包Spring Boot项目时按需使用日常、测试、预发、正式环境的配置文件

文章目录 前言1. 创建5个配置文件2. 在pom.xml文件中如下配置3. 在application.properties中加入环境变量 前言 在我们开发项目的时候,一般有四套环境:日常、测试、预发、正式。日常环境作为我们开发环境;测试环境给测试同学测试功能&#x…

Jenkins 部署.net core 项目 - NU1301错误

/root/.jenkins/workspace/householdess/services/host/fdbatt.monitor.HttpApi.Host/fdbatt.monitor.HttpApi.Host.csproj : error NU1301: 本地源“/root/.jenkins/workspace/householdess/​http:/x.x.x.x:9081/repository/nuget.org-proxy/index.json”不存在。 [/root/.je…

【Java 进阶篇】Java Filter 快速入门

欢迎来到这篇有关 Java Filter 的快速入门指南!如果你是一名 Java 开发者或者正在学习 Java Web 开发,Filter 是一个强大的工具,可以帮助你管理和控制 Web 应用程序中的请求和响应。本文将向你解释 Filter 的基本概念,如何创建和配…

SHAP 和 LIME 解释模型

内容大纲 1、SHAP 解释器1.1 案例:用于预测患者肺癌1.2 案例中使用的shap解释器1.3 SHAP工作原理1.4 举例说明 2、LIME 解释器2.1 案例:判断法律案件胜诉可能性2.2 LIME解释器工作原理2.3 本地解释模型的训练过程2.4 举例说明1:新闻分类2.4 举…

智慧安防:监控防盗两不误的安防视频监控系统是什么样的?

随着社会的不断发展,安全问题越来越受到人们的关注,特别是对于居住在城市里的人们来说,盗窃问题是影响他们生活质量的重要因素之一。因此,根据市场需求,以监控防盗两不误的智慧监控系统得到了广泛的推广和应用。 一般…