notebook notebook
首页
  • 计算机网络
  • 计算机系统
  • 数据结构与算法
  • 计算机专业课
  • 设计模式
  • 前端 (opens new window)
  • Java 开发
  • Python 开发
  • Golang 开发
  • Git
  • 软件设计与架构
  • 大数据与分布式系统
  • 常见开发工具

    • Nginx
  • 爬虫
  • Python 数据分析
  • 数据仓库
  • 中间件

    • MySQL
    • Redis
    • Elasticsearch
    • Kafka
  • 深度学习
  • 机器学习
  • 知识图谱
  • 图神经网络
  • 应用安全
  • 渗透测试
  • Linux
  • 云原生
面试
  • 收藏
  • paper 好句
GitHub (opens new window)

学习笔记

啦啦啦,向太阳~
首页
  • 计算机网络
  • 计算机系统
  • 数据结构与算法
  • 计算机专业课
  • 设计模式
  • 前端 (opens new window)
  • Java 开发
  • Python 开发
  • Golang 开发
  • Git
  • 软件设计与架构
  • 大数据与分布式系统
  • 常见开发工具

    • Nginx
  • 爬虫
  • Python 数据分析
  • 数据仓库
  • 中间件

    • MySQL
    • Redis
    • Elasticsearch
    • Kafka
  • 深度学习
  • 机器学习
  • 知识图谱
  • 图神经网络
  • 应用安全
  • 渗透测试
  • Linux
  • 云原生
面试
  • 收藏
  • paper 好句
GitHub (opens new window)
  • 深度学习

  • 机器学习

    • 吴恩达-机器学习

    • 浙大胡浩基-机器学习

      • 支持向量机(SVM)
        • 1. 线性可分定义
        • 2. 线性可分时的最优分类 hyperplane
          • 2.1 什么是最优分类 hyperplane?
          • 2.2 寻找最优分类 hyperplane
        • 3. 线性不可分情况
          • 3.1 线性模型的局限
          • 3.2 从低维到高维的映射
          • 3.3 Kernel Function 的定义
          • 3.4 原问题和对偶问题
          • 3.5 转化为对偶问题
        • 4. SVM 的算法总体流程
        • 5. SVM 的使用
    • 莫烦-机器学习算法的数学解析与 Python 实现

    • 李航-统计学习方法

    • 李沐-实用机器学习

  • 知识图谱

  • AI
  • 机器学习
  • 浙大胡浩基-机器学习
yubin
2022-06-26
目录

支持向量机(SVM)

# 1. 线性可分定义

在二维中,线性可分表示为:

image-20220707104445520
  • 存在一条直线将 x 和 ○ 分开

线性不可分则表示为:

image-20220707104819974
  • 此时不存在一条直线将 x 与 ○ 分开

如果扩展到三维,则是用平面来分割:

image-20220707104935191

如果维度大于等于四维,那么就是用超平面(Hyperplane)来分割。

我们借助数学对 Linear Separable 和 Nonlinear Separable 进行定义,以二维为例,直线就可以表示为一个方程:

image-20220707105224545
  • 在直线的其中一边,,另一边则相反。
  • 可不可以让右边是小于 0 呢?可以呀,只需要假设 ,就可以是让右边小于 0,左边大于 0 了。所以我们只需要分析我们上图所示的情况即可。

接下来我们用数学严格定义训练样本以及他们的标签:假设我们有 N 个训练样本和他们的标签 ,其中 ,,并令 属于 时 ,反之则为 。

线性可分的严格定义:一个训练样本及 ,在 线性可分,是指存在 使得对 ,有:

  • 若 ,则
  • 若 ,则

若将 表示成一个 vector ,那么上面的定义可以写成:

  • 若 ,则
  • 若 ,则

# 2. 线性可分时的最优分类 hyperplane

# 2.1 什么是最优分类 hyperplane?

支持向量机算法分成了两个步骤:

  1. 解决线性可分问题
  2. 再将线性可分问题中获得的结论推广到线性不可分情况

我们先看一下他是如何解决线性可分问题的。

如果一个数据集是线性可分的,那么就存在无数多个 hyperplane 将各个类别分开。

既然有上面的结论,那哪一个是最好的呢?比如一个二分类的问题:

image-20220716193434391

问哪一个最好呢?大多数都是说 2 号线。其实原因在于:2 号线更能低于训练样本位置的误差。那这个 2 号线怎么画出来的呢?Vapnik 给出了基于最优化理论的回答。

将这个直线向左向右移动,直到能碰上一个或几个训练样本为止:

image-20220716193736561
  • 我们将移动后的平行线所擦到的训练样本为 support vector。
  • 两条平行线之间的距离叫做 margin。

这样我们所要找的线就是使 margin 最大的线,为了是直线唯一,又规定这条线是擦到 support vector 的两个线的正中间的那条线,也就是上图中的 2 号线了。

经过上面讨论,我们知道了 SVM 寻找的最优分类直线应该满足:

  1. 该直线分开了两个类;
  2. 该直线最大化 margin;
  3. 该直线处于间隔的中间,到所有 support vector 的距离相等。

上面的结论是基于二维特征空间的结果,扩展到更高维度后,直线将变成 hyperplane,此时被称为最优分类 hyperplane,但结论不会变。

# 2.2 寻找最优分类 hyperplane

下面我们讲如何用严格的数学来把寻找这个最优分类 hyperplane 的过程写成一个最优化问题。

假定训练样本集是线性可分的,那么 SVM 需要寻找的是最大化 margin 的 hyperplane,这个优化问题可以写成下面的形式:

  • minimize:
  • 限制条件:

下面讨论为什么会这样?我们先看两个个事实:

事实 1

与 是同一个超平面。()

事实 2

一个点 到超平面 的距离为:

借助于这两个事实,我们可以用 a 去缩放 和 ,即 ,最终使得缩放后的 和 能够在 support vector 上有 ,而在 non support vector 上,有 。

为什么可以这样推导呢?根据事实 1 可知,用 a 缩放后的仍是同一个超平面,而根据事实 2,support vector 到超平面的距离将变为:

有上面的式子可以看出来,最大化 support vector 到 hyperplane 的距离等价于最小化 。因此优化问题定为 minimize 和 minimize 是一样的。所以优化问题可以写成这样。

我们再来看限制条件。

support vector 到 hyperplane 的距离是 ,在 non support vector 上 。综合两者,我们可以写出 SVM 的限制条件:

,

  • 其中 的作用是协调超平面的左右
  • 右边的 1(标红)可以改成任意的正数,因为修改后计算出来的 和 也只比原来差了 a 倍,而根据事实 1,他们代表的是同一个 plane。

总结一下:

总结

线性可分情况下,SVM 寻找最佳 hyperplane 的优化问题可以表示为:

  • minimize:
  • 限制条件:

其中 是已知的, 是待求的。

可以看到,我们所表述的这个问题是凸优化(Convex Optimization)问题中的二次规划问题。

二次规划的定义

  1. 目标函数(object function)是二次项
  2. 限制条件是一次项

而 Convex Optimization 问题中,只有唯一一个全局极值,我们可以利用 gradient descent 方法来求出这个全局极值,从而解决这个 Convex Optimization 问题。

我们这里不详细探讨如何解 Convex Optimization 问题,而是将这个寻找 hyperplane 的问题转换为一个 Convex Optimization,并直接利用解这类问题的工具包来解出这个问题。

# 3. 线性不可分情况

# 3.1 线性模型的局限

在线性不可分的情况下,不存在 和 满足上面所有 N 个限制条件作为最优化的解,所以需要适当放松限制条件。

放松限制条件的基本思路是,对每个训练样本及标签 ,我们设置一个松弛变量(slack variable) ,并将 N 个限制条件改写为:

,

可以看到,只要每个 slack var 取得足够大,这些不等式的限制条件一定是可以满足的,所以我们还需要加入限制条件,以防止 slack var 无限地大。

改造后的 SVM 优化版本:

改造后的 SVM 的优化问题

  • minimize: 或
  • 限制条件:
    1. ,
    2. ,

以前的 objective function 只需要最小化 ,而现在加了一个正则化项,这样是想让所有 slack var 的和越小越好,比例因子 C 起到了平衡两项的作用。

这里用于平衡两项的比例因子 C 是人为设定的,因此它是一个 hyper parameter,这个 hyper param 需要去调的。尽管如此,SVM 也是 hyper param 较少的一个算法了,因此不需要花很多时间炼丹。

到了这里,其实上面的解线性不可分的情况有时是不行的,比如下图:

image-20220716210149264

这基本和瞎猜没什么区别,问题就出在:我们假设分开两类的函数是线性的。但线性模型的表现力是不够的,面对上面这个数据集总是无法找到一个直线可以分开两类,因此我们需要扩大可选的函数范围从而应对更加复杂的线性不可分的情况。

# 3.2 从低维到高维的映射

为了达成扩大可选函数范围的目标,像神经网络或决策树等都是直接产生更多可选函数,比如神经网络是通过多层非线性函数的组合,而 SVM 做法的思想是:将特征空间从低维映射到高维,然后用线性 hyperplane 对数据进行分类。

举个例子,考察下面如图的异或问题,这两类样本是在二维空间中是线性不可分的:

image-20220716220302773

而如果构造一个从二维到五维的映射 ,在五维的特征空间中,这个例子将有可能变成线性可分:

image-20220716220705227

这样映射到五维空间后, 变得线性可分了,因为:

image-20220716221145907

这样就是 、 是一类,另外两个是一类。

可以看到,通过人为指定一个二维到五维的映射 后,线性不可分的数据集变成了线性可分的数据集。这件事情说明了一个更一般的结论:

THEOREM

假设在一个 M 维空间上随机取 N 个训练样本,同时随机地对每个训练样本赋予标签 +1 或 -1,同时假设这些训练样本线性可分的概率为 P(M),则有当 M 趋于无穷大时,P(M) = 1。

这个结论我们不再证明了,但可以直观理解一下。当 feature space 的 维度 增加后,待估计参数 的维度也会增加,也就是说整个算法模型的自由度也会增加,当然也就更有可能分开低维时候无法分开的数据集。

这个定理告诉我们,将训练样本从低维映射到高维后,会增大线性可分的概率。我们先放下对 具体形式的探讨,并假设其已经确定下来,来看看 SVM 的优化问题将做出什么样的改变:

改造后的 SVM 的优化问题

  • minimize: 或
  • 限制条件:
    1. ,
    2. ,
  • 主要改变是 被 替换;
  • 之前是 维度与 维度相同,而现在与 维度相同。

可以看到,高维情况下优化问题的解法和低维情况是完全类似的。

现在还剩下一个问题:在 SVM 中,低维到高维的映射 取什么样的形式呢?

# 3.3 Kernel Function 的定义

本节具体研究 的形式,并引入 Kernel Function 的定义。

SVM 的创始人 Vapnik 对回答 的具体形式这一问题是非常有创意的。他指出,我们可以不用知道 的具体形式,取而代之,如果对于两个 vector 、,我们知道 ,那么我们仍然能够通过一些技巧获得一个测试样本 的类别信息,从而完成测试样本类别的预测。

我们定义 为 Kernel Function,它的值是一个实数,这从它的等式右边就可以看出来。

我们举两个例子来说明 Kernel Function 与低维到高维的映射 之间的相互关系。

Example:已知映射求 Kernel Function

🍉 首先举一个已知映射 求 Kernel Function 的例子:

假设 是一个将二维向量映射为三维向量的映射,例如:

image-20220716225615547

我们看一下与这个 相对应的 Kernel Function 的形式。假设有两个二维向量:,此时有:

image-20220716225837642

Example:已知 Kernel Function 求映射

🍉 然后举一个已知 Kernel Function 求映射 的例子:

假设 X 是一个 2 dim vector,,然后假设:

image-20220716231016401

根据定义 ,那么 的形式就是:

image-20220716231103538

值得一提的是,如果 是这种形式,那 也就一定是上面那种形式,这可以看出两者具有一一对应的关系。

从上面例子中可以看出,Kernel Function 与映射 是一一对应的关系。还要指出的是,Kernel Function 的形式不能随意的取,它必须要满足一定的条件才能分解为两个 内积的形式。

有大佬提出了如下定理:

Mercer’s Theorem

能写成 的充要条件是:

  1. 【交换性】
  2. , 有 【半正定性】

只要 K 满足交换性和半正定性,那么它就能写成 内积的形式。比如:

image-20220716233130866

但在这个例子中却不能显式写出 的具体表达式。

虽然我们无法知道 的具体形式,但是我们却可以通过一些方法知道 的值,进而可以知道一个测试样本 X 所属的类别。

本节总结

在这一节中,我们定义了 Kernel Function ,同时指出了它和低维到高维的映射 的相互决定关系。

下一节我们主要讲如何在已知 K 而不知 的情况下去求解 SVM 的优化问题。

# 3.4 原问题和对偶问题

本节从更广泛的角度出发,来解释最优化理论中的原问题和对偶问题的定义,为后续进一步推导 SVM 的对偶问题做准备。

原问题(Prime problem)的定义如下:

Prime problem 的定义

image-20220716234114598

可以看到这个定义很宽泛,自变量 是一个多维变量,目标函数是 。我们假设限制条件中不等式有 K 个,分别用 来表示;同时假设限制条件中等式有 m 个,分别用 来表示。

然后我们定义该原问题的对偶问题。首先先定义一个函数 如下:

image-20220716234821522

在此基础上,对偶问题(Dual problem)可以定义如下:

Dual problem 的定义

image-20220716235001835

这里面的 指的是遍历所有定义域的 ,找到使 最小的那个 ,同时把最小的 L 函数值赋值为 。

综合 prime problem 和 dual problem 的定义可以得到:

定理 一

如果 是 prime problem 的解, 是 dual problem 的解,则有

image-20220716235641988

最后一步的推导中 成立是因为:

  • 由于 是 prime problem 的解,所以 ,
  • 由于 是 dual problem 的解,所以

定义对偶差距(Duality Gap)为 。根据上面定理我们知道了 ,所以 。

还有如下的一个强对偶定理:

强对偶定理(Strong Duality Theorem)

如果 ,,且 为凸函数,则有 ,则对偶差距为 0。

简单来说就是,如果 prime problem 的目标函数是凸函数,限制条件是线性函数,那么 ,在这种情况下 Duality Gap 为 0。

定理的证明可参考 《CONVEX OPTIMIZATION》

接下来说,假如强对偶定理成立,也就是有 ,再根据定理一推出的不等式,我们可以这么说:

若 ,则从定理一的证明推理过程中的 这一步可以看出,由于有 ,那对于所有 ,必然有 ,也就是要么 ,要么 。这个条件称为 KKT 条件。

KKT 条件是由 Karush、Kuhn 和 Tucker 先后独立发表出来的。

本节小结

  • 定义了 prime problem 和 dual problem
  • 强对偶定理
  • KKT 条件

接下来,我们将利用这一节的知识,将 SVM 的 prime problem 转化为 dual problem,从而进一步完成 SVM 优化问题的求解。

# 3.5 转化为对偶问题

本节介绍把 SVM 的 prime problem 转化为 dual problem,从而进一步完成 SVM 优化问题的求解。

# 3.5.1 证明:SVM 的 prime problem 满足强对偶定理

回顾一下目前 SVM 的优化问题:

  • minimize: 或
  • 限制条件:
    1. ,
    2. ,

对比 prime problem 的定义,我们对这个版本进行改造,使它的形式成为一个 prime problem。改造的部分就是将原来的 变成原来的相反数,并对限制条件 2 做一下变形,从而 SVM 的优化问题就可以表达成:

  • minimize: 或
  • 限制条件:
    1. ,
    2. ,

可以看到上面这个版本中,目标函数是凸函数,两个限制条件都是线性的,因此满足强对偶定理。

# 3.5.2 使用对偶理论求解对偶问题

容易混淆的是,在 3.4 节讲的对偶理论的 prime problem 定义中,自变量 在 SVM 优化问题中相当于被拆成了 ;而限制条件中的 相当于被拆成了 () 和 () 两部分;由于 SVM 优化问题中不存在等式形式的限制条件,因此不存在 。

按照上一节对偶问题的定义,我们可以将这个 SVM 优化问题的 prime problem 转换成 dual problem,先看转换的结论,写出来的形式如下:

转换后的对偶问题

  • maximize:

  • 限制条件:

里面的一串式子就是 。

注意的是,由于上一节的 被拆成了实际的两部分限制条件,所以转换后 dual problem 中理论形式上 的系数 相当于被拆成了这里的两部分系数 和 ,而原来理论形式上的 在这里是没有了。

再来看一下是如何转化成这个对偶问题的。

求 部分,就是要遍历所有的 来求 的最小值。我们可以对 求导并令导数等于 0,这样我们可以得到(修正:下图中左边的 都应该改成 ):

image-20220717131050965

然后将获得的三个式子代入到 的表达式中,可以将 SVM 的 prime problem 转换为下面的对偶问题:

image-20220717133358038

将三个式子代入到 L 从而化简成这样的推导规程可以参考浙大胡浩基老师的现场版教学视频。

在目标函数的式子中, 可以写成 Kernel Function ,这样就不需要知道 的具体形式了。

可以看到这个对偶问题也是一个二次规划问题,可以通过最优化理论的 SMO 算法非常方便地求解出 ,注意所要最大化的目标函数 中其实已经没有 了,因此也可以写成 。

我们已经将 SVM 问题化成了对偶问题,但我们还没有完全结束。通过转化我们求出了 ,但我们的本质是想求最开始说的 中的 和 ,那怎么把求 转化到求 呢?

# 3.5.3 把求 转化为求

其实这个事情很简单。在令 而得出了 这个结论,但只通过这个公式,我们必须先知道 才能知道 。而 Vapnik 提出的算法的妙处在于,我们不见得需要 。

为什么呢?在 SVM 测试流程中,当来了一个样本 X,我们怎样知道它是属于哪个类呢?我们是:

  • 若 ,则 y = +1
  • 若 ,则 y = -1

在这里,我们可以不知道 ,我们只需要能够知道 这一个整体的值就可以了。我们把刚刚说的结论 代入进去,可以得到:

所以可以借助 Kernel Function 直接算出 这一部分。现在只剩下求 了。

求 b 需要用到 KKT 条件:。如果我们把它翻译成 SVM 的情况,就可以写成:

KKT 条件应用到 SVM 中

,

  1. 要么 ,要么
  2. 要么 ,要么

怎么求 b 呢?我们首先要取一个 (), 然后可以推出 ,此时 且 ,所以根据上面 KKT 条件我们可以得知只能是 和 ,这俩式子一联立就可以求出 了:

因为此时通过转化为对偶问题,已经可以将 求出来了,所以这里可以取它的一个分量 。当然也可以把所有 的可能取值都取一遍,各算出一个 b,然后计算这些这些 b 的平均值作为最终 的值,这样也许会更准确。

有了上面的推导,我们就可以最终在得到输入样本 X 后,计算 并与 0 做比较从而判别出该样本属于哪一类。

# 4. SVM 的算法总体流程

经过上面的介绍,我们得出了如下的一个结论:

核函数戏法(Kernel Trick)

有了 Kernel Trick 这个结论,我们就可以不需要知道 ,而仅需知道 Kernel Function 就可以了。

最终我们可以得到如下的 SVM 判别标准:

SVM 判别标准

  • 如果 ,那么
  • 如果 ,那么

基于对偶问题的求解,我们可以得出支持向量机的训练和测试的流程:

SVM 训练和测试的流程

训练过程:

输入 training data ,,其中 ,然后解下面这个优化问题从而求出 :

image-20220717133358038

然后再求 b:

测试过程:

一旦知道了 和 后,就可以按照 SVM 的判别标准来预测 X 的类别。

  • 如果 ,那么
  • 如果 ,那么

在这个过程中,完全没有用到低维到高维的映射 ,而只是用到了 Kernel Function 。

上面讲的是让 SVM 优化问题的目标函数是 情况下的训练和测试流程,课下可以自己试一下推导目标函数是 情况下的 SVM 训练和测试流程。

# 5. SVM 的使用

使用支持向量机进行分类经过三个步骤:

  1. 选取一个合适的数学函数作为核函数;
  2. 核函数完成高维映射并完成计算间隔所需的内积运算,求得间隔;
  3. 用间隔作为度量分类效果的损失函数,使用 SMO 等算法使得间隔最大,最终找到能够让间隔最大的 hyperplane。

在 scikit-learn 库中,支持向量机算法族都在 sklearn.svm 包中,支持向量机算法总的来说就一种,只是在核函数上有不同的选择,以及用于解决不同的问题,包括分类问题、回归问题和无监督学习问题中的异常点检测。因此需要根据场景选用不同的 SVM 算法类型:

  • LinearSVC 类:基于线性核函数的支持向量机分类算法。
  • LinearSVR 类:基于线性核函数的支持向量机回归算法。
  • SVC 类:可选择多种核函数的支持向量机分类算法,通过“kernel”参数可以传入 “linear” 选择线性函数、传入 “polynomial” 选择多项式函数、传入 “rbf” 选择径向基函数、传人 “sigmoid” 选择 Logistics 函数作为核函数,以及设置 “precomputed” 使用预设核值矩阵。默认以径向基函数作为核函数。
  • SVR 类:可选择多种核函数的支持向量机回归算法。
  • NuSVC 类:与 SVC 类非常相似,但可通过参数 “nu” 设置支持向量的数量。
  • NuSVR 类:与 SVR 类非常相似,但可通过参数 “nu” 设置支持向量的数量。
  • OneClassSVM 类:用支持向量机算法解决无监督学习的异常点检测问题。

使用 SVC 类调用的例子:

from sklearn.datasets import load_iris
from sklearn.svm import SVC

X, y = load_iris(return_X_y=True)
clf = SVC().fit(X, y)

clf.kernel  # 默认为径向量 rbf

clf.predict(X)

clf.score(X, y)
1
2
3
4
5
6
7
8
9
10
11

运行结果:

image-20220717160712873
编辑 (opens new window)
上次更新: 2022/07/17, 08:08:18
大规模机器学习
Decision Tree

← 大规模机器学习 Decision Tree→

最近更新
01
Deep Reinforcement Learning
10-03
02
误删数据后怎么办
04-06
03
MySQL 一主多从
03-22
更多文章>
Theme by Vdoing | Copyright © 2021-2024 yubincloud | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×