机器学习中核函数(Kernel)的理解与Kernel-SVM原理解析

第一节 由线性分类器说起

线性分类器是一种采用超平面(hyper-plane)分割数据的分类方法,对于分布是凸性的两类分类问题,线性分类器基本可以达到最优的分类效果。

典型的线性分类的场景

注意文章中的“线性分类器”和“分类平面”是同一个概念。

线性分类器的局限性

对于非凸分布的数据类,线性分类器难以对数据进行有效的分类。如下图,设任意点P=[x1,x2]T\bold P = [x_1,x_2]^T属于C1C_1C2C_2类,其分布满足方程:(散点图如下)

(1){x12+2x1x2+3x22=4if PC12x12+x1x2+2x22=1if PC2\begin{cases} x_1^2+2x_1x_2+3x_2^2=4 & \text{if } \bold P \in C_1\\[2ex] 2x_1^2+x_1x_2+2x_2^2=1 & \text{if } \bold P \in C_2 \end{cases} \tag{1}

显然,没有任何一种线性分类器可以将这两类分开。

non-convex data

如何绕过局限性

目前已经知道,线性分类器无法作用于类似上图一类“包起来”另一类的数据。现在我们有两种解决方法:

  1. 更换分类器
  2. 对数据进行处理

为了引申Kernel的意义,这里不再讨论第一种方法,只讨论第二种方法:如何对数据进行处理,使得线性分类器可以有效分开两组数据?

观察式(1)(1) ,若设点Q=[y1,y2,y3]T\bold Q=[y_1,y_2,y_3]^T,并手动定义非线性映射:

(2)y=ϕ(x):{y1=x12y2=x1x2y3=x22\bold y = \phi(\bold x): \begin{cases} y_1 = x_1^2 \\ y_2 = x_1x_2 \\ y_3 = x_2^2 \end{cases} \tag{2}

将上式代入(1)(1)中,得:

(3){y1+2y2+3y3=4if PC12y1+y2+2y3=1if PC2\begin{cases} y_1+2y_2+3y_3=4 & \text{if } \bold P \in C_1 \\[2ex] 2y_1+y_2+2y_3=1 & \text{if } \bold P \in C_2 \end{cases} \tag{3}

绘制散点图如下。可以发现,原本式(1)(1)中定义的二维的”包起来"的两类数据,被高维映射到三维空间中的两个平面(毕竟(3)(3)式为平面一般方程)上!如下图左所示。而且很明显,这两组数据在三维空间中是线性可分的!

高维映射后的数据点某一个可以分开两类的平面
高维映射后的数据点分类结果

现在对该三维空间中的数据进行线性分类。这里手动选择一个线性分类器(分类平面),如上图右半部分品红色平面所示。其分类器平面的表达式为:

(4)32y1+32y2+52y3=52\frac{3}{2}y_1+\frac{3}{2}y_2+\frac{5}{2}y_3=\frac{5}{2} \tag{4}

可以看到,该线性分类器可以很好地区分两类数据。

最后在将这个分类器映射回原始二维空间。由非线性变换(2)(2),可以将(4)(4)降为二维表达形式为:

(5)32x12+32x12x22+52x22=52\frac{3}{2}x_1^2+\frac{3}{2}x_1^2x_2^2+\frac{5}{2}x_2^2=\frac{5}{2} \tag{5}

(5)(5)图像如下图品红色曲线所示,可以看到,三维空间中的线性分类器在二维空间中是非线性的,该二维非线性分类器很好地区分了两类数据点。

Classification_result

至此我们可以得出结论,非线性可分的数据映射到高维空间后有可能变为线性可分的数据,高维映射为数据分类提供了一种新思路。

第二节 分类平面计算算法

由上一节可以看到,若对非线性可分地数据进行分类,要经过以下步骤:

  1. 手动定义高维映射,使得该数据集在映射后线性可分
  2. 在映射后的高维空间手动选取分类面,该分类面可以区分该线性可分数据集
  3. 将该分类面逆映射回原始空间,即可对原始空间中非线性可分的数据进行分类

目前这里的高维映射和分类面都是手动选取的。当然,如果它们可以通过一定算法自动选取,这将会带来很大的便利性。在这一节,先考虑如何自动选取一个分类面,使其可以区分线性可分数据。

有些读者可能已经反应过来了,SVM!SVM可以说是最好的线性分类器。下面给出SVM的具体解释,以供没反应过来的读者食用。

SVM算法简介

Overview

SVM这里仅简要说明,并列出之后所需要的公式。具体的细节还请读者查阅相关书籍和博客

对于两类分类问题,SVM的主要任务是,找到一个“最佳”分类面(Separating Hyperplane),将两类点分离。

这里“最佳”的含义是,这个分类面在保证对当前数据集正确分类(这里不讨论容许一定错误率的软间隔SVM)的前提下,同时应该满足该分类面与两类数据点中与该分类面最近的数据点的距离是最大的(The distance between the separating hyperplane and the two-class points whose distance from the hyperplane is the minimum is maximal)。这个距离被称为margin。以上“最佳”分类面的判定原则被称为最小最大化原则。

SVM的应用过程是,首先采用分类已知的数据点对SVM进行训练(即找到margin最大的分类平面),输出一个分类平面,然后对于待分类的数据(不知道其类别),通过这个分类平面进行分类。所以SVM是一个有监督的学习算法。

SVM-Planes

注:图引自:http://dni-institute.in/blogs/wp-content/uploads/2015/09/SVM-Planes.png

如上图所示,黑白两种颜色的数据点代表两类数据。这里采用SVM找到了使得margin最大化的分类平面(分类平面一定在margin中间,而不是偏向某一侧,这是因为它与两类最小距离数据点的距离都要最大化)。该平面可以很好地区分两类数据。

当然,取其他分类平面也可以很好地区分两类数据。想象一下,把上图中的分类平面稍稍倾斜一点,其实也可以将两类数据很好地分离,只不过此时的margin不是最大而已。但为什么非要取margin最大的分类平面呢?这是因为margin最大的分类平面具有最好的鲁棒性。

想象一下,假如分类平面在正确分类的前提下非常靠近上图Target=No数据点。此时输入一个待分类数据点(此时SVM已经训练完毕),这个数据点实际属于Target=No。但是因为分类平面与Targei=No数据集距离很近,所以如果这个数据点在Target=No面向分类平面的边界上,并且扰动较大,它很容易超出分类平面,被误分类到Target=Yes类。所以margin最大化使得误分类率最小化,提高了SVM分类的泛化能力。这是margin最大化的直观解释,理论上的解释需要采用VC维度,这里不再叙述。

理论推导

理论推导固然难,但是下面的式子只要求看懂它的功能,不要求搞懂推导式怎么做的。

1. 分类平面的表达式与分类方法

对于线性SVM,其分类平面的表达式为:

(6)wTx+b=0\bold w^T\bold x+b=0\tag{6}

其中xx是数据点坐标,ww是”斜率“(slope),bb是偏移(offset)。对于二维空间,ww, xx2×12\times 1的列向量,无论在多少维的空间下,bb都是常数。

分类平面的分类方法是:

(7){xC1if wTx+b1xC2if wTx+b1\begin{cases} \bold x \in C_1 & \text{if } \bold w^T\bold x+b \geq 1\\[2ex] \bold x \in C_2 & \text{if } \bold w^T\bold x+b \leq -1 \end{cases} \tag{7}

2. 如何求解分类平面

现在我们已经知道了分类平面的表达式以及采用分类平面进行分类的方法。那么对于给定的已知分类的数据集,如何找到它的分类平面呢?根据SVM理论,确定分类平面的两个必要参数w\bold w, bb只需要求解以下优化问题

(8)minw,b12w2s.t.li(wTxi+b)1,i=1,2,...,n.\begin{aligned} & \min_{\bold w,b} \frac{1}{2}||\bold w||^2 \\[2ex] & s.t. l_i(\bold w^T\bold x_i + b) \geq 1, \\[2ex] & i=1,2,...,n. \end{aligned} \tag{8}

其中nn为数据点的个数,lil_ixi\bold x_i数据点的类标(label),取值如下:

(9){li=1if xiC1li=1if xiC2\begin{cases} l_i=1 & \text{if } \bold x_i \in C_1 \\[2ex] l_i=-1 & \text{if } \bold x_i \in C_2 \end{cases} \tag{9}

此时求解出来的w\bold w​, bb​即为margin最大的分类平面的参数。

3. 转化对偶问题求解

(8)(8)的优化问题可以转化为其对偶问题

(10)maxαi=1nαi12i=1nj=1nαiαjliljxiTxjs.t.i=1nαili=0,αi0,i=1,2,...,n.\begin{aligned} \max_{\bold \alpha} \sum_{i=1}^{n}\alpha_i&-\frac{1}{2}\sum_{i=1}^{n}\sum_{j=1}^{n}\alpha_i\alpha_jl_il_j\bold x_i^T\bold x_j \\[2ex] & s.t. \sum_{i=1}^{n}\alpha_il_i=0,\\[2ex] & \alpha_i \geq 0, \\[2ex] & i=1,2,...,n. \end{aligned} \tag{10}

注意上述过程需满足KKT条件:

(11){αi0lif(xi)10αi(lif(xi)1)=0\begin{cases} \alpha_i \geq 0 \\[2ex] l_if(\bold x_i) - 1\geq 0 \\[2ex] \alpha_i(l_if(\bold x_i)-1) =0 \end{cases} \tag{11}

其中α=[α1,α2,...,αn]T\bold \alpha = [\alpha_1,\alpha_2,...,\alpha_n]^T,为拉格朗日乘子项;另外f(xi)=wTxi+bf(\bold x_i) = \bold w^T\bold x_i + b

通过这个优化问题解出α\bold \alpha之后,分类平面斜率参数w\bold w通过下式确定:

(12)w=i=1nαilixi\bold w = \sum_{i=1}^{n}\alpha_il_i\bold x_i \tag{12}

bb的确定要稍麻烦一点。观察式(11)(11)可以发现,αi\alpha_ilif(xi)1l_if(\bold x_i)-1必须至少有一个为零。此时观察式(12)(12)可以发现,αi\alpha_i为零的数据点xi\bold x_iw\bold w没有贡献。也就是说,只有αi\alpha_i不为零的数据点xi\bold x_i才对分类平面有贡献,这些数据点被称为支持向量。

bb的求解,只需要在解完对偶问题(10)(10)之后,随便取一个支持向量xsupportx_{support},联立以下方程即可得出。

(13){αsupport(lsupportf(xsupport)1)=0w=i=1nαilixif(x)=wTx+b\begin{cases} \alpha_{support}(l_{support}f(\bold x_{support})-1)=0 \\[2ex] \bold w = \sum_{i=1}^{n}\alpha_il_i\bold x_i \\[2ex] f(\bold x) = \bold w^T\bold x + b \end{cases} \tag{13}

目前公式太多可能的确有点绕,但只需要记住一点就可以了:求解对偶问题(10)(10)​,即可求解出分类平面。这是SVM的核心优化问题,也是Kernel方法的关键。

SVM算法的应用效果

我们按照该节最开始所述的三个步骤,采用SVM求解第一节中的非线性分类问题。

1. 手动定义高维映射

这一部在第一节中已经做过了,直接引用高维映射后的数据集(3)(3),这里重新贴数据图。

高维映射后的数据点

2. 采用SVM选取分类面

在上一节中我们手动选取分类面如式(4)(4)所示,这一节采用SVM选取分类面,计算得到的分类平面表达式为:

(14)0.8174y1+1.5955y2+2.4111y3=2.20960.8174y_1+1.5955y_2+2.4111y_3=2.2096 \tag{14}

分类平面的图像如下所示:

分类结果

可以看到该分类平面完美区分了两组数据点。

3. 将分类面逆映射回原始空间

根据高维映射方程(2)(2),将分类平面(12)(12)逆映射回原始二维空间。此时的分类器的表达式为:

(15)0.8174x12+1.5955x12x22+2.4111x22=2.20960.8174x_1^2+1.5955x_1^2x_2^2+2.4111x_2^2=2.2096 \tag{15}

分类器图像如下图所示:

Classification_result_using_SVM

可以看到该分类器是非线性的,并且很完美地区分两类数据点。

第三节 Kernel到底是什么

由于笔者的慢热性(追妹子也慢热),铺垫了好久才步入正题,这里是整部文章的关键(要表白了哈哈哈哈)。

目前我们已经实现自动选取分类平面的问题,并且也看到,非线性可分的数据映射到高维空间后有可能变为线性可分的数据。但是手动选取高维映射的问题还没有得到解决。

但是对于Kernel方法而言,因为kernel是人工选择的,而kernel间接定义了高维映射,所以实际上高维映射也是人工指定的。所以在这个方法里实现不了高维映射的自动选取。但是因这个间接,Kernel方法反倒带来了一些好处。

上面这一段中加粗的文字其实就是Kernel的本质。不过看不懂没关系,之后会慢慢重新引出来。

高维空间分类数据的一般过程

由第一节第二节可以看出,若寻找到一个高维映射

(16)y=ϕ(x)\bold y = \phi(\bold x) \tag{16}

使得原本线性不可分的数据x\bold x在映射后的高维空间中变得线性可分(即y\bold y线性可分),那么在原始空间构建有效分类器的方法如下图所示:

这个过程分三步进行,比较繁琐,所以可否寻找一种方法,将这三步合为一步呢?

Kernel Trick

由2.1.2我们已经知道,线性SVM的训练过程实际上就是求解优化问题(10)(10)。高维映射(15)(15)将线性不可分的x\bold x映射为线性可分的y\bold y。这里对y\bold y做SVM分类,将其代入优化问题(10)(10)中,得:

(17)maxαi=1nαi12i=1nj=1nαiαjliljyiTyjs.t.i=1nαili=0,αi0,i=1,2,...,n.\begin{aligned} \max_{\bold \alpha} \sum_{i=1}^{n}\alpha_i&-\frac{1}{2}\sum_{i=1}^{n}\sum_{j=1}^{n}\alpha_i\alpha_jl_il_j\bold y_i^T\bold y_j \\[2ex] & s.t. \sum_{i=1}^{n}\alpha_il_i=0,\\[2ex] & \alpha_i \geq 0, \\[2ex] & i=1,2,...,n. \end{aligned} \tag{17}

可以发现所有数据点y\bold y仅通过内积yiTyj\bold y_i^T\bold y_j与该优化式耦合。此时定义:(重点来了啊,敲黑板)

(18)Kij=yiTyjK_{ij} = \bold y_i^T\bold y_j \tag{18}

将式(18)(18)代入式(17)(17),得:

(19)maxαi=1nαi12i=1nj=1nαiαjliljKijs.t.i=1nαili=0,αi0,i=1,2,...,n.\begin{aligned} \max_{\bold \alpha} \sum_{i=1}^{n}\alpha_i&-\frac{1}{2}\sum_{i=1}^{n}\sum_{j=1}^{n}\alpha_i\alpha_jl_il_jK_{ij} \\[2ex] & s.t. \sum_{i=1}^{n}\alpha_il_i=0,\\[2ex] & \alpha_i \geq 0, \\[2ex] & i=1,2,...,n. \end{aligned} \tag{19}

优化式(19)(19)等价于优化式(17)(17),它们的优化结果相同。这样做貌似并没有什么卵用;但是,如果采用式(19)(19)做分类,可以发现,原本我们对数据点做1. 高维映射,然后2. 应用式(17)(17)进行分类的这两步,只需要通过定义一个KijK_{ij},就可以直接采用式(19)(19)进行优化了!两步被合为一步。

KijK_{ij},或者K(xi,xj)K(\bold x_i,\bold x_j),就是核函数,而上述替代内积的应用方法,就是Kernel Trick

对于分类器的确定如下式:

(20)g(xj)=f(ϕ(xj))=wTϕ(xj)+b=i=1nαiliyiTϕ(xj)+b=i=1nαiliϕ(xi)Tϕ(xj)+b=i=1nαiliKij+b\begin{aligned} g(\bold x_j) &= f(\phi(\bold x_j)) \\[2ex] &= \bold w^T\phi(\bold x_j) + b \\[2ex] &= \sum_{i=1}^n\alpha_il_i\bold y_i^T\phi(\bold x_j) +b \\[2ex] &= \sum_{i=1}^n\alpha_il_i\phi(\bold x_i) ^T\phi(\bold x_j) +b \\[2ex] &= \sum_{i=1}^n\alpha_il_iK_{ij} +b \end{aligned} \tag{20}

目前bb还是待定的,根据式(13)(13),联立以下方程即可求解:

(21){αsupport(lsupportf(xsupport)1)=0f(x)=i=1nαiliKi,support+b\begin{cases} \alpha_{support}(l_{support}f(\bold x_{support})-1)=0 \\[2ex] f(\bold x) = \sum_{i=1}^n\alpha_il_iK_{i,support} +b \end{cases} \tag{21}

从式(20)(20)(21)(21)可以看出,通过核函数也可以直接求解原始空间中的分类器,毋须对高维空间中的分类器逆映射至原始空间。

故核函数的定义将本节开始提到的三个步骤合为一步(即通过求解式(19)(20)(21)(19)(20)(21),直接对原始数据分类)。它使得我们不需要对原始数据做手动的高维映射然后再线性分类;而是隐式地将高维映射嵌入到SVM直接做分类:这个过程一般称作隐式映射。而采用了Kernel的SVM叫Kernel-SVM。

至此我们知道,Kernel是一个内积函数,该内积隐式(implicitly)包含了高维映射。Kernel Trick是一种用Kernel函数替换算法中内积项的方法。

一个实际的例子

Kernel间接定义了一个高维映射ϕ\phi,这里我们重现2.2中手动映射数据点后做分类的场景,只不过这里采用Kernel-SVM,而Kernel通过已有的高维映射(2)(2)定义,以比对比同一种高维映射函数在手动映射和Kernel隐式映射下,产生的分类器的异同

根据式(2)(2),定义Kernel如下:

(22)Kij=yiTyj=ϕ(xi)Tϕ(xj)=[(x1(i))2,x1(i)x2(i),(x2(i))2][(x1(j))2x1(j)x2(j)(x2(j))2]=(x1(i))2(x1(j))2+x1(i)x2(i)x1(j)x2(j)+(x2(i))2(x2(j))2\begin{aligned} K_{ij} &= \bold y_i^T\bold y_j = \phi(\bold x_i)^T\phi(\bold x_j) \\[2ex] &= [(x_{1}^{(i)})^2,x_{1}^{(i)}x_{2}^{(i)},(x_{2}^{(i)})^2]\begin{bmatrix}(x_{1}^{(j)})^2\\x_{1}^{(j)}x_{2}^{(j)}\\(x_{2}^{(j)})^2\end{bmatrix} \\[2ex] &= (x_{1}^{(i)})^2(x_{1}^{(j)})^2+x_{1}^{(i)}x_{2}^{(i)}x_{1}^{(j)}x_{2}^{(j)}+(x_{2}^{(i)})^2(x_{2}^{(j)})^2 \end{aligned} \tag{22}

注:其中x1(i)x_{1}^{(i)}表示第ii个数据点的第一个坐标值(横坐标),x2(j)x_{2}^{(j)}表示第jj个数据点的第二个坐标值(纵坐标)。这个式子看起来蛮吓人的,但其实很简单,只不过涉及的角标多一点而已。

直接采用Kernel-SVM(将式(12)(12)代入式(19)(19) ,然后根据最优的α\alpha计算式(20)(21)(20)(21)构建分类器)对数据集(1)(1)进行分类,下图为与2.2节分类器结果对比图:

difference

可以看到在同种高维映射下,2.2节手动映射计算出的分类器和Kernel-SVM计算出来的分类器是一致的。

第四节 关于常用Kernel

可能到这里有读者会有疑问,在3.3节的例子中,我们是先知道了某种高维映射可以使得数据点线性可分,然后再定义相应的Kernel做Kernel-SVM。绕了这么一圈,除了减小计算量,貌似还是摆脱不了显式定义高维映射啊。而且,对于大部分数据集,定义一个线性可分的高维映射也是一件非常困难的事情。所以能不能只定义Kernel,不再显式定义高维映射吗?

这里先看一下Cover’s theorem:

A complex pattern-classification problem, cast in a high-dimensional space nonlinearly, is more likely to be linearly separable than in a low-dimensional space.

Cover’s theorem表明,投影到高维空间中的数据更有可能线性可分。如果我们投影更高维,甚至到无穷维的高维空间,数据集线性可分的概率应该是很大的。所以此时不需要显示定义高维映射,只需要定义一个隐含高维映射的核函数,数据集就有可能线性可分(就是差不多定义一个能把数据映射到更高空间的核函数就行了(当然核函数本身也要满足一定的条件))。

目前常用的核函数有多项式核函数(映射至高维空间),高斯核函数(映射至无穷维空间)。

多项式核函数

多项式核函数的表达式为:

(23)K(x1,x2)=(x1Tx2+c)dK(\bold x_1,\bold x_2)=(\bold x_1^T \bold x_2+c)^d \tag{23}

其中dd为多项式核函数的阶数,cc为非负常数,如果c=0c=0,此时多项式核函数变成齐次多项式。

若采用2阶多项式核函数对第一节中的分类问题做分类,可以得到分类器如下所示:

polynomial

可以发现,它的结果跟手动映射的SVM分类器非常相似,其实也非常相似于3.3节中Kernel-SVM的结果。这是因为对于二维空间,2阶多项式Kernel的表达式为:

(24)K(xi,xj)=(k=1nxk(i)xk(j)+c)dd=2,n=2=k=12(xk(i))2(xk(j))2+p=22q=1p1(2xp(i)xq(i))(2xp(j)xq(j))+k=12(2cxk(i))(2cxk(j))+c2=(x1(i))2(x1(j))2+2x1(i)x2(i)x1(j)x2(j)+(x2(i))2(x2(j))2+2cx1(i)x1(j)+2cx2(i)x2(j)+c2\begin{aligned} K(\bold x_i,\bold x_j) &= (\sum_{k=1}^{n}x_k^{(i)}x_k^{(j)}+c)^d|_{d=2,n=2} \\[2ex] &= \sum_{k=1}^2(x_k^{(i)})^2(x_k^{(j)})^2+\sum_{p=2}^2\sum_{q=1}^{p-1}(\sqrt{2}x_p^{(i)}x_q^{(i)})(\sqrt{2}x_p^{(j)}x_q^{(j)})+\sum_{k=1}^2(\sqrt{2c}x_k^{(i)})(\sqrt{2c}x_k^{(j)}) + c^2 \\[2ex] &= (x_1^{(i)})^2(x_1^{(j)})^2 + 2x_1^{(i)}x_2^{(i)}x_1^{(j)}x_2^{(j)} + (x_2^{(i)})^2(x_2^{(j)})^2 + 2cx_1^{(i)}x_1^{(j)} + 2cx_2^{(i)}x_2^{(j)} + c^2 \end{aligned} \tag{24}

该Kernel包含了式(22)(22)Kernel所含的所有因子,所以它们的结果是非常类似的。

高斯核函数

高斯核函数又名径向基核函数(RBF kernel),其表达式为:

(25)K(xi,xj)=exp(xixj22σ2)K(\bold x_i,\bold x_j) = exp(-\frac{||\bold x_i-\bold x_j||^2}{2\sigma^2}) \tag{25}

高斯核函数隐含了无穷维映射,采用该核函数对第一节中的问题做分类可得:

Gaussian

可以看到高斯核函数很好地区分了两类数据点。

第五节 Kernel方法的扩展

前几节通过SVM引入了Kernel方法,但是Kernel方法绝不会只能应用于SVM。只要是只利用原始数据内积,或者可以转化为只利用原始数据内积的算法,都可以采用Kernel Trick将其转化为Kernel算法。

如Kernel-PCA,Kernel-LDA就是两种典型的嵌入核函数的算法。因介绍这两种算法的资料颇丰,不再赘述其嵌入方式和应用场景。


已经结束了

休息一会喝杯茶吧~

别忘了歇歇眼睛

参考资料

[1]周志华. 机器学习[M]. 清华大学出版社

[2]https://en.wikipedia.org/wiki/Polynomial_kernel

[3]https://en.wikipedia.org/wiki/Gaussian_function

0%