1 引 言

在前面几章中,掌柜已经陆续介绍了多种分类算法模型,相信各位读者朋友对于机器学习也算是有了一定的了解。在接下来的这一些列文章中,掌柜将开始逐步介绍下一个分类模型——支持向量机。支持向量机(Support Vector Machine, SVM)可以算得上是机器学习算法中最为经典的模型。之所以称之为经典是因为支持向量机的背后有着完美的数学推导与证明。当然,也正是因为这个原因使得学习SVM有着较高的门槛。因此,在接下来的内容中,掌柜将会尽可能以最通俗的表达来介绍SVM中的相关原理。

2 支持向量机

2.1 SVM思想

什么是支持向量机呢?初学者刚接触到这个算法时基本上都会被这个名字所困扰,到底什么叫“向量机”,听起来总觉得怪怪的。因此首先需要明白的是,支持向量机其实和“机”一点关系也没有,算法的关键在于“支持向量”。如图1所示为4种不同模型对同一个数据集分类后的决策边界图。可以看到尽管每个模型都能准确地将数据集分成两类,但是从各自的决策边界到两边样本点的距离来看却有着很大的区别。

图 1. 不同模型决策边界

为了能更加清楚的进行观察,下面将4个决策边界放到一张图中,如图2所示。

图 2. 决策边界图

如图2所示,图中左边从上到下分别为模型(d)(a)(b)(c)在数据集上的决策边界。可以发现模型(c)的泛化能力应该会是最差的,因为从数据的分布位置来看真实的决策面应该是一条左高右低倾斜的直线。其次是模型(b)的泛化能力,因为从图2可以看出模型(b)的决策面太过于偏向方块形的样本点。因为在评估分类决策面优劣的一个原则就是,当没有明确的先验知识告诉我们决策面应该偏向于哪边时,最好的做法应该是居于中间位置,也就是类似于模型(a)和模型(d)的决策面。那么模型(a)和模型(d)谁又更胜一筹呢?进一步,可以将(a)和(d)这两个模型各自到两侧样本点距离可视化出来,如图3所示。

图 3. 决策边界宽度图

从图3中一眼便可以看出,模型(d)的决策面要更居于“中间”(事实上就是在中间),而模型(a)的决策面也是略微偏向于方块形的样本点。因此在这4个模型中,模型(d)的泛化能力通常情况下都会是最强的。此时有读者可能就会问,假如把模型(a)中的决策面向上平移一点,使得其也居于两条虚线之间,那么此时应该选择谁呢?答案当然依旧是模型(d),原因在于模型(d)的决策面还满足另外一个条件,到两条虚线的距离最大。换句话说也就是,模型(d)中两条虚线之间的距离要大于模型(a)中两条虚线之间的距离。

说到这里,相信各位读者已经猜到,模型(d)对应的就是支持向量机模型,同时虚线上的两个样本点就被称为支持向量。可以发现,最终对决策面其决定性作用的也只有这两个样本点,说得通俗点就是仅根据这两个点就能训练得到模型(d)。

因此,这里可以得出的结论就是,通过支持向量机我们便能够得到一个最优超平面,该超平面满足到左右两侧最近样本点的间隔相同,且离左右最近样本点的间隔最大。不过那又该如何来找到这个超平面呢?

2.2 SVM原理

2.2.1超平面的表达

在正式定义距离之前,这里先回顾一下超平面的表达式

wTx+b=0(1)

其中w表示权重参数(系数),b表示截距,x表示样本点。同时需要说明的是,在SVM中,用y=+1,y=1分别来表示正样本和负样本。

从上述表达式可知,当通过某种方法找到参数w,b后,也就代表确立了超平面。不过对于SVM建模来说,应该从哪个地方入手呢? 答案是从SVM的核心思想:最大化间隔(Gap) 入手。

2.2.2函数间隔

上面说到SVM的核心思想就是最大化间隔,既然是最大化间隔那总得有个度量间隔的方法才行。根据中学知识可知,当超平面wTx+b=0确定后,可以通过|wTx+b|来表示每个样本点到超平面的相对距离,也就是说虽然实际距离不是|wTx+b|这么多,但是它依旧遵循绝对值大的离超平面更远的原则,如图4所示。

图 4. 函数间隔图

如图4所示,其中直线方程为x1+x23=0,且A,B分别为正负两个样本点,即yA=+1,yB=1,则此时有点A到直线的相对距离为|wTx+b|=|2+33|=2,点B到直线的相对距离为|wTx+b|=|1+13|=1

同时还可以注意到,只要分类正确,y(i)(wTx+b)>0就成立;或者说如果y(i)(wTx+b)>0成立,则这就意味着分类正确。并且其值越大说明其分类正确的可信度就越高,而这也是y为什么取±1的原因。所以此时可以将训练集中所有样本点到超平面的函数间隔(Functional Margin)定义为[1]

γ^(i)=y(i)(wTx(i)+b)(2)

且定义训练集中样本点到超平面的函数间隔中的最小值为

γ^=mini=1,2,...,mγ^(i)(3)

但是此时可以发现,如果在式(1)的两边同时乘以k(k0),虽然此时超平面并没有发生改变,但是相对距离却变成了之前的k倍。所以仅有函数间隔显然不能够唯一确定这一距离,还需要引入另外一种度量方式——几何间隔。

2.2.3 几何间隔

所谓几何间隔(Geometric Margin),就是样本点到直线实实在在的距离。只要直线不发生改变,那么间隔就不会发生任何改变,这样就避免了在函数间隔中所存在的问题。那么应该如何来表示几何间隔呢?如图5所示,线段AB就表示样本点A到直线的真实距离。

图 5. 几何间隔图

如图5所示,直线方程为wTx+b=0A为数据集中任意一个点x(i)γ(i)A到直线的距离,可以看成是向量BA的模;W为垂直于wTx+b=0的法向量。此时便可以得到点B的坐标为

x(i)γ(i)W||W||(4)

又因为B点在直线上,所以满足

wT(x(i)γ(i)W||W||)+b=0(5)

因此可以通过化简等式(5)来得到几何距离的计算公式。不过此时的问题在于W该怎么得到?

现在,假设有一直线wTx+b=0,w=(w1,w2)T,即w1x1+w2x2+b=0,那么该直线的斜率便为k1=w1/w2。又因为W垂直于该直线,所以W的斜率为k2=w2/w1。因此W的一个方向向量为(1,k2)。进一步再同时乘以w1即可得到W=(w1,w2)=w,即W其实就是w。也就是说,如果直线wTx+b=0,那么w就是该直线的其中一条法向量。

所以根据式(5)

wT(x(i)γ(i)w||w||)+b=0(6)

因此几何距离计算公式为

γ(i)=wTx(i)+b||w||=(w||w||)Tx(i)+b||w||(7)

当然,这只是当样本A为正样本,即yA=+1时的情况,更一般地几何距离的计算公式为

γ(i)=y(i)((w||w||)Tx(i)+b||w||)(8)

故,根据图4可知,样本点A,B到直线x1+x23=0的距离分别为

γA=+1((w||w||)Tx(A)+b||w||)=((1,1)1+1)T(2,3)+31+1=2γB=1((w||w||)Tx(A)+b||w||)=((1,1)1+1)T(1,1)+31+1=12(9)

此时可以发现,同函数间隔类似只要在分类正确的情况下几何间隔也都满足条件y(i)γ(i)>0。进一步,定义训练集中样本点到超平面的几何间隔中最小值为

γ=mini=1,2,...,mγ(i)(10)

同时,函数间隔与几何间隔存在以下关系

γ=γ^||w||(11)

可以发现,几何间隔其实就是在函数间隔的基础上施加了一个约束限制。此时我们已经有了对于间隔度量的方式,所以下一步自然就是最大化这个间隔来求得分类超平面。

2.2.4 最大间隔分类器

什么是最大间隔分类器(Maximum Margin Classifiers) 呢?上面说到,有了间隔的度量方式后,接着就是最大化这一间隔,然后求得超平面wTx+b=0。最后通过函数g(wTx+b)将所有样本点输出只含{1,+1}的值,以此来完成对数据集样本的分类任务。由于g(wTx+b)就是一个分类器,又因为它是通过最大化几何间隔得来的,故将其称之为最大间隔分类器。

因为在式(10)中已经得到了几何间隔的表达式,所以再对其最大化即可

maxw,bγs.t.  y(i)((w||w||)Tx(i)+b||w||)γ,i=1,2,...m(12)

其中s.t.表示服从于约束条件。同时,式(12)的含义就是找到参数w,b,使得满足以下条件:

γ尽可能大,因为目的就是最大化γ;

② 同时要使得样本中所有的几何距离都大于γ,因为由式(10)可知γ是所有间隔中的最小值;

所以,进一步由式(11)中函数间隔与几何间隔的关系,可以将式(12)中的优化问题转化为

maxw,bγ^||w||s.t.  y(i)(wTx(i)+b)γ^,i=1,2,...m(13)

此时可以发现,约束条件由几何间隔变成了函数间隔,准确说应该既是函数间隔同样也是几何间隔。因此,既然可以看作函数间隔,那么令γ^=1自然也不会影响最终的优化结果。

所以,式(13)中的优化问题便可以再次转化为如下形式

maxw,b1||w||s.t.  y(i)(wTx(i)+b)1,i=1,2,...m(14)

但是对于(14)这样一个优化问题还是无法直接解决。不过,对于f(x)>0来说max1/f(x)就等价于minf(x),进一步也就等价于min(f(x))2,这三者求解出的x都相同。所以进一步式(14)可以将式化简为

minw,b12||w||2s.t.  y(i)(wTx(i)+b)1,i=1,2,...m(15)

之所以要进行这样的处理,是因为这样可以将其转换为一个典型的凸优化问题,并用现有的方法进行求解;而在前面乘以1/2是为了后面求导时方便,同时这也不会影响优化结果。到这一步,我们就算是搞清楚了SVM的基本思想,以及它需要求解的优化问题。

2.2.5 函数间隔的性质

在2.2.1节优化问题的化简过程中掌柜直接将函数间隔设置为了1,不过相信对于不少读者来说在这一点上仍旧比较疑惑。当然,这也是一个在学习SVM中最典型的问题,因此接下来就这点进行一个简要的说明。

假设现在有如下函数间隔

γ^=y(i)(wTx(i)+b)(16)

那么对等式(16)两边同时除以γ^便有

y(i)((wγ^)Tx(i)+bγ^)=1(17)

此时令W=wγ^,B=bγ^,便可以将(17)转化为

y(i)(WTx(i)+B)=1(18)

接着再把式(18)中的W,B换成w,b即可得到

y(i)(wTx(i)+b)=1(19)

不过需要明白的是,式(16)和式(19)中的w,b并不是同一个。

例如现有如下平面方程

2x1+4x28=0(20)

某正样本y(k)=+1的函数间隔为γ^(k)=2,所以有

+1(2x1(k)+4x2(k)8)=2(21)

进一步在等式(21)两边同时除以2有

x1(k)+2x2(k)4=1(22)

虽然此时的w,b同时都缩小了两倍,函数间隔变成了1,但是2x1+4x28=0x1+2x24=0所表示的依旧是同一个平面。所以此时可知,wTx(i)+b=0WTx(i)+B=0代表的是同一个平面,故可以直接由式(16)得到式(19),也就是说同一个平面与用什么字母表示无关。因此可以将函数间隔直接设为1(实质是同时除以了函数间隔)。

2.2.6 小结

在本节中,掌柜首先通过一个引例介绍了支持向量机的核心思想;接着介绍了支持向量机中衡量间隔的两种度量方式,即函数间隔和几何间隔;然后介绍了如何通过结合函数间隔与几何间隔来建模支持向量机的优化问题;最后还介绍了SVM中的一个经典问题,函数间隔为什么可以设为1。

3 SVM示例代码与线性不可分

在前面两节内容中,掌柜介绍了支持向量机的基本思想以及对应的数学原理。不过说一千道一万,还是不如自己亲手来做一做。在接下来的内容中,掌柜将首先介绍如何通过sklearn来搭建相应的SVM分类模型,然后将接着介绍如何处理SVM中的线性不可分问题。

3.1 线性SVM示例代码

在sklearn中可以通过from sklearn.svm import SVC这句代码就能够导入SVM分类模型了。有读者可能会觉得奇怪,为什么导入的是一个叫SVC的东西?这是因为其实SVM不仅可以用来分类,它同样也能用于回归问题,因此SVC其实就是支持向量分类的意思。

点击进入SVC定义的地方便可以发现里面有很多超参数可以进行设置

在上述代码中只列举了SVM中常见的一些超参数。不过这里暂时只对kernel这个参数进行介绍,其它的参数等介绍完相关原理后再进行解释。根据前面两节内容可知SVM是一个线性分类器,因此这里只需要将参数kernel设置为kernel='linear'便能达到这一目的。

在完成SVC的导入工作后,根据如下代码便可以使用线性SVM进行分类建模,完整实例代码参见Book/Chapter09/01_linear_svm.py文件。

上述代码就是通过sklearn实现线性SVM的全部代码。可以看出,在sklearn中使用一个模型的步骤依旧是掌柜在5.3.1节中总结的3步走:建模、训练和预测。同时,由于这里的超参数kernel暂时只有一个取值,因此也不需要进行模型选择。从最后在测试集上的结果来看,线性SVM分类器的表现在准确率上有着不错的结果。

3.2 从线性不可分谈起

根据2节内容中SVM的思想来看,到目前为止谈到的情况都是线性可分的,也就是说总能找到一个超平面将数据集分开。可事实上却是,在大多数场景中各个类别之间都是线性不可分的,即类似如图6所示的情况。

图 6. SVM线性不可分图

对于图6中这种情况应该怎么才能将其分开呢?在4.2.4节中掌柜介绍过,这类问题可以使用特征映射的方法将原来的输入特征映射到更高维度的空间,然后再找寻一个超平面将数据集中不同类别的样本进行分类,如图7所示。

图 7. SVM特征映射图

如图7所示,现在我们已经用一个超平面完美的将不同类别的样本进行了分开。不过此时有读者可能会疑惑到这还是刚刚的数据集么?之前明明在二维平面,现在却跑到三维空间。虽然数据集确确实实已经不是同一个数据集了,但是每个数据样本所对应的类别却依旧和原来的一样,只不过现在给它穿上了一件“马甲”。也就是说,假如x(i)是正样本,那么它穿上马甲变成x^(i)后仍然属于正样本,只要能把x^(i)进行正确分类,那么自然也就能够对x(i)进行分类。

在介绍完特征映射的基本思想后,下面掌柜就来介绍如何在SVM中将低维特征映射到高维空间中。

3.3 将低维特征映射到高维空间

所谓将低维特征映射到高维空间指的是用一定的映射关系,将原始特征映射到更高维度的空间。比如通过一个函数ϕ(x)将一维特征x映射到三维特征x,x2,x3。在这里,掌柜先直接给出SVM中权重w的计算解析式,其具体由来可参见后续内容。

w=i=1mαiy(i)x(i)(23)

根据式(23)可知,假如此时已求得αib,那么对一个新输入的样本点其预测结果为

wTx+b=i=1mαiy(i)x(i)x+b=i=1mαiy(i)x(i),x+b(24)

其中x(i)表示训练集中的样本点(其实就是支持向量),x为新输入的样本点;a,b表示a,b之间的内积(Inner Products)。当且仅当式(24)大于0时,新输入样本x的类别为y=1

按照上面提到的通过函数ϕ(x)将低维映射到高维的思想,只需要在预测时将之前的x,全部替换成ϕ(x),则此时有

y=i=1mαiy(i)x(i),x+b=i=1mαiy(i)ϕ(x(i)),ϕ(x)+b(25)

虽然这样一来算是一定程度上解决了SVM中线性不可分的难题,但是又出现了一个新的问题——“维度爆炸”。

假设现有数据集X,其样本点x(i)有3个维度,分别为x1(i),x2(i),x3(i)(下面简写为x1,x2,x3)。现通过函数ϕ(x)将其映射到某个9维空间中,且假设映射后的9个维度分别为x1x1,x1x2,x1x3,x2x1,x2x2,x2x3,x3x1,x3x2,x3x3。如果此时要对新样本z进行预测,则首先需要对ϕ(x),ϕ(z)进行计算

ϕ(x)=[x1x1,x1x2,x1x3,x2x1,x2x2,x2x3,x3x1,x3x2,x3x3]Tϕ(z)=[z1z1,z1z2,z1z3,z2z1,z2z2,z2z3,z3z1,z3z2,z3z3]Tϕ(x),ϕ(z)=[x1x1z1z1+x1x2z1z2++x3x3z3z3](26)

此时各位读者应该会发现这个过程的计算量太大了,整体复杂度为o(n2)(分别为o(n2),o(n2),o(n)),其中n为特征的维数。因此,若是在高维数据中进行更为复杂的映射,那么整个过程的时间复杂度将不可想象,而这就是“维度爆炸”。但是此时我们仔细想一想,“映射”和“预测”之间到底是什么关系?“映射”是作为一种思想将低维映射到高维,从而解决线性不可分到可分的问题;而“预测”时所计算的则是ϕ(x),ϕ(z),但说穿了它就是一个值。不管最后采用的是什么样的映射规则,在预测时都只需要计算这么一个值。因此,假如能通过某种“黑箱”直接计算出这一个值岂不最好?那有没有这样的黑箱呢?当然有,这一“黑箱”操作就称为核函技巧(Kernel Trick)。

3.4 SVM中的核技巧

X是输入空间(欧式空间Rn的子集或离散集合),又设H为特征空间(希尔伯特空间),如果存在一个从XH的映射ϕ(x):XH使得对所有x,zX,函数K(x,z)满足条件K(x,z)=ϕ(x)ϕ(z),则称K(x,z)为核函数,ϕ(x)称为映射函数[2]。

说得简单点就是,存在某个映射能够找到一个与之对应的核函数K(x,z)用来代替计算ϕ(x),ϕ(z),从而避免了上面出现“维度爆炸”的问题。因此,核函数可以看作是实现“黑箱”操作(核技巧)的工具。

现假设式(26)中的两个样本点分别为x=(1,2,3),z=(2,3,4),则此时有