打开搜索引擎搜索核函数,都会发现 SVM 会一起出现。但是核函数是一种技巧,并不只限于 SVM。其实,核技巧是一个非常纯粹的数学方法,不应该一上来就扯上 SVM,也没必要。因为这个技巧不仅应用在SVM中,它解决了数据映射到高维空间之后点积的计算量过于复杂的问题。很多人啰啰嗦嗦说了一大堆,把原本很简单的东西搞的很复杂,甚至还在推 SVM 的公式,就像孔乙己问茴香豆的『茴』有几种写法一样的没意思。
问题描述
支持向量机为了解决数据在低维度不容易线性分割的情况下,会通过某非线性变换 ,将输入空间映射到高维特征空间。但是映射的维度会很高,为了降低计算复杂度,解决映射后可能产生的维度爆炸问题,我们在求解的时候引入了核技巧。所以,核技巧的应用场景不限于 SVM,而是:需要处理高维映射计算的问题。
给定两个向量 和 ,我们的目标是要计算他们的内积 。如果原始空间内不可分,那么现在通过某种非线性变换把他们映射到某一个高维空间中去,那么映射后的向量就变成 和 ,映射后的内积就变成 。现在改如何计算映射后的内积呢?
传统方法是先计算映射后的向量 和 ,然后再计算它俩的内积。但是这样做计算很复杂,因为映射到高维空间后的数据维度很高。一旦达到一万多维计算起来简直浪费时间。
于是,能不能在原始空间找到一个函数 使得 呢?如果这个函数存在,那么我们只需要在低维空间里计算函数的值即可,而不需要先把数据映射到高维空间,再通过复杂的计算求解映射后的内积了。
庆幸的是,这样的函数是存在的。这样一来计算的复杂度就大大降低了,这种简化计算的方法被称为核技巧(The Kernel Trick),而函数 就是核函数(Kernel Function)。这里我们选用高斯核函数,可以将原始维度映射到无穷维。
这种东西最好是去看官方文档,有人把高斯核函数中的范数写成了,第三方博客一点都不注重细节,我半天没看懂还以为取绝对值,艹。
代码实现
1 2 3 4 5 6 7 8 9 10 11 12
| import math import numpy as np
def mapping(x, y, sigma=1): return math.exp(-np.linalg.norm((x-y), ord = 2) / 2 / sigma ** 2)
x_1 = np.random.random_sample((10, 1)) x_2 = np.random.random_sample((10, 1))
a = mapping(x_1, x_2)
print(a)
|
结语
核函数是个好东西,之前还写过用核函数去聚类的文章,欢迎观看:https://muyuuuu.github.io/2020/03/30/KDE-cluster/
参考
- 核技巧:http://www.fanyeong.com/2017/11/13/the-kernel-trick/
- 核函数:https://en.wikipedia.org/wiki/Radial_basis_function_kernel
- numpy求范数:http://liao.cpython.org/numpy11/
Gitalk 加载中 ...