ML学习笔记 #09 支持向量机
本文最后更新于:2022年11月22日 晚上
本节将继续介绍监督学习中的一个强力的分类器——支持向量机(Support Vector Machine,SVM),其通过「间隔最大化」的思想来学习最优的决策边界,比逻辑回归算法更为鲁棒。
支持向量机 | SVM
首先来直观地理解一下决策边界,考虑一个线性可分的二分类问题:
图中有三条直线分别代表三个分类器的决策边界,可以直观地感受到 \(H_3\) 应该会好于 \(H_1\) 和 \(H_2\)。显然,\(H_1\) 甚至不能把类别正确分开,肯定不能考虑;\(H_2\) 虽然可以,但是边界距离最近的数据点只有很小的间隔,如果测试数据有一些噪声的话,很可能会被 \(H_2\) 错误地分到另一类——即对噪声敏感、泛化能力弱。
而 \(H_3\) 似乎距离两侧都有较大的间隔,可以容忍一些微小的噪声。如何能学习到这样一个分类器呢?
优化目标
回忆逻辑回归的优化目标: \[ \min_{\theta} \frac{1}{m}\left[ \sum_{i=1}^m{y^{\left( i \right)}}\left( -\ln h_{\theta}\left( x^{\left( i \right)} \right) \right) +\left( 1-y^{\left( i \right)} \right) \left( -\ln \left( 1-h_{\theta}\left( x^{\left( i \right)} \right) \right) \right) \right] +\frac{\lambda}{2m}\sum_{j=1}^n{\theta _{j}^{2}} \] 其中的 \(h_{\theta}\left( x^{\left( i \right)} \right)\) 使用 \(\mathrm{sigmoid}\) 函数,因此对于一个 \(y=1\) 的样本,我们希望 \(h_{\theta}\left( x\right)\) 也趋近于 \(1\),也就是 \(\theta^Tx\) 远大于 \(0\),反之同理。进一步地,我们只考虑优化目标中的代价函数: \[ \mathrm{Cost}\left( h_{\theta}(x),y \right) =\begin{cases} -\ln \left( h_{\theta}\left( x \right) \right)& y=1\\ -\ln \left( 1-h_{\theta}\left( x \right) \right)& y=0\\ \end{cases} \] 画出两种情况下的代价函数关于 \(\theta^Tx\) 的曲线:
记上图中左图为 \(\text{cost}_1(\theta^T x)\),即分类为 \(1\) 时采用的代价;右图为 \(\text{cost}_0(\theta^T x)\),即分类为 \(0\) 时采用的代价。在支持向量机中,我们不再采用 \(\mathrm{sigmoid}\) 函数,而是将其修改为一条非常接近的折线:
其中,折线的拐点位于 \(z=\pm 1\) 的位置,先不考虑斜率的大小,则代价函数可以表示为: \[ \text{cost}_1(z)=\begin{cases}0&z\geqslant1\\k_1(z-1)&z<1\end{cases}\quad\quad \text{cost}_0(z)=\begin{cases}0&z\leqslant-1\\k_0(z+1)&z>-1\end{cases} \] > 此代价函数也被称为折页损失(Hinge Loss),非常形象,常用于凸优化任务中,也被写作: > \[ > L(y)=\max (0, 1-\hat{y}\cdot y) > \] > 其中 \(y=\pm 1\) 为正确的标签,\(\hat{y}\) 为预测输出,通常是软结果,即取 \([-1,1]\) 区间中的值。
另外,SVM 中习惯不除以样本大小 \(m\),这不会影响最终的优化目标。并将正则化参数放在第一项而非第二项,即支持向量机的优化目标为: \[ \min_{\theta} C\sum_{i=1}^m{\left[ y^{\left( i \right)}\mathrm{cost}_1\left( \theta ^Tx^{\left( i \right)} \right) +\left( 1-y^{\left( i \right)} \right) \mathrm{cost}_0\left( \theta ^Tx^{\left( i \right)} \right) \right]}+\frac{1}{2}\sum_{j=1}^n{\theta _{j}^{2}} \] 其中,\(C\) 就是正则化参数,类比逻辑回归中 \(\lambda\) 的作用。并且当 \(C\) 取到 \(\frac{1}{\lambda}\) 时两者的优化目标一致。
大间隔思想 | Large Margin
显然,新的代价函数会在计算速度上有一定的优势,但它是如何最大化间隔(Margin)的呢?我们首先观察第一项代价 $y_1( ^Tx ) +( 1-y ) _0( ^Tx ) $,欲使之最小,最理想的情况就是对于每个样本,都有 \(\text{cost}_y(\theta^T x)=0\),对应着: \[ \begin{cases} \theta^Tx\geqslant 1&\text{if }y=1\\ \theta^Tx\leqslant -1&\text{if }y=0 \end{cases} \] 而在逻辑回归中,我们只需要使误分类的样本最少,也就是: \[ \begin{cases}\theta^Tx\geqslant 0&\text{if }y=1\\\theta^Tx\leqslant 0&\text{if }y=0\end{cases} \] 因此 SVM 相当于将判别条件变得更苛刻,以文章开篇提到的三条决策边界为例,直线 \(H_2\) 和 \(H_3\) 以及它俩的任意线性组合,都能完美分开两类,也就是能有无穷多个解满足逻辑回归的优化目标。但对于支持向量机而言,可选的解会相对少很多。而这也使 SVM 能相对更具有鲁棒性,因为我们留出了一个「安全边界」来应对噪声样本。
接下来假设一种极端的情况,我们将正则化参数 \(C\) 取一个非常大的值,此时模型会倾向于将第一项收敛为 \(0\)。那么模型的优化目标可以改写为: \[ \min_{\theta} \frac{1}{2}\sum_{j=1}^n{\theta _{j}^{2}}\,\, \\ \mathrm{s}.\mathrm{t} \begin{cases} \theta^Tx^{(i)}\geqslant 1 &\text{if } y^{(i)}=1\\ \theta^Tx^{(i)}\leqslant -1 &\text{if } y^{(i)}=0\\ \end{cases} \] 上式也被称为硬间隔(Hard Margin)优化目标,用于在线性可分的数据集中找到唯一的最优边界。但在在现实情况中,数据样本通常更加复杂,即使真的线性可分,也可能会存在部分离群点,而模型为了得到完美的边界,会学习到偏差很大的边界。因此在实际中通常不将 \(C\) 设置得过大,采用软间隔(Soft Margin)。
回顾我们前面说到的,可以将 \(C\) 类比为 \(\frac{1}{\lambda}\),因此:
- \(C\) 较大时,相当于 \(\lambda\) 较小,可能会导致过拟合、高方差,出现如上图红线那样的情形。
- \(C\) 较小时,相当于 \(\lambda\) 较大,可能会导致欠拟合、高偏差,甚至无法分类。
几何角度理解大间隔
在前文改写的优化目标的基础上,我们注意到 \(\theta^Tx\) 其实是参数 \(\theta\) 和 \(x\) 两个向量的点积(内积),可以视作 \(x\) 向 \(\theta\) 的投影长度乘上 \(\theta\) 的长度 \(||\theta||\)。
为了更好理解,我们忽略掉截距,令 \(\theta_0=0\),将特征数 \(n\) 置为 \(2\),于是仅有两个特征 \(\{x_1,x_2\}\) 和两个参数 \(\{\theta_1,\theta_2\}\)。则此时有: \[ \frac{1}{2}\sum_{j=1}^n{\theta _{j}^{2}}=\frac{1}{2}\left( \theta _{1}^{2}+\theta _{2}^{2} \right) =\frac{1}{2}\left( \sqrt{\theta _{1}^{2}+\theta _{2}^{2}} \right) ^2=\frac{1}{2}\left\| \theta \right\| ^2 \] 从几何角度理解,参数 \(\theta\) 其实是决策边界的法向量,因此会和边界本身呈现垂直关系。而特征 \(x\) 就是样本点在(特征空间)坐标系上的向量,起点为原点。绘制出如下样例:
其中 \(p^{\left( i \right)}\) 为投影轴的长度(可正可负),于是可以得到: \[ \theta ^Tx^{\left( i \right)}=\theta _1x_{1}^{\left( i \right)}+\theta _2x_{2}^{\left( i \right)}=p^{\left( i \right)}\left\| \theta \right\| \] 因此优化目标可以从几何角度再次改写为: \[ \min_{\theta} \frac{1}{2}\left\| \theta \right\| ^2\,\, \\ \mathrm{s}.\mathrm{t}\begin{cases} p^{\left( i \right)}\left\| \theta \right\| \geqslant 1& \text{if } y^{(i)}=1\\ p^{\left( i \right)}\left\| \theta \right\| \leqslant -1& \text{if } y^{(i)}=0\\ \end{cases} \] 显然,为了让法向量的范数 \(\left\| \theta \right\| ^2\) 最小化,我们必须增大样本在法向量上的投影 \(p^{\left( i \right)}\) 长度,如下图所示:
以上就是为什么支持向量机最终会找到最大间隔的原因。当然,在推导的过程中我们使用了简化的假设,例如 \(θ_0=0\),这是为了让决策平面通过原点,下面我们将移除这个假设进行数学推导。
线性 SVM 的通解
前面我们介绍了 SVM 优化目标的设定,显然,对于线性可分的数据集,有且仅有一个最优超平面可以达到间隔最大化。接下来我们将以硬间隔为例,推导线性可分数据集的最优决策平面的求解过程。本节将继续沿用前文的参数定义。
支持向量 | Support Vector
一个超平面由法向量 \(\theta\)(不包含 \(\theta_0\))和截距 \(\theta_0\) 决定,其方程为 \(\theta^Tx+\theta_0=0\),这里规定法向量指向的一侧为正类,另一侧为负类。上图中最优超平面的法方向取右上方向。
在线性可分的情况下,训练数据集的样本点中与分离超平面距离最近的数据点称为支持向量(Support Vector),支持向量是使得优化目标中的约束条件取等的点,即满足: \[ y^{\left( i \right)}\left( \theta ^Tx^{\left( i \right)}+\theta _0 \right) =0 \] 在决定最佳超平面时只有支持向量起作用,而其他数据点并不起作用。如果移动非支持向量,甚至删除非支持向量都不会对最优超平面产生任何影响。也即支持向量对模型起着决定性的作用,这也是「支持向量机」名称的由来。
容易发现,两条支持向量其实是平行的直线,通过两条平行直线的距离公式可得: \[ \rho =\frac{2}{\left\| \theta \right\|} \] 要使得间隔 $$(Margin)尽量大,存在以下等价关系: \[ \max_{\theta ,\theta _0} \rho \Longleftrightarrow \max_{\theta ,\theta _0} \rho ^2\Longleftrightarrow \min_{\theta ,\theta _0} \frac{1}{2}\left\| \theta \right\| ^2 \] 进而,加入约束条件,得到间隔最大化问题的数学表达(与上一节类似): \[ \begin{aligned} &\min_{\theta ,\theta _0} \frac{1}{2}\left\| \theta \right\| ^2 \\ \mathrm{s}.\mathrm{t}\;\;y^{\left( i \right)}&\left( \theta ^Tx^{\left( i \right)}+\theta _0 \right) \geqslant 1 \end{aligned} \]
对偶问题 | Dual Problem
称上式所述问题为原始问题(Primal Problem),可以应用拉格朗日乘子法构造拉格朗日函数(Lagrange Function)再通过求解其对偶问题(Dual Problem)得到原始问题的最优解。
首先引入拉格朗日乘子(Lagrange Multiplier)\(\alpha^{(i)}\geqslant 0,i=1,2,\cdots ,n\)。则拉格朗日函数为: \[ L(\theta ,\theta _0,\alpha )=\frac{1}{2}\left\| \theta \right\| ^2-\sum_{i=1}^n{\alpha ^{\left( i \right)}}\left[ y^{\left( i \right)}\left( \theta ^Tx^{\left( i \right)}+\theta _0 \right) -1 \right] \] 如果所有样本点都线性可分,则上式中第二项必不为负,则: \[ \max_{\alpha} L(\theta ,\theta _0,\alpha )=\frac{1}{2}\left\| \theta \right\| ^2 \] 因此,优化问题等价于: \[ \min_{\theta ,\theta _0} \max_{\alpha} L(\theta ,\theta _0,\alpha ) \] 根据拉格朗日对偶性,上述问题即原始问题的对偶问题是: \[ \max_{\alpha} \min_{\theta ,\theta _0} L(\theta ,\theta _0,\alpha ) \] 通过转化为对偶问题,我们只需优化一个变量 \(\alpha\),且约束条件也可以简化。
极大化极小
首先求内部的极小化问题 \(\min_{\theta ,\theta _0} L(\theta ,\theta _0,\alpha )\),对拉格朗日函数求导并令导数为 \(0\): \[ \begin{aligned} &\nabla _{\theta}L(\theta ,\theta _0,\alpha )=\theta -\sum_{i=1}^n{\alpha ^{\left( i \right)}y^{\left( i \right)}x^{\left( i \right)}}=0\Longrightarrow \theta =\sum_{i=1}^n{\alpha ^{\left( i \right)}y^{\left( i \right)}x^{\left( i \right)}} \\ &\nabla _{\theta _0}L(\theta ,\theta _0,\alpha )=-\sum_{i=1}^n{\alpha ^{\left( i \right)}y^{\left( i \right)}}=0\Longrightarrow \sum_{i=1}^n{\alpha ^{\left( i \right)}y^{\left( i \right)}}=0 \end{aligned} \] 将以上两式代入 \(L(\theta ,\theta _0,\alpha )\) 并化简: \[ \begin{aligned} L(\theta ,\theta _0,\alpha )&=\frac{1}{2}\left\| \theta \right\| ^2-\sum_{i=1}^n{\alpha ^{\left( i \right)}}\left[ y^{\left( i \right)}\left( \theta ^Tx^{\left( i \right)}+\theta _0 \right) -1 \right]\\ &=\frac{1}{2}\left( \sum_{i=1}^n{\alpha ^{\left( i \right)}y^{\left( i \right)}x^{\left( i \right)}} \right) \cdot \left( \sum_{j=1}^n{\alpha ^{\left( j \right)}y^{\left( j \right)}x^{\left( j \right)}} \right) -\left( \sum_{i=1}^n{\alpha ^{\left( i \right)}y^{\left( i \right)}x^{\left( i \right)}} \right) \cdot \left( \sum_{j=1}^n{\alpha ^{\left( j \right)}y^{\left( j \right)}x^{\left( j \right)}} \right) -\theta _0\sum_{i=1}^n{\alpha ^{\left( i \right)}y^{\left( i \right)}}+\sum_{i=1}^n{\alpha ^{\left( i \right)}}\\ &=\sum_{i=1}^n{\alpha ^{\left( i \right)}}-\frac{1}{2}\left( \sum_{i=1}^n{\alpha ^{\left( i \right)}y^{\left( i \right)}x^{\left( i \right)}} \right) \cdot \left( \sum_{j=1}^n{\alpha ^{\left( j \right)}y^{\left( j \right)}x^{\left( j \right)}} \right)\\ &=\sum_{i=1}^n{\alpha ^{\left( i \right)}}-\frac{1}{2}\sum_{i,j=1}^n{y^{\left( i \right)}}y^{\left( j \right)}\alpha ^{\left( i \right)}\alpha ^{\left( j \right)}\left( x^{\left( i \right)}\cdot x^{\left( j \right)} \right)\\ \end{aligned} \] 在求外部的极大化问题,等价于对上取负数后对 \(\alpha\) 求极小: \[ \begin{aligned} \min_{\alpha} \frac{1}{2}&\sum_{i,j=1}^n{y^{\left( i \right)}}y^{\left( j \right)}\alpha ^{\left( i \right)}\alpha ^{\left( j \right)}\left( x^{\left( i \right)}\cdot x^{\left( j \right)} \right) \,\,\\ &\mathrm{s}.\mathrm{t}\;\;\sum_{i=1}^n{\alpha ^{\left( i \right)}y^{\left( i \right)}}=0\\ \end{aligned} \] 不难发现这是一个二次规划问题,有现成的通用的算法来求解。此外也有一些更高效的算法,例如序列最小优化(Sequential Minimal Optimiation,SMO)算法。
KKT 条件
Karush-Kuhn-Tucker(KKT)条件是非线性规划(Nonlinear Programming)最佳解的必要条件,这里暂不展开介绍。现在假设我们求出了以上问题的最优解 \(\hat{\alpha}\),则可以求出最优 \(\theta\): \[ \hat{\theta}=\sum_{i=1}^n{\hat{\alpha}^{\left( i \right)}y^{\left( i \right)}x^{\left( i \right)}} \] 因为至少存在一个 \(\hat{\alpha}^{(j)}>0\)(若不存在,即 \(\hat{\alpha}\) 全为 \(0\),则 \(\hat{W}=0\),即 \(\rho=\frac{2}{\|\hat{W}\|}=\infty\),显然不行),再根据 KKT 条件,即: \[ \left\{ \begin{array}{l} \text{乘子非负:}\alpha ^{\left( i \right)}\geqslant 0\\ \text{约束条件:}y^{\left( i \right)}\left( \theta ^Tx^{\left( i \right)}+\theta _0 \right) -1\geqslant 0\\ \text{互补条件:}\alpha ^{\left( i \right)}\left( y^{\left( i \right)}\left( \theta ^Tx^{\left( i \right)}+\theta _0 \right) -1 \right) =0\\ \end{array} \right. \] 根据互补条件,至少存在一个 \(j\),使 \(y^{\left( j \right)}\left( \theta ^Tx^{\left( j \right)}+\theta _0 \right) -1=0\),即存在一个支持向量,可求得最优 \(\hat{b}\) : \[ \begin{aligned} \hat{b}&=\frac{1}{y^{\left( j \right)}}-\theta ^Tx^{\left( j \right)}\\ &=y^{\left( j \right)}-\theta ^Tx^{\left( j \right)}\\ &=y_j-\sum_{i=1}^n{\hat{\alpha}^{\left( i \right)}y^{\left( i \right)}\left( x^{\left( i \right)}\cdot x^{\left( j \right)} \right)}\\ \end{aligned} \]
此时分类的决策函数为: \[ f(x)=\mathrm{sign}\left( \sum_{i=1}^n{\hat{\alpha}^{\left( i \right)}y^{\left( i \right)}\left( x^{\left( i \right)}\cdot x \right)}+\hat{b} \right) \] 此外,根据互补条件,如果一个样本点不是支持向量,则其 \(\hat{\alpha}^{(i)}=0\),说明此样本点对模型没有任何作用。
实际使用
软间隔 | Soft Margin
当训练数据不能线性可分但是可以近似线性可分时,可以允许 SVM 在少量样本上出错,即将之前的硬间隔最大化条件放宽一点,为此引入软间隔(Soft Margin)的概念。
此时,我们就不再不将正则化参数 \(C\) 设置得过大,则优化目标就变成: \[ \min_{\theta ,\theta _0} \frac{1}{2}\left\| \theta \right\| ^2+C\sum_{i=1}^n{\max \left( 0,1-y^{\left( i \right)}\left( \theta ^Tx^{\left( i \right)}+\theta _0 \right) \right)} \] 通过引入松弛变量改写优化目标后,得到的式子依然是一个凸二次规划问题,和硬间隔支持向量机类似,我们可以通过拉格朗日乘子法将其转换为对偶问题进行求解。这里不展开介绍。
高斯核函数 | Gaussian Kernel
对于非线性可分的数据,在之前的文章中我们直到可以引入高阶特征来进行多项式回归,而问题就是如何选择这些高阶特征?除了通过组合原有特征,在这里我们引入核函数 \(\phi:x\mapsto \phi(x)\),它将原来的 \(n\) 维向量映射为更高维的向量,使得这些向量在该更高维空间中线性可分。
在之前的例子中,可以认为是使用了线性核 \(\phi(x)=x\),即不做任何改变;而接下来我们将介绍一种最常用的核函数——高斯核(Gaussian Kernel): \[ \phi_i \left( x \right) =\mathrm{Sim}\left( x,l^{\left( i \right)} \right) =\exp \left\{ -\frac{\left\| x-l^{(i)} \right\| ^2}{2\sigma ^2} \right\} \] 其中 \(\sigma\) 是可调节参数,\(l^{(i)}\) 被称为地标(Landmarks),是原始空间中选取的某些点,具有和样本特征 \(x\) 相同的维度。\(\left\| x-l^{(i)} \right\|\) 即为样本到地标的欧氏距离。
可以看出,高斯核与正态分布的形式有些许类似,绘制出函数图像:
显然,\(x\) 距离 \(l^{(i)}\) 越远时,分子越大,函数值越接近 \(0\);距离越近时,分子越接近 \(0\),函数值越接近 \(1\);当 \(x=l^{(i)}\) 时,函数值取到最大值。因此,我们自然而然地想到可以取训练集中的样本点作为地标,有 \(m\) 个样本就取 \(m\) 个地标。这里不需要区分正负样本点,因为在核函数 \(\phi^{\left( i \right)} \left( x \right)\) 前面还有一个可学习的 \(\theta^{(i)}\),对于不同样本会自动区分。注意到 \(\sigma\) 较大时,变化也较为平缓,模型可能会欠拟合,造成高偏差;反之则可能会造成过拟合。
假设我们原来用 \(x^{\left( i \right)}=\left\{ 1,x_{1}^{\left( i \right)},x_{2}^{\left( i \right)},\cdots ,x_{n}^{\left( i \right)} \right\} \in \mathbb{R} ^{n+1}\) 来描述第 \(j\) 个样本的特征向量,则现在就是使用: \[ f\left( x^{\left( i \right)} \right)=\left[ \begin{array}{c} 1\\ \phi _1\left( x^{\left( i \right)} \right)\\ \phi _2\left( x^{\left( i \right)} \right)\\ \vdots\\ \phi _i\left( x^{\left( i \right)} \right)\\ \vdots\\ \phi _m\left( x^{\left( i \right)} \right)\\ \end{array} \right] =\left[ \begin{array}{c} 1\\ \mathrm{Sim}\left( x^{\left( i \right)},l^{\left( 1 \right)} \right)\\ \mathrm{Sim}\left( x^{\left( i \right)},l^{\left( 2 \right)} \right)\\ \vdots\\ \mathrm{Sim}\left( x^{\left( i \right)},l^{\left( i \right)} \right) =1\\ \vdots\\ \mathrm{Sim}\left( x^{\left( i \right)},l^{\left( m \right)} \right)\\ \end{array} \right] \in \mathbb{R} ^{m+1} \]
Scikit-learn 练习
在实际运用 SVM 时,我们通常会调用现成的机器学习第三方库,比较经典的就有 Python 中的 Scikit-learn,其调用支持向量分类器的函数如下:
1 |
|
该函数的实现基于 libsvm,其中二次规划问题的解决算法是 SMO,通常需要调节的参数如下:
C
:正则化参数,取值越大,对松弛变量(误分类的代价函数)的惩罚越大,适用于训练集几乎可分的情况,此时训练集上的准确率较高,但泛化能力弱(过拟合)。kernel
:默认取rbf
径向基函数(高斯核),可选linear
线性核、poly
多项式核、sigmod
等。gamma
:核函数系数,默认为 auto,取样本特征数的倒数。probablity
:是否启用概率估计,即最后的输出会包含属于每个类的概率值。
下面以 Coursera 上的数据集 ex6data1.mat
为例,这是一个线性可分的数据集:
使用如下代码:
1 |
|
训练结果如下:
此外还有一个非线性可分的数据集ex6data2.mat
:
使用如下代码:
1 |
|
训练结果如下: