算法——支持向量机(support vector machines,SVM)

news2024/9/21 19:08:58

简介:个人学习分享,如有错误,欢迎批评指正

支持向量机(Support Vector Machine, SVM)是一种监督学习算法,广泛用于分类任务,也可以用于回归和异常检测等问题。SVM的核心思想是通过在特征空间中找到一个最优的分隔超平面,将不同类别的数据点分开,使得各类别之间的间隔最大化。

一、SVM的基本概念

1. 超平面
在二维空间中,超平面就是一条直线,而在高维空间中,超平面是一个维度比特征空间低一维的几何平面。例如,在三维空间中,超平面就是一个二维平面。

2. 支持向量
支持向量是指离决策边界(超平面)最近的那些数据点。这些点对定义最优超平面起到关键作用,移除这些点可能会改变超平面的位置。SVM算法通过支持向量来构建分类器。

3. 间隔(Margin)
间隔是指分类决策边界与最近的支持向量之间的距离。在SVM中,目标是最大化这个间隔,使得分类器在面对未见过的数据时具有更好的泛化能力。最大化间隔也意味着分类器对噪声和异常值更具鲁棒性。

4. 线性可分和线性不可分

  • 线性可分:如果可以用一个超平面完全分开两类数据,即数据点位于超平面的两侧并且没有任何错误分类,这样的数据集被称为线性可分的。
  • 线性不可分:如果数据无法用一个超平面完全分开,部分数据点会位于错误的分类区域。这时,SVM引入松弛变量允许少量错误分类,以求找到一个尽可能好的超平面。

5. 核函数(Kernel Function)
当数据在原始特征空间中不可线性分离时,SVM可以使用核函数将数据映射到更高维的特征空间,在高维空间中找到一个线性可分的超平面。常见的核函数有线性核、多项式核、高斯核(RBF核)等。

SVM的工作原理
SVM的目标是通过求解一个优化问题,找到一个能够最大化间隔的决策边界。在处理线性可分问题时,SVM直接在特征空间中寻找最优超平面;而在处理线性不可分问题时,SVM通过核函数将数据映射到高维空间,再寻找最优超平面。

:二维数据集的线性分类
假设我们有一个二维数据集,其中有两类数据点:类 A(红色圆点)和类 B(蓝色方块)。这些数据点在二维平面上分布,如下图所示:
在这里插入图片描述

SVM 的任务是找到一条直线(即超平面),将这两类点分开,并且使得这条直线到两类点最近点的距离最大化。

二、SVM算法流程

1. 数据准备

首先,收集并整理训练数据集 { ( x i , y i ) } i = 1 n \{(x_i, y_i)\}_{i=1}^{n} {(xi,yi)}i=1n,其中 x i x_i xi 是特征向量, y i y_i yi 是类别标签(通常取值为 − 1 -1 1 1 1 1)。如果数据集中的特征具有不同的尺度,需要进行标准化处理。

2. 选择核函数

SVM的核心在于选择合适的核函数来处理数据的非线性特征。常见的核函数(个人总结)有:

  • 线性核(Linear Kernel):适用于线性可分的数据。
  • 多项式核(Polynomial Kernel):能够处理非线性特征,但计算复杂度较高。
  • 高斯核(RBF Kernel):常用的核函数,能够在高维空间处理非线性数据。
  • Sigmoid核:类似于神经网络中的激活函数。

核函数的选择对SVM的性能有重要影响,通常需要通过实验或交叉验证来选择最优的核函数。

3. 构建优化问题

在选择好核函数后,SVM通过求解以下优化问题来找到最优超平面:

  • 线性可分:寻找一个能够完全分开两类数据的超平面。目标是最大化化边界的间隔,同时满足所有数据点被正确分类的约束条件:

    min ⁡ w , b 1 2 ∥ w ∥ 2 \min_{w,b} \frac{1}{2} \|w\|^2 w,bmin21w2

    满足条件 y i ( w ⋅ x i + b ) ≥ 1 y_i(w \cdot x_i + b) \geq 1 yi(wxi+b)1 对所有 i i i 成立。

  • 线性不可分:引入松弛变量 ξ i \xi_i ξi,允许少量错误分类,并通过惩罚参数 C C C 控制错误分类的惩罚程度:

    min ⁡ w , b , ξ 1 2 ∥ w ∥ 2 + C ∑ i = 1 n ξ i \min_{w,b,\xi} \frac{1}{2} \|w\|^2 + C \sum_{i=1}^{n} \xi_i w,b,ξmin21w2+Ci=1nξi

    满足条件 y i ( w ⋅ x i + b ) ≥ 1 − ξ i y_i(w \cdot x_i + b) \geq 1 - \xi_i yi(wxi+b)1ξi ξ i ≥ 0 \xi_i \geq 0 ξi0 对所有 i i i 成立。

4. 求解优化问题

这个优化问题通常通过拉格朗日乘子法和对偶问题转换来求解。求解过程依赖于计算核函数值和优化拉格朗日乘子,从而得到最终的分类决策函数:

f ( x ) = sign ( ∑ i = 1 n α i y i K ( x i , x ) + b ) f(x) = \text{sign} \left( \sum_{i=1}^{n} \alpha_i y_i K(x_i, x) + b \right) f(x)=sign(i=1nαiyiK(xi,x)+b)

其中 α i \alpha_i αi 是拉格朗日乘子, K ( x i , x ) K(x_i, x) K(xi,x) 是核函数。

5. 训练模型

使用训练数据集进行模型训练,求解得到支持向量 α i > 0 \alpha_i > 0 αi>0 对应的 x i x_i xi。这些支持向量决定了最优超平面的参数 w w w b b b

6. 预测

对于新的数据点 x x x,通过计算其与支持向量的核函数值,利用决策函数 f ( x ) f(x) f(x) 判断其所属类别。如果 f ( x ) > 0 f(x) > 0 f(x)>0,则预测为正类;否则预测为负类。

三、K-means算法的损失函数和收敛问题

1. 损失函数

SVM的目标是找到一个最优的超平面来分离不同类别的数据点。在这个过程中,损失函数用于衡量模型预测结果与实际结果之间的差异。SVM的损失函数主要包含两个部分:间隔最大化误分类惩罚

1.1. 硬间隔损失函数(适用于线性可分的情况)

对于线性可分的情况,SVM的目标是找到一个超平面,使得所有的样本点都能够被正确分类,并且最大化分类间隔。对于这种情况,损失函数仅考虑分类间隔的最大化:

L ( w ) = 1 2 ∥ w ∥ 2 L(w) = \frac{1}{2} \|w\|^2 L(w)=21w2

在约束条件 y i ( w ⋅ x i + b ) ≥ 1 y_i(w \cdot x_i + b) \geq 1 yi(wxi+b)1 下成立。这里, w w w 是权重向量, b b b 是偏置项。这个损失函数的目标是最小化权重向量的二范数,从而最大化分类间隔。

1.2. 软间隔损失函数(适用于线性不可分的情况)

在实际应用中,数据往往不是线性可分的,因此需要引入松弛变量 ξ i \xi_i ξi 来允许一些数据点出现误分类。在这种情况下,损失函数不仅要考虑分类间隔的最大化,还要对误分类进行惩罚:

L ( w , ξ ) = 1 2 ∥ w ∥ 2 + C ∑ i = 1 n ξ i L(w, \xi) = \frac{1}{2} \|w\|^2 + C \sum_{i=1}^{n} \xi_i L(w,ξ)=21w2+Ci=1nξi

其中, C C C 是一个惩罚参数,用于控制误分类的容忍程度, ξ i \xi_i ξi 是松弛变量,用于度量误分类的程度。这个损失函数的目标是在最大化分类间隔的同时,最小化误分类的代价。

1.3. 铰链损失函数(Hinge Loss)

SVM的铰链损失函数是为了衡量误分类问题而设计的,它对分类边界上的数据点施加了特别的约束。铰链损失函数定义为:

L ( y , f ( x ) ) = max ⁡ ( 0 , 1 − y ⋅ f ( x ) ) L(y, f(x)) = \max(0, 1 - y \cdot f(x)) L(y,f(x))=max(0,1yf(x))

其中, y y y 是实际标签, f ( x ) f(x) f(x) 是预测函数 f ( x ) = w ⋅ x + b f(x) = w \cdot x + b f(x)=wx+b。铰链损失函数确保支持向量的预测值至少与真实标签保持1的间隔。

2. 收敛问题

收敛性问题是指在训练过程中,优化算法是否能够在有限的迭代次数内找到一个满足损失函数最小化的解。SVM的收敛性通常受到以下几个因素的影响:

2.1. 优化算法

SVM训练通常采用二次规划(Quadratic Programming, QP)来求解。然而,直接求解二次规划问题在大规模数据集上可能计算复杂度较高。为此,常用的优化算法有:

  • SMO(Sequential Minimal Optimization)算法:这是一种分解算法,每次只优化两个拉格朗日乘子,使得计算复杂度大大降低,并且在大多数情况下收敛较快。
  • 梯度下降:包括原始的梯度下降和随机梯度下降(SGD),这些方法通过逐步逼近最优解来实现收敛。
2.2. 数据规模和特征维度
  • 数据规模:随着数据规模的增加,训练SVM的时间复杂度也会增加,导致收敛速度变慢。
  • 特征维度:高维特征空间可能会使得优化问题变得更加复杂,从而影响收敛性。
2.3. 超参数选择
  • 惩罚参数 C:惩罚参数 C C C 决定了模型对误分类的容忍度。较大的 C C C 倾向于减少误分类,但也可能导致模型过拟合,从而影响收敛速度。
  • 核参数:例如在RBF核中,参数 γ \gamma γ 的选择也会影响收敛性。合适的 γ \gamma γ 值能够加速收敛,而不合适的值可能导致模型收敛缓慢或局部最优。
2.4. 初始条件
  • 初始化范围和值:初始化条件的设定会影响优化算法的收敛路径。特别是在使用梯度下降法时,初始权重的选择可能决定收敛速度。

四、算法的调优和改进

1. 超参数调优

SVM的性能在很大程度上依赖于超参数的选择,尤其是惩罚参数 C C C 和核函数参数(如RBF核的 γ γ γ)。常用的调优方法包括:

1.1 网格搜索(Grid Search)
通过设定一组候选参数,遍历所有可能的参数组合,寻找最优参数。虽然计算复杂度较高,但网格搜索能够确保找到全局最优解。

1.2 随机搜索(Random Search)
与网格搜索相比,随机搜索在设定的参数空间中随机采样,虽然没有网格搜索的全面性,但在大多数情况下能显著降低计算成本,并且可能找到接近最优的参数组合。

1.3 交叉验证(Cross-Validation)
无论是网格搜索还是随机搜索,都通常结合交叉验证来评估模型的泛化性能。通过将数据集划分为训练集和验证集,可以有效地避免过拟合。

2. 核函数的选择与改进

核函数在SVM中起着至关重要的作用,选择合适的核函数可以显著提高模型的表现。常用的核函数有:

  • 线性核(Linear Kernel):适用于线性可分数据。
  • 多项式核(Polynomial Kernel):适用于复杂的非线性关系,但计算复杂度较高。
  • 高斯核(RBF Kernel):是最常用的核函数,适用于大多数非线性问题。
  • 自定义核函数:根据实际问题的特征,可以设计自定义的核函数,满足特定的需求。

3. 数据预处理

SVM对数据的预处理要求较高,尤其是在处理高维或不平衡数据时,适当的预处理能够极大地改善模型性能。

3.1 特征缩放
SVM对特征的尺度非常敏感,因此在使用前通常需要对特征进行标准化或归一化处理。常用方法包括:

  • Z-score标准化:将特征值减去均值,再除以标准差。
  • Min-Max归一化:将特征值缩放到一个固定范围(通常是[0, 1])。

3.2 处理不平衡数据
当数据集不平衡时,SVM可能会倾向于预测多数类。可以通过以下方法来改善这一问题:

  • 调节惩罚参数 C:为不同类别设置不同的惩罚权重,使得SVM对少数类更加敏感。
  • 欠采样或过采样:对数据集进行重新采样,使得各类别的样本数更加均衡。
  • 合成少数类样本(SMOTE):通过生成虚拟样本来平衡数据集。

4. 算法改进

SVM的基本算法在一些特定场景下可能需要进一步改进,以提升计算效率或处理更加复杂的问题。

4.1 SMO算法优化

Sequential Minimal Optimization(SMO)是解决二次规划问题的一种有效方法,SMO算法可以在不需要大量内存的情况下解决大规模的SVM问题。通过每次仅优化两个拉格朗日乘子,SMO能够大大加快SVM的训练过程。

4.2 增量式SVM(Incremental SVM)

增量式SVM允许模型在新数据到来时动态更新,而无需从头训练整个模型。对于实时系统或大数据流应用,增量式SVM可以有效地处理动态变化的数据。

4.3 核函数近似

在处理大规模数据时,计算核矩阵的复杂度非常高。使用核函数近似方法(如随机傅里叶特征、Nyström方法)可以大幅降低计算复杂度,提升SVM的可扩展性。

五、SVM的Python代码实现

使用调包实现

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score

# 加载数据集
iris = datasets.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)

# 数据标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# SVM模型
svm = SVC(kernel='linear', C=1.0)
svm.fit(X_train, y_train)

# 预测与评估
y_pred = svm.predict(X_test)
print(f'Accuracy: {accuracy_score(y_test, y_pred):.2f}')

不调包实现

import numpy as np

def linear_kernel(x1, x2):
    return np.dot(x1, x2)

def fit(X, y, C=1.0):
    n_samples, n_features = X.shape
    K = np.zeros((n_samples, n_samples))
    
    # 计算核矩阵
    for i in range(n_samples):
        for j in range(n_samples):
            K[i,j] = linear_kernel(X[i], X[j])
    
    # 定义P, q, G, h, A, b用于QP求解
    P = np.outer(y, y) * K
    q = -np.ones(n_samples)
    A = y.reshape(1, -1)
    b = np.zeros(1)
    G = np.vstack((-np.eye(n_samples), np.eye(n_samples)))
    h = np.hstack((np.zeros(n_samples), np.ones(n_samples) * C))
    
    # 通过CVXOPT或其他QP求解库来解优化问题
    # 示例中简化为伪代码,实际需调用QP求解器
    # sol = qp_solver(P, q, G, h, A, b)
    
    # 根据求解结果计算权重w和偏置b
    # w = ...
    # b = ...
    
    return w, b

# 调用fit函数训练模型(代码中省略了QP求解的部分)
# w, b = fit(X_train, y_train)

六、总结

SVM的优点

1.高效性:

  • 高维空间表现良好:SVM在高维空间中仍能有效地工作,尤其适用于特征数量远大于样本数量的情况。
  • 内存高效:SVM通过支持向量来构建决策边界,只依赖于少量的支持向量,节省了内存资源。

2.鲁棒性:

  • 最大化间隔:SVM通过最大化决策边界到最近数据点的间隔,增强了模型的泛化能力,减少了过拟合的风险。
  • 能够处理非线性问题:通过核函数技巧,SVM能够在高维空间中处理非线性可分的数据,具有很强的灵活性。

3.模型可解释性:

  • 决策边界清晰:SVM的决策边界由少数支持向量决定,便于理解和解释模型的分类决策。

4.对多种数据类型的适应性:

  • SVM可以处理多种数据类型,如线性、非线性、分类、回归和异常检测等,应用范围广泛。

SVM的缺点

1.计算复杂度高:

  • 大规模数据处理困难:SVM在面对大规模数据集时,训练时间较长,计算复杂度高。尤其是在使用非线性核函数时,计算开销更大。

2.参数调优复杂:

  • 对超参数敏感:SVM的性能依赖于超参数 C 和核函数参数的选择,调优过程需要耗费大量时间和计算资源。
  • 核函数的选择困难:选择合适的核函数并非易事,不同核函数对模型表现有很大影响,通常需要通过实验或交叉验证来确定最优核函数。

3.对不平衡数据的表现较差:

  • SVM在处理类别不平衡数据集时,可能会倾向于预测多数类,从而导致模型的偏差。

4.训练时间长:

  • 在大规模数据集上的训练时间较长:尤其是在使用复杂核函数或高维特征空间时,SVM的训练时间显著增加。

5.缺乏概率估计:

  • 预测结果不具有概率性:SVM输出的决策值是一个确定性的类别标签,而不是概率,需要借助其他方法(如Platt Scaling)来估计分类概率。

参考文献:
统计学习方法(李航)
机器学习算法(一)SVM

结~~~

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

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

相关文章

单片机内存区域划分

目录 一、C 语言内存分区1、栈区2、堆区3、全局区(静态区)4、常量区5、代码区6、总结 二、单片机存储分配1、存储器1.1 RAM1.2 ROM1.3 Flash Memory1.4 不同数据的存放位置 2、程序占用内存大小 一、C 语言内存分区 C 语言在内存中一共分为如下几个区域…

高效达人必备!Simple Sticky Notes让灵感与任务不再遗漏!

前言 阿尔伯特爱因斯坦所言:“我们不能用制造问题时的同一水平思维来解决它。”这句话深刻地揭示了创新与突破的必要性。正是基于这样的理念,Simple Sticky Notes这款桌面便签软件以其独特的创新视角和实用性,在众多同类软件中脱颖而出。 它…

【原型设计工具评测】Axure、Figma、Sketch三强争霸

在当今的数字化设计领域,选择合适的原型设计工具对于项目的成功至关重要。Axure、Figma 和 Sketch 是目前市场上最受欢迎的三款原型设计工具,它们各具特色,满足了不同用户的需求。本文将对这三款工具进行详细的对比评测,帮助设计师…

Fine-Grained Egocentric Hand-Object(中文翻译)

精细化自我中心手-物体分割: 数据集、模型(model)与应用 灵芝张1, 盛昊周1, 西蒙斯滕特 $ {}^{2} $, 和健博石 $ {}^{1} $ 摘要。 自我中心视频提供了高保真度建模人类行为的细粒度信息。手和交互对象是理解观众行为和意图的一个关键方面。…

Pandas 10-绘制饼图

1. 准备数据 首先,需要准备一个DataFrame。 import pandas as pd# 创建一个DataFrame data {Category: [A, B, C, D],Value: [15, 30, 45, 10] }df pd.DataFrame(data) print(df)输出: Category Value 0 A 15 1 B 30 2 …

职称评审汇报ppt模板_副教授教学科研型职称答辩ppt制作案例

副教授教学科研型职称答辩ppt制作案例 专业技术职务评聘述职报告PPT制作案例 PPT项目概要: 项目名称:专业技术职务评聘述职报告PPT 项目单位:浙江X大学 制作需求:PPTX 制作方式:线上沟通 专业技术职务聘任申报人汇…

【战术数据链】Link 22 - 已准备好投入使用

Link 22,又称北约改进型 Link Eleven (NILE),是一种战术数据链通信标准。新标准计划在中期内取代广泛使用的 Link 11,并将与 Link 16 同时使用。 就数字海军通信而言,战术数据链尤为重要。北约和盟国海军使用 Link 11 协议&#…

初始MYSQL数据库(1)——创建、删除数据库和数据表的相关操作

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏: MYSQL 目录 数据库的概念 数据库的相关操作 常用的数据类型 数值型 字符串类型 日期类型 数据表的相关操作 练习 数据库的概念 数…

C++20中lambda表达式新增加支持的features

1.弃用通过[]隐式捕获this&#xff0c;应使用[,this]或[,*this]显示捕获&#xff1a; namespace { struct Foo {int x{ 1 };void print(){//auto change1 [] { // badauto change1 [, this] { // good, this: referencethis->x 11;};change1();std::cout << "…

【进程间通信】匿名管道

1.进程间通信的介绍 是什么 为什么 怎么做 匿名管道 原理 特征 管道的四种情况可以写代码自己看看 管道接口 编码实现 父进程进行读&#xff0c;子进程进行写 里面有snprintf的使用 #include<iostream> #include<unistd.h> #include<stdlib.h> #i…

力扣435-无重叠区间(Java详细题解)

题目链接&#xff1a;435. 无重叠区间 - 力扣&#xff08;LeetCode&#xff09; 前情提要&#xff1a; 因为本人最近都来刷贪心类的题目所以该题就默认用贪心方法来做。 贪心方法&#xff1a;局部最优推出全局最优。 如果一个题你觉得可以用局部最优推出全局最优&#xff0…

祝贺 | 武汉大学生命科学学院孙蒙祥教授课题组时隔三年再发Nature

公众号&#xff1a;生信漫谈&#xff0c;获取最新科研信息&#xff01; 祝贺 | 武汉大学生命科学学院孙蒙祥教授课题组时隔三年再发Naturehttps://mp.weixin.qq.com/s?__bizMzkwNjQyNTUwMw&mid2247487136&idx1&sn9d65a5f18c7b5131800446bcbba7fa06&chksmc0e9…

计算之魂:持续于正确的因果链(一)

文章目录 引言25 人赛跑比赛过程模拟演示 BB84 量子密钥分发&#xff08;量子通信&#xff09;协议模拟图形化演示 BB84 协议过程BB84 协议优势应用场景 结语 引言 如果你只有一杆 100 年前的毛瑟枪&#xff0c;能够打中目标只能靠天分&#xff0c;如果你有一杆最先进的狙击步…

每日定期分享诗歌

安装schedule库 首先&#xff0c;确保你已经安装了schedule库。如果没有安装&#xff0c;可以使用以下命令进行安装&#xff1a; pip install schedulepython每日定期分享诗歌 import json import requests import schedule import timedef get_poem():# 这里使用一个公开的…

Linux下快速判断当前终端使用的是bash or csh

在Linux下设置环境变量的时候&#xff0c;可能你也遇到过export: Command not found一类的错误。这是因为当前终端使用的不是bash&#xff0c;如何快速判断当前终端使用的是哪种类型的shell呢&#xff1f; echo $0判断shell类型 最简单的方法就是在终端输入echo $0&#xff0…

编写一个每次随机生成 10个 0(包括) 到 100 之间的随机正整数。

编写一个每次随机生成 10个 0&#xff08;包括&#xff09; 到 100 之间的随机正整数。 package cn.itcast.example;import java.util.Iterator; import java.util.Random; public class example {public static void main (String[] arge) {System.out.println("Math.ra…

【微机原理】v和∧区别

&#x1f31f; 嗨&#xff0c;我是命运之光&#xff01; &#x1f30d; 2024&#xff0c;每日百字&#xff0c;记录时光&#xff0c;感谢有你一路同行。 &#x1f680; 携手启航&#xff0c;探索未知&#xff0c;激发潜能&#xff0c;每一步都意义非凡。 在汇编语言和逻辑表达…

Android使用内容提供器(ContentProvider)实现跨程序数据共享

文章目录 Android使用内容提供器&#xff08;ContentProvider&#xff09;实现跨程序数据共享新建内容提供器DatabaseProvider修改DatabaseProvider中的代码AndroidManifest.xml文件中注册provider修改activity_main.xml中的代码修改MainActivity中的代码运行ProviderTest项目 …

mysql查询慢除了索引问题还会是因为什么?

问题 作为一个程序员SQL查询慢的问题在工作和面试中都是会经常遇到的问题, 一般情况下我们都会联想到索引问题, 那么除了索引问题还有什么其他的场景会导致SQL查询慢呢? MySQL执行查询逻辑 例如我们使用可视化工具执行这样一条SQL: select * from user_info where age 10;…

Java:寻找最长连续序列

Java实现寻找最长连续序列 引言问题描述设计思路实现代码 代码解释单元测试 总结 引言 在面对大规模数据集时&#xff0c;经常需要识别出其中的连续子序列&#xff0c;这一任务在诸多领域如股票市场分析、天气预报等方面尤为关键&#xff0c;因为连续性的数据往往承载了重要的…