python svm核函数_Python.SVM(三)核方法

Python.SVM(三)核方法

1

什么是核方法

往简单里说,核方法是将一个低维的线性不可分的数据映射到一个高维的空间、并期望映射后的数据在高维空间里是线性可分的。

我们以异或数据集为例:在二维空间中、异或数据集是线性不可分的;但是通过将其映射到三维空间、我们可以非常简单地让其在三维空间中变得线性可分。

比如定义映射:

02174a93b10636a43094775337f33c40.png

该映射的效果如下图所示:

python svm核函数_Python.SVM(三)核方法_第1张图片

可以看到,虽然左图的数据集线性不可分、但显然右图的数据集是线性可分的,这就是核工作原理的一个不太严谨但仍然合理的解释

从直观上来说,确实容易想象、同一份数据在越高维的空间中越有可能线性可分,但从理论上是否确实如此呢?

1965 年提出的 Cover 定理从理论上解决了这个问题,我们会在文末附上相应的公式,这里暂时按下不表

至此,似乎问题就转化为了如何寻找合适的映射、使得数据集在被它映射到高维空间后变得线性可分。

不过可以想象的是,现实任务中的数据集要比上文我们拿来举例的异或数据集要复杂得多、直接构造一个恰当的的难度甚至可能高于解决问题本身。

而核方法的巧妙之处就在于,它能将构造映射

a3617cc5182f3bc8df25e07863bb511d.png这个过程再次进行转化、从而使得问题变得简易:它通过核函数来避免显式定义映射往简单里说,核方法会通过用能够表示成

521a6ee8adccf88e5a77033c7e06a31b.png的核函数

85abcdecb780029fe36c0ded2d0f7578.png替换各算式中出现的内积

d3d70562c66d30459902407173d25dc0.png来完成将数据从低维映射到高维的过程。

换句话说、核方法的思想如下:

将算法表述成样本点内积的组合(这经常能通过算法的对偶形式实现)

设法找到核函数

c3043b6f8db4df8235f114fa8133cc63.png,它能返回样本点

b51a7b23a7c009f1769a0dcb9b31ee38.png

cf41ee40e4828dcea6182dcfaeb4d187.png

2ab3f59e8d8ca90d9972004e213a5dc2.png作用后的内积

070b439a37c0bfdc8926b9005e9b9205.png替换

87856b8aaf47bbb160d207d60b441c17.png、完成低维到高维的映射(同时也完成了从线性算法到非线性算法的转换)

当然了,不难想象的是,并不是所有的函数都能够对应一个映射(亦即不是所有的

a9ea68d2412a39d51d88e572f49af014.png都能拆成

f14c660ea0e7db05b815632f10690267.png比如说,显然

47029fc76c91578b8c1863901c932486.png至少需要是一个对称函数)。

幸运的是,1909 年提出的 Mercer 定理解决了这个问题,它的具体叙述会在文末给出。

Mercer 定理为寻找核函数带来了极大的便利。可以证明如下两族函数都是核函数:

python svm核函数_Python.SVM(三)核方法_第2张图片

那么核方法的应用场景有哪些呢?在 2002 年由 Scholkopf 和 Smola 证明的表示定理告诉我们它的应用场景非常广泛。定理的具体内容同样会附在文末。

2

核模型的表现

还是用 GIF 来说明问题最为形象。

当我们对感知机应用核方法后,它就能对非线性数据集(比如螺旋线数据集)进行分类了,训练过程将如下:

python svm核函数_Python.SVM(三)核方法_第3张图片

3

怎么应用核方法

简单来说,就是把算法中涉及到样本的地方都通过某种变换、弄成样本的内积形式。以感知机为例,感知机的原始损失函数为:

787b6c646fc54db4e5948fdbfb2aa5f0.png

为了让损失函数中的样本都变成内积形式,考虑令

python svm核函数_Python.SVM(三)核方法_第4张图片

python svm核函数_Python.SVM(三)核方法_第5张图片

(有没有发现核形式和对偶形式很像?( σ'ω')σ)

4

如何训练核模型

注意:为简洁,从此往后的推导和实现均以核感知机为例,核 SVM 的相关讨论会放在下一章介绍 SMO 算法时进行】

简洁起见,我们还是用梯度下降法来进行训练,为此我们需要进行求导工作。假设当前模型参数为

c21eafdc759e495628906c2c3a161535.png

e66cc244024062a93098407b375245b9.png在参数

40a4ffb29155243083ebfe4f3f12ca3e.png下的预测值为

7e636f5be3282b76208bc33483b5be2e.png,则:

python svm核函数_Python.SVM(三)核方法_第6张图片

为了加速训练,我们需要将该算式向量化,为此我们需要定义核矩阵。假设现在我们有两组样本

804788e968992fc68fcd4ae40695cff7.png

72154b03cf75604c1623406df490645b.png,那么它们的核矩阵即为:

5724e26eddc5dfc9510bba50df32393e.png

对于训练过程而言,我们关心的是训练样本之间的核矩阵

python svm核函数_Python.SVM(三)核方法_第7张图片

‍利用它,不难写出相应的向量化代码:

python svm核函数_Python.SVM(三)核方法_第8张图片

对于预测过程,我们关心的是原样本和新样本之间的核矩阵。假设新样本为

32be3f6e64b558910b56d9999fea1304.png,则

python svm核函数_Python.SVM(三)核方法_第9张图片

那么预测过程即为

34eb729cc17102378e54524823197a8d.png

于是关键就在于如何定义计算核矩阵的核函数了。

对于多项式核来说,核函数的实现是直观的:

6839a26c87949df2e32f78824b46e15b.png

但对于 RBF 来说就没那么直观了,用到了 Numpy 的高级实用技巧之一——升维:

5947f13d885e4152ca268d9a4d55613b.png

当然直接用 for 来实现也是可以的,不过那将会非常非常慢……

5

核模型的实现

如果思路能够整理清楚,那么核模型相比原模型来说只有如下两点改变:

需要定义核函数并计算出核矩阵

计算预测值时不是

eaa336e6ad1de938437b298d233324f9.png,而是

4070cfec885664a9d476fdf8bc2e1db6.png,其中

在训练时,K为原样本之间的核矩阵

在测试时,K为原样本和新样本的核矩阵

所以实现起来的话会有许多重复代码,这里就只展现其中最核心的部分(仍以核感知机为例):

python svm核函数_Python.SVM(三)核方法_第10张图片

6

相关数学理论

1)Cover 定理

python svm核函数_Python.SVM(三)核方法_第11张图片

【注意:通常我们会称满足这两个充要条件之一的函数为 Mercer 核函数而把核函数定义得更宽泛。

不过如果不打算在理论上深入太多的话,将 Mercer 核函数简称为核函数是可以的。

此外,虽说 Mercer 核函数确实具有 Hilbert 空间中的内积形式、但此时的 Hilbert 空间并不一定具有“维度”这么好的概念(或说、可以认为此时 Hilbert 空间的维度为无穷大;比如说 RBF 核,它映射后的空间就是无穷维的)】

3)表示定理

python svm核函数_Python.SVM(三)核方法_第12张图片

这意味着对于任意一个损失函数和一个单调递增的正则化项组成的优化问题、我们都能够对其应用核方法

下一篇文章我们则会抛开梯度下降这个有些“偷懒”的做法,并介绍一种叫序列最小最优化(SMO)的算法

希望观众老爷们能够喜欢~

推荐阅读:

精选干货|近半年干货目录汇总----全是通俗易懂的硬货!欢迎阅读!

自然语言处理中CNN模型几种常见的Max Pooling操作

干货|非常详细的神经网络入门解释

欢迎关注公众号学习交流~

你可能感兴趣的:(python,svm核函数)