支持向量机

1.前言

支持向量机(Support Vector Machine)是常用的分类模型,其核心思想是求解超平面使得数据集分成两堆,其中一堆是正例,另一堆是反例。但能够将数据集D分开的超平面存在很多个,如下图所示,我们应该如何选择最优超平面呢?

支持向量机SVM算法推导及实现
从直觉上看,粗线应该是最优超平面,因为正反例样本距离超平面最远、间隔最大。间隔越大,说明分类越准确,置信度越高。

在样本空间中,划分超平面可以通过如下线性方程来描述:
ωTx+b=0 \omega ^T \mathbf{x}+b=0
其中,ω=(ω1,ω2,...,ωk)\mathbf{\omega} = (\omega_1,\omega_2,...,\omega_k)为法向量,决定了超平面方向;b为位移项,决定了超平面与原点之间的距离。显然,正反例样本到超平面的距离与法向量、位移项有关。于是做出如下定义:

对于任意一点(xi,yi)(x_i,y_i)yi{1.1}y_i \in \{-1.1\},其到超平面ωTx+b=0\omega ^T \mathbf{x}+b=0的距离可定义为yi(ωTxi+b)y_i(\omega ^ Tx_i+b)。选择好划分超平面后,正反两类样本中到超平面距离最近的样本点被称为支持向量,其到超平面的距离被称为间隔,如下图。

支持向量机SVM算法推导及实现

其中带圆圈的样本为支持向量,虚线之间的空白部分为间隔。间隔有两种定义:

  • 函数间隔
    γ=yi(ωTxi+b) \gamma = y_i(\omega^T x_i + b)

  • 几何间隔
    γ^=γω \hat{\gamma}=\frac{\gamma}{||\omega||}

函数间隔易受ω||\omega||影响,但超平面方程同除ω|| \omega ||,超平面不变,其间隔也应该不变,所以引入几何间隔来表示点到超平面距离。

2.线性可分支持向量机

线性可分是指一定存在某一个超平面使得数据集完全正确地分成正反两类,前言中图片展示的就是一个线性可分数据集。当然也存在一些数据集,比如异或关系的数据集,无法由一个平面来进行划分,可能需要曲面才能够划分,这样的数据集称为线性不可分

线性可分支持向量机正是用来解决线性可分数据集分类问题的,其原始问题形式如下:
maxω,b  γ^s.t. yi(ωTxi+b)γ,i=1,2,...,n \begin{aligned} &\max_{\omega,b} \space \space \hat{\gamma}\\ &s.t. \space y_i(\omega^Tx_i+b) \ge \gamma,i=1,2,...,n \end{aligned}
又因为γ^=γω\hat{\gamma}=\frac{\gamma}{||\omega||},不妨取γ=1\gamma=1,通过调整ω\omega来调整几何间隔。于是问题等价于
maxω,b  1ωs.t. yi(ωTxi+b)1,i=1,2,...,n \begin{aligned} & \max_{\omega,b} \space \space \frac{1}{||\omega||}\\ & s.t. \space y_i(\omega^Tx_i+b) \ge 1,i=1,2,...,n \end{aligned}
将上式转化为最小值问题:
minω,b  12ω2s.t. yi(ωTxi+b)1,i=1,2,...,n \begin{aligned} & \min_{\omega,b} \space \space \frac{1}{2}||\omega||^2\\ & s.t. \space y_i(\omega^Tx_i+b) \ge 1,i=1,2,...,n \end{aligned}
此时由于这是一个条件约束极值问题,转化为对偶问题:

  • 拉格朗日函数

    对于不等式约束条件下最小值拉格朗日函数通用形式为
    minxf(x)s.t. hi(x)<0,gi(x)=0,i=1,...,nL(x,a,λ)=f(x)+i=1naihi(x)+i=1nλigi(x) and ai0 \begin{aligned} &\min_{x} f(x)\\ &s.t. \space h_i(x) \lt 0,\\ & g_i(x)=0,i=1,...,n\\ &\Rightarrow L(x,a,\lambda)=f(x)+\sum_{i=1}^na_ih_i(x) + \sum_{i=1}^n \lambda_ig_i(x) \space and \space a_i \ge 0 \end{aligned}
    于是原始问题拉格朗日函数为
    L(ω,b,a)=12ω2+i=1nai[1yi(ωTxi+b)], ai0 L(\omega,b,a) = \frac{1}{2}||\omega||^2 + \sum_{i=1}^n a_i[1-y_i(\omega^Tx_i+b)], \space a_i \ge 0

  • 原始问题可转化为极小极大问题

    对于拉格朗日函数L(x,a,λ)=f(x)+i=1naihi(x)+i=1nλigi(x) and ai0L(x,a,\lambda)=f(x)+\sum_{i=1}^na_ih_i(x) + \sum_{i=1}^n \lambda_ig_i(x) \space and \space a_i \ge 0有,
    maxai0,λiL(x,a,λ)={f(x),hi(x)>0 or gi(x)̸=0,hi(x)0 and gi(x)=0 \max_{a_i \ge 0,\lambda_i}L(x,a,\lambda) = \left\{ \begin{aligned} & f(x),&h_i(x)\gt 0 \space or \space g_i(x) \not = 0\\ & \infin, &h_i(x)\le 0 \space and \space g_i(x)=0 \end{aligned} \right.
    显然,当不满足约束条件时,拉格朗日函数第二部分或者第三部分最大值趋于无穷大;当满足约束条件时,拉格朗日函数最大值为函数值f(x),于是取其最小值得
    minω,bmaxai0L(ω,b,a) \min_{\omega,b} \max_{a_i \ge 0} L(\omega,b,a)

  • 对偶问题极大极小问题
    maxai0minω,bL(ω,b,a) \max_{a_i \ge 0} \min_{\omega, b} L(\omega, b, a)
    ψ(a)=minω,bL(ω,b,a)\psi(a)=\min_{\omega,b} L(\omega,b,a),拉格朗日函数求偏导得
    Lω=ωi=1naiyixiLb=i=1naiyi \begin{aligned} &\frac{\partial L}{\partial \omega}=\omega - \sum_{i=1}^na_iy_ix_i\\ &\frac{\partial L}{\partial b}=-\sum_{i=1}^na_iy_i \end{aligned}

    令偏导为0,可得ω=i=1naiyixii=1naiyi=0,\omega=\sum_{i=1}^na_iy_ix_i,\sum_{i=1}^na_iy_i=0,带入ψ(a)\psi(a)
    ψ(a)=12i=1nj=1naiyiajyjxixj+i=1nai \psi(a)=-\frac{1}{2}\sum_{i=1}^n\sum_{j=1}^n a_iy_i \cdot a_jy_j \cdot x_ix_j+\sum_{i=1}^na_i
    于是,问题转化为
    maxa ψ(a)s.t.i=1naiyi=0,      ai0,i=1,2,...,n \begin{aligned} &\max_a \space \psi(a) \\ &s.t. \sum_{i=1}^na_iy_i=0,\\ &\space \space \space \space \space \space a_i \ge 0,i=1,2,...,n \end{aligned}
    将上述问题转化为最小值问题得
    mina 12i=1nj=1naiyiajyjxixji=1nais.t.i=1naiyi=0,      ai0,i=1,2,...,n \begin{aligned} &\min_a \space \frac{1}{2}\sum_{i=1}^n\sum_{j=1}^n a_iy_i \cdot a_jy_j \cdot x_ix_j-\sum_{i=1}^na_i \\ &s.t. \sum_{i=1}^na_iy_i=0,\\ &\space \space \space \space \space \space a_i \ge 0,i=1,2,...,n \end{aligned}
    由此,得出线性支持向量机的最终问题形式,这种形式的极值问题采用SMO算法求解,在后面会谈到。最终得到的决策规则形式为
    f(x)=sign(i=1naiyixix+b) f(x)=sign(\sum_{i=1}^na_iy_ix_i \cdot x + b)
    其中,选择支持向量0<αi<C0 \lt \alpha_i \lt C,则b=yij=1najyjxjxib=y_i - \sum_{j=1}^na_jy_jx_j \cdot x_i

3.线性支持向量机

对于线性不可分数据集,如果存在一个划分超平面使得大部分点都能正确划分,只有比较少的点错误,那么可以使用线性支持向量机解决这个问题。在前面线性可分支持向量机中讲过,数据集中所有点到超平面的距离都应该大于函数间隔,但对于线性不可分数据集而言,定义软间隔,在函数间隔的基础上设置松弛变量,使分类器能够接受一定的错误分类。如下图所示,红色圆圈中的样本点都是存在松弛变量的,用形式化公式表示yi(ωTxi+b)1ξiξi0,y_i(\omega^Tx_i+b)\ge1-\xi_i,\xi_i \ge 0,其中ξi\xi_i为松弛变量。显然,我们希望松弛变量越小越好。
支持向量机SVM算法推导及实现
于是,线性支持向量机原始问题为
minω,b,ξ  12ω2+Ci=1nξis.t. yi(ωTxi+b)1ξi,ξi0,i=1,2,...,n and C>0 \begin{aligned} & \min_{\omega,b,\xi} \space \space \frac{1}{2}||\omega||^2+C\sum_{i=1}^n\xi_i\\ & s.t. \space y_i(\omega^Tx_i+b) \ge 1-\xi_i,\xi_i \ge 0,i=1,2,...,n \space and \space C>0 \end{aligned}
转化为对偶问题

  • 拉格朗日函数
    L(ω,b,ξ,a,μ)=12ω2+Ci=1nξi+i=1nai[1ξiyi(ωTxi+b)]i=1nμiξi L(\omega,b,\xi,a,\mu)=\frac{1}{2}||\omega||^2+C\sum_{i=1}^n\xi_i+\sum_{i=1}^na_i[1-\xi_i-y_i(\omega^Tx_i+b)]-\sum_{i=1}^n\mu_i\xi_i

  • 原始问题极小极大问题
    minω,b,ξmaxai0,μi0L(ω,b,ξ,a,μ) \min_{\omega,b,\xi} \max_{a_i \ge 0, \mu_i \ge 0} L(\omega,b,\xi,a,\mu)

  • 对偶问题极大极小问题

maxai0,μi0minω,b,ξL(ω,b,ξ,a,μ) \max_{a_i \ge 0, \mu_i \ge 0} \min_{\omega,b,\xi} L(\omega,b,\xi,a,\mu)

​ 拉格朗日函数求偏导分别为
Lω=ωi=1naiyixiLb=i=1naiyiLξi=Caiμi \begin{aligned} &\frac{\partial L}{\partial \omega}=\omega - \sum_{i=1}^na_iy_ix_i\\ &\frac{\partial L}{\partial b}=-\sum_{i=1}^na_iy_i\\ &\frac{\partial L}{\partial \xi_i}=C-a_i-\mu_i \end{aligned}
​ 令偏导为0,并带入原问题有
mina 12i=1nj=1naiyiajyjxixji=1nais.t. i=1naiyi=0,      0aiC,i=1,2,...,n \begin{aligned} &\min_a \space \frac{1}{2}\sum_{i=1}^n\sum_{j=1}^n a_iy_i \cdot a_jy_j \cdot x_ix_j-\sum_{i=1}^na_i \\ &s.t. \space \sum_{i=1}^na_iy_i=0,\\ &\space \space \space \space \space \space 0 \le a_i \le C,i=1,2,...,n \end{aligned}
从另一个角度看,原始问题中12ω2\frac{1}{2}||\omega||^2表示第二范数,属于正则项,Ci=1mξiC\sum_{i=1}^m\xi_i表示经验风险,其中ξi=max{0,1yi(ωTxi+b)}\xi_i=\max\{0,1-y_i(\omega^Tx_i+b)\}表示hinge损失函数。当然损失函数可以换成其他的,那么相应地转换为其他模型算法,后续再谈。

4.非线性支持向量机

​ 之前介绍的算法都不能解决真正的线性不可分数据集问题。考虑到机器学习算法效果是依赖于数据表现形式的,换个角度思考线性不可分问题,在原始维度空间无法找到超平面进行线性划分,但是当进行维度变换时,一定能够找到一个更高维度特征空间能够进行线性划分,这是由模式识别理论证明过的,如下图所示。数据集在直角坐标系中无法用直线完全正确地划分,但是当转换为极坐标系时,却能够进行线性划分。

支持向量机SVM算法推导及实现

​ 那么如何进行维度变换呢?从之前导出的问题最终形式可以看出,样本数据通过xixjx_i \cdot x_j形式整合到模型算法中。于是假设通过维度变换后样本数据整合形式为ϕ(xi)ϕ(xj)\phi(x_i) \cdot \phi(x_j),但是由于维度变换后特征向量维度不定,直接使用內积计算效率比较低。举例来说,原始样本空间中x=[x1,x2,...,xn]Tx=[x_1,x_2,...,x_n]^T,经过维度变换后ϕ(x)=[x1x1,x1x2,...,x1xn,...,xnx1,...,xnxn]\phi(x) =[x_1x_1,x_1x_2,...,x_1x_n,...,x_nx_1,...,x_nx_n],于是k(x,l)ϕ=(x)ϕ(l)=i=1nj=1n(xixj)(lilj)=i=1n(xili)j=1n(xjlj)=(xTl)2k(x,l)\phi=(x) \cdot \phi(l)=\sum_{i=1}^n\sum_{j=1}^n(x_ix_j)(l_il_j)=\sum_{i=1}^n(x_il_i) \sum_{j=1}^n(x_jl_j)=(x^Tl)^2。因此,核函数K(x,l)K(x,l)时间复杂度为O(n)优于升维后內积。

(1)核函数定义

​ 在举例中k(x,l)=(xTl)2k(x,l)=(x^Tl)^2就是一个核函数,核函数指能够简化经过隐式维度变换后空间內积计算的函数。以下对核函数做出定义:

χ\chi为输入空间,k(,)k(\cdot,\cdot)是定义在χ×χ\chi \times \chi上的对称函数,则K是核函数当且仅当对于任意数据D={x1,x2,...,xm}D=\{x_1,x_2,...,x_m\}有,“核矩阵”K始终是半正定的:
K=[k(x1,x1)k(x1,x2)...k(x1,xm)k(x2,x1)k(x2,x2)...k(x2,xm)..................k(xm,x1)k(xm,x2)...k(xm,xm)] K=\left[ \begin{matrix} k(x_1,x_1)&k(x_1,x_2)&...&k(x_1,x_m)\\ k(x_2,x_1)&k(x_2,x_2)&...&k(x_2,x_m)\\ .&.&...&.\\ .&.&...&.\\ .&.&...&.\\ k(x_m,x_1)&k(x_m,x_2)&...&k(x_m,x_m) \end{matrix} \right]

(2)常用核函数

​ 在举例中先确定维度变换公式,再计算出核函数,但是在现实问题中往往不能够很容易地确定维度变换公式。所以人们常常从归纳总结出的常用核函数中,根据不同的问题和参数选择不同的核函数。常用核函数如下:

  • 多项式核函数:适合正交归一化数据
    k(x,z)=(xz+1)p k(x,z)=(x \cdot z+1)^p

  • 高斯核函数:径向基核函数,适用性广,鲁棒性好,对参数敏感
    k(x,z)=exp{xz22δ2} k(x,z)=exp\{-\frac{||x-z||^2}{2\delta^2}\}

  • ANOVA核函数:适用于多维回归问题
    k(x,z)=exp(δ(xkyk)2)d k(x,z)=exp(-\delta(x^k-y^k)^2)^d

  • sigmoid核函数:广泛应用于深度学习
    k(x,z)=tanh(αxz+c) k(x,z)=tanh(\alpha x \cdot z+c)

  • 对数核:多用于图像分割
    k(x,z)=log(1+xzd) k(x,z)=-log(1+||x-z||^d)

  • 直方图交叉核:多用于图像分类
    k(x,z)=k=1nmin{xk,zk} k(x,z)=\sum_{k=1}^n\min\{x_k,z_k\}

5.SMO算法

​ SMO算法是一种启发式算法,用于快速解决凸二次优化问题。其基本思路是,如果所有变量都能够满足最优化问题KKT条件,那么最优化问题就能够求解出。选择所有变量中最不符合KKT条件的变量α1\alpha_1,另一个变量α2\alpha_2随着α1\alpha_1的变化而变化,选择使α1\alpha_1变化最大的α2\alpha_2,其他所有变量固定不变。由此求解这个二次优化问题,不断逼近最优解。

算法推导过程:

K=i=3naiyiK=\sum_{i=3}^na_iy_i,并代入约束条件i=1nαiyi=0\sum_{i=1}^n\alpha_iy_i=0
α2y2=(α1y1K) \alpha_2y_2 = (-\alpha_1y_1 - K)
对偶问题展开可得
minα12(α1y1x1+α2y2x2+i=3nαiyixi)(α1y1x1+α2y2x2+j=3nαjyjxj)i=1nαiminα12[α12k(x1,x1)+2α1y1α2y2k(x1,x2)+α22k(x2,x2)+2(α1y1x1+α2y2x2)i=3nαiyixi+i=3nj=3nαiyiαjyjxixj]i=1nαi \min_{\alpha} \frac{1}{2}(\alpha_1y_1x_1+\alpha_2y_2x_2 + \sum_{i=3}^n\alpha_iy_ix_i)(\alpha_1y_1x_1+\alpha_2y_2x_2 + \sum_{j=3}^n\alpha_jy_jx_j) - \sum_{i=1}^n\alpha_i\\ \Rightarrow \min_{\alpha}\frac{1}{2}[\alpha_1^2k(x_1,x_1)+2\alpha_1y_1\alpha_2y_2k(x_1,x_2)+\alpha_2^2k(x_2,x_2)+2(\alpha_1y_1x_1+\alpha_2y_2x_2)\sum_{i=3}^n\alpha_iy_ix_i+\sum_{i=3}^n\sum_{j=3}^n \alpha_iy_i \cdot \alpha_jy_j \cdot x_ix_j] - \sum_{i=1}^n\alpha_i\\
L=i=3nj=3nαiyiαjyjxixj, P=i=3nαiyixiL=\sum_{i=3}^n\sum_{j=3}^n \alpha_iy_i \cdot \alpha_jy_j \cdot x_ix_j,\space P=\sum_{i=3}^n\alpha_iy_ix_i,并代入对偶问题得
minα12{α12k(x1,x1)2(α12+Kα1y1)k(x1,x2)+(α1y1+K)2k(x2,x2)+2[α1y1(x1x2)Kx2]P+L}i=1nαiminα12{α12[k(x1,x1)2k(x1,x2)+k(x2,x2)]+α1[2Ky1k(x1,x2)+2Ky1k(x2,x2)+2y1(x1x2)P2(1y1/y2)]} \min_{\alpha} \frac{1}{2}\{\alpha_1^2k(x_1,x_1)-2(\alpha_1^2+K\alpha_1y_1)k(x_1,x_2)+(\alpha_1y_1+K)^2k(x_2,x_2)+2[\alpha_1y_1(x_1-x_2)-Kx_2]P+L\}-\sum_{i=1}^n\alpha_i\\ \Rightarrow \min_{\alpha}\frac{1}{2}\{\alpha_1^2[k(x_1,x_1)-2k(x_1,x_2)+k(x_2,x_2)]+\alpha_1[-2Ky_1k(x_1,x_2)+2Ky_1k(x_2,x_2)+2y_1(x_1-x_2) \cdot P - 2(1-y_1/y_2)]\}
α1\alpha_1求导可得
α1new=Ky1k(x1,x2)Ky1k(x2,x2)y1(x1x2)P+(1y1/y2)k(x1,x1)2k(x1,x2)+k(x2,x2)=y1(α1y1+α2y2)[k(x1,x2)k(x2,x2)]y1(x1x2)i=1nαiyixi+y1(x1x2)(α1y1x1+α2y2x2)+1y1y2k(x1,x1)2k(x1,x2)+k(x2,x2)=α1[k(x1,x1)2k(x1,x2)+k(x2,x2)]y1[i=1nαiyik(x1,xi)i=1nαiyik(x2,xi)]+1y1y2k(x1,x1)2k(x1,x2)+k(x2,x2)=α1yi[i=1nαiyik(x1,xi)i=1nαiyik(x2,xi)]1+y1y2k(x1,x1)2k(x1,x2)+k(x2,x2) \begin{aligned} \alpha_1^{new}&=&\frac{Ky_1k(x_1,x_2)-Ky_1k(x_2,x_2)-y_1(x_1-x_2) \cdot P + (1-y_1/y_2)}{k(x_1,x_1)-2k(x_1,x_2)+k(x_2,x_2)}\\ &=&\frac{-y_1(\alpha_1y_1+\alpha_2y_2)[k(x_1,x_2)-k(x_2,x_2)]-y_1(x_1-x_2)\sum_{i=1}^n\alpha_iy_ix_i+y_1(x_1-x_2)(\alpha_1y_1x_1+\alpha_2y_2x_2)+1-y_1y_2}{k(x_1,x_1)-2k(x_1,x_2)+k(x_2,x_2)}\\ &=&\frac{\alpha_1[k(x_1,x_1)-2k(x_1,x_2)+k(x_2,x_2)]-y_1[\sum_{i=1}^n\alpha_iy_ik(x_1,x_i)-\sum_{i=1}^n\alpha_iy_ik(x_2,x_i)]+1-y_1y_2}{k(x_1,x_1)-2k(x_1,x_2)+k(x_2,x_2)}\\ &=&\alpha_1-\frac{y_i[\sum_{i=1}^n\alpha_iy_ik(x_1,x_i)-\sum_{i=1}^n\alpha_iy_ik(x_2,x_i)]-1+y_1y_2}{k(x_1,x_1)-2k(x_1,x_2)+k(x_2,x_2)} \end{aligned}
进一步地,因为k(x1x2,x1x2)=k(x1,x1)2k(x1,x2)+k(x2,x2)y12=1,k(x_1-x_2,x_1-x_2)=k(x_1,x_1)-2k(x_1,x_2)+k(x_2,x_2),y_1^2=1
α1new=α1y1[i=1nαiyik(x1,xi)i=1nαiyik(x2,xi)](y12y1y2)k(x1x2,x1x2)=α1y1{[i=1nαiyik(x1,xi)+by1][i=1nαiyik(x2,xi)+by2]}k(x1x2,x1x2) \begin{aligned} \alpha_1^{new}&=&\alpha_1-\frac{y_1[\sum_{i=1}^n\alpha_iy_ik(x_1,x_i)-\sum_{i=1}^n\alpha_iy_ik(x_2,x_i)]-(y_1^2-y_1y_2)}{k(x_1-x_2,x_1-x_2)}\\ &=&\alpha_1-\frac{y_1\{[\sum_{i=1}^n\alpha_iy_ik(x_1,x_i)+b-y_1]-[\sum_{i=1}^n\alpha_iy_ik(x_2,x_i)+b-y_2]\}}{k(x_1-x_2,x_1-x_2)} \end{aligned}
η=k(x1x2,x1x2)Ei=g(xi)yi=j=1nαjyjk(xi,xj)+byi,\eta = k(x_1-x_2,x_1-x_2),E_i=g(x_i)-y_i=\sum_{j=1}^n\alpha_jy_jk(x_i,x_j)+b-y_i,其中EiE_i表示预测值与真实值之间误差。于是
α1new=α1oldy1(E1E2)η \alpha_1^{new} = \alpha_1^{old}-\frac{y_1(E_1-E_2)}{\eta}

α2new=y2[(α1oldα1new)y1+α2oldy2]=α2old+y1y2(α1oldα1new) \alpha_2^{new} = y_2[(\alpha_1^{old}-\alpha_1^{new})y_1+\alpha_2^{old}y_2]=\alpha_2^{old}+y_1y_2(\alpha_1^{old}-\alpha_1^{new})

进一步地,α1,α2\alpha_1,\alpha_2应该满足约束条件0α1,α2C0 \le \alpha_1,\alpha_2 \le C,于是优化后的α1new,α2new\alpha_1^{new},\alpha_2^{new}在二维空间中图像表示如下:
支持向量机SVM算法推导及实现
故,取L与H分别为α1new\alpha_1^{new}约束下界和上界,当y1̸=y2y_1 \not= y_2
L=max{0,α1oldα2old}, H=min{C,C+α1oldα2old} L=\max\{0,\alpha_1^{old}-\alpha_2^{old}\},\space H=\min\{C,C+\alpha_1^{old}-\alpha_2^{old}\}
y1=y2y_1=y_2时,L=max{0,α1old+α2oldC}, H=min{C,α1oldα2old}L=\max\{0,\alpha_1^{old}+\alpha_2^{old}-C\},\space H=\min\{C,\alpha_1^{old}-\alpha_2^{old}\}

因此,
α1new={H,α1new>Hα1new,Lα1newHL,α1new<L \alpha_1^{new}= \begin{cases} &H,&\alpha_1^{new} \gt H\\ &\alpha_1^{new},&L\le \alpha_1^{new} \le H\\ &L,&\alpha_1^{new}<L \end{cases}

α2new=y2[(α1oldα1new)y1+α2oldy2]=α2old+y1y2(α1oldα1new) \alpha_2^{new} = y_2[(\alpha_1^{old}-\alpha_1^{new})y_1+\alpha_2^{old}y_2]=\alpha_2^{old}+y_1y_2(\alpha_1^{old}-\alpha_1^{new})

接下来,问题关键是如何选取变量α1,α2\alpha_1,\alpha_2,先选取违反KKT条件的变量作为α1\alpha_1,再选取E1E2|E_1-E_2|最大的变量作为α2\alpha_2。其中KKT条件为
αi=0yig(xi)10<αi<Cyig(xi)=1αi=Cyig(xi)1 \begin{aligned} \alpha_i = 0 &\Rightarrow& y_ig(x_i) \ge 1\\ 0 \lt \alpha_i \lt C &\Rightarrow& y_ig(x_i)=1\\ \alpha_i=C&\Rightarrow&y_ig(x_i)\le1 \end{aligned}
更新α1,α2\alpha_1,\alpha_2后,需要同时更新b,分以下情况:

  • α1,α2\alpha_1,\alpha_2中至少存在一个支持向量:b=yij=1najyjxjxib=y_i - \sum_{j=1}^na_jy_jx_j \cdot x_i,其中xix_i表示支持向量
  • α1,α2\alpha_1,\alpha_2均不是支持向量:令bi=yij=1najyjxjxib_i=y_i - \sum_{j=1}^na_jy_jx_j \cdot x_i,则b=(b1+b2)/2b=(b_1+b_2)/2

6.算法实现

import numpy as np
from math import *


class SVM(object):
    # 初始化超参数
    def __init__(self, C, kernel):
        self.C = C
        self.kernel = kernel

    # 计算g(x)值
    def g(self, x, alpha, b, trainMat, trainLabels):
        n = trainMat.shape()[0]
        return np.sum([alpha[i]*trainLabels[i]*self.kernel(x,trainMat[i]) for i in range(n)]) + b


    # 训练数据
    def train(self, trainMat, trainLabels):
        n,m = trainMat.shape()
        # 设置初值
        alpha = np.zeros((n,1))
        b = np.sum(trainLabels)/n

        # 循环训练
        while True:
            # 计算g(x)值
            G = np.array([self.g(trainMat[i], alpha, b, trainMat, trainLabels) for i in range(n)])
            # 满足KKT条件状态
            dis = np.multiarray(G, trainLabels)
            status = [ 1 if alpha[i]==0 and  dis[i] < 1 or 0< alpha[i] < self.C and dis[i] != 1 or alpha[i]==self.C and dis[i] > 1 else 0 for i in range(n)]

            # 均满足KKT条件
            if 0 == sum(status):
                break

            # 阿尔法变量1
            i = status.index(1)

            # 计算E
            E = G - trainLabels
            delta = [fabs(E[j] - E[i]) for j in range(n)]

            # 阿尔法变量2
            j = delta.index(max(delta))

            # 更新无约束最优解
            eta = self.kernel(trainMat[i]-trainMat[j], trainMat[i]-trainMat[j])
            aiNew = alpha[i] - trainLabels[i]*(E[i]-E[j])/eta

            # 约束更新
            if trainLabels[i] == trainLabels[j]:
                L = max(0, alpha[i]+alpha[j]-self.C)
                H = min(self.C, alpha[i]-alpha[j])
            else:
                L = max(0, alpha[i]-alpha[j])
                H = min(self.C, self.C+alpha[i]-alpha[j])

            if aiNew > H:
                aiNew = H
            elif aiNew < L:
                aiNew = L

            ajNew = alpha[j] + trainLabels[i]*trainLabels[j]*(alpha[i]-aiNew)

            # 更新alpha,b
            alpha[i] = aiNew
            alpha[j] = ajNew

            if 0<aiNew<self.C:
                b = trainLabels[i] - G[i] + b
            elif 0<ajNew<self.C:
                b = trainLabels[j] - G[j] + b
            else:
                b = (trainLabels[i] - G[i] + trainLabels[j] - G[j])/2 + b
        self.alpha = alpha
        self.b = b
        self.trainMat = trainMat
        self.trainLabels = trainLabels

    # 预测
    def predict(self, x):
        if self.g(x, self.alpha, self.b, self.trainMat, self.trainLabels) > 0:
            return 1
        else:
            return 0

参考资料

github代码地址https://github.com/flushest/machine-learning-practice

相关文章: