文章目录
核技巧
假设给定一个特征空间上的训练数据集
T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x N , y N ) } T=\{(x_1,y_1),(x_2,y_2),\cdots,(x_N,y_N)\} T={(x1,y1),(x2,y2),⋯,(xN,yN)}其中,实例 x i ∈ X = R n x_i\in \mathcal{X}=\mathbb{R}^n xi∈X=Rn,对应的标记有两类 y i ∈ Y = { + 1 , − 1 } , i = 1 , 2 , . . . , N y_i\in \mathcal{Y}=\{+1,-1\},i=1,2,...,N yi∈Y={
+1,−1},i=1,2,...,N。如果能用 R n \mathbb{R}^n Rn 中的一个超曲面将正负例正确分开,则称这个问题为非线性可分问题。
非线性问题往往不好求解,所以希望能用解线性分类问题的方法解决这个问题。所采取的方法是进行一个非线性变换,将非线性问题变换为线性问题。设原空间为 X ⊂ R 2 , x = ( x ( 1 ) , x ( 2 ) ) ⊤ \mathcal{X} \subset \mathbb{R}^2,\ x=(x^{(1)},x^{(2)})^\top X⊂R2, x=(x(1),x(2))⊤,新空间为 Z ⊂ R 2 , z = ( z ( 1 ) , z ( 2 ) ) ⊤ \mathcal{Z} \subset \mathbb{R}^2,\ z=(z^{(1)},z^{(2)})^\top Z⊂R2, z=(z(1),z(2))⊤,定义从原空间到新空间的变换(映射):
z = ϕ ( x ) = ( ( x ( 1 ) ) 2 , ( x ( 2 ) ) 2 ) ⊤ z=\phi(x)=((x^{(1)})^2,(x^{(2)})^2)^\top z=ϕ(x)=((x(1))2,(x(2))2)⊤ 对于下图的例子,通过此变换,将左图中椭圆变成右图中的直线。
原空间的点相应地变为新空间中的点,原空间中的椭圆
w 1 ( x ( 1 ) ) 2 + w 2 ( x ( 2 ) ) 2 + b = 0 w_1(x^{(1)})^2+w_2(x^{(2)})^2+b=0 w1(x(1))2+w2(x(2))2+b=0变换成新空间中的直线
w 1 z ( 1 ) + w 2 z ( 2 ) + b = 0 w_1z^{(1)}+w_2z^{(2)}+b=0 w1z(1)+w2z(2)+b=0
核技巧应用到支持向量机的基本思想就是通过一个非线性变换将输入空间对应于一个特征空间,使得在输入空间中的超曲面模型对应于特征空间中的超平面模型。
核函数的定义:设 X \mathcal{X} X 是输入空间(欧式空间 R n \mathbb{R}^n Rn 的子集或离散集合),又设 H \mathcal{H} H 为特征空间(希尔伯特空间),如果存在一个从 X \mathcal{X} X 到 H \mathcal{H} H 的映射 ϕ ( x ) : X → H \phi(x): \mathcal{X}\to \mathcal{H} ϕ(x):X→H 使得对所有 x , z ∈ X x,z\in \mathcal{X} x,z∈X,函数 K ( x , z ) K(x,z) K(x,z) 满足条件 K ( x , z ) = ϕ ( x ) ⋅ ϕ ( z ) K(x,z)=\phi(x) \cdot \phi(z) K(x,z)=ϕ(x)⋅ϕ(z) 则称 K ( x , z ) K(x,z) K(x,z) 为核函数,式中 ϕ ( x ) ⋅ ϕ ( z ) \phi(x) \cdot \phi(z) ϕ(x)⋅ϕ(z) 为 ϕ ( x ) \phi(x) ϕ(x) 和 ϕ ( z ) \phi(z) ϕ(z) 的内积。
核技巧的想法是,在学习与预测中只定义核函数 K ( x , z ) K(x,z) K(x,z),而不是显式地定义映射函数 ϕ \phi ϕ. 对于给定的核 K ( x , z ) K(x,z) K(x,z),特征空间和映射函数的取法并不唯一,可以取不同的特征空间,即使在同一特征空间里也可以取不同的映射。
在线性可分支持向量机的对偶问题中,无论是目标函数还是决策函数都只涉及输入实例与实例之间的内积,这个内积 x i ⋅ x j x_i\cdot x_j xi⋅xj 可以用核函数 K ( x i , x j ) = ϕ ( x i ) ⋅ ϕ ( x j ) K(x_i,x_j)=\phi(x_i) \cdot \phi(x_j) K(xi,xj)=ϕ(xi)⋅ϕ(xj) 来代替:
W ( α ) = 1 2 ∑ i = 1 N ∑ j = 1 N α i α j y i y j K ( x i , x j ) − ∑ i = 1 N α i W(\alpha)= \frac{1}{2}\sum_{i=1}^N\sum_{j=1}^N\alpha_i\alpha_jy_iy_jK(x_i,x_j)-\sum_{i=1}^N\alpha_i W(α)=21i=1∑Nj=1∑NαiαjyiyjK(xi,xj)−i=1∑Nαi这等价于经过映射函数将原来的输入空间变换到一个新的特征空间,将输入空间中的内积 x i ⋅ x j x_i\cdot x_j xi⋅xj 变换为特征空间中的内积 ϕ ( x i ) ⋅ ϕ ( x j ) \phi(x_i) \cdot \phi(x_j) ϕ(xi)⋅ϕ(xj),在新的特征空间里从训练样本中学习线性支持向量机。
正定核
已知映射函数 ϕ \phi ϕ,可以通过 ϕ ( x ) \phi(x) ϕ(x) 和 ϕ ( z ) \phi(z) ϕ(z) 的内积求得核函数 K ( x , z ) K(x,z) K(x,z)。不用构造映射 ϕ ( x ) \phi(x) ϕ(x)能否直接判断一个给定的函数 K ( x , z ) K(x,z) K(x,z) 是不是核函数?或者说, 函数 K ( x , z ) K(x,z) K(x,z) 满足什么条件才能成为核函数?
通常所说的核函数就是正定核函数,正定核的充要条件为:
设 K : X × X → R K:\mathcal{X} \times \mathcal{X} \to \mathbb{R} K:X×X→R 是对称函数,则 K ( x , z ) K(x,z) K(x,z) 为正定核函数的充要条件是对任意 x i ∈ X , i = 1 , 2 , ⋯ , m , K ( x , z ) x_i \in \mathcal{X},\ i=1,2,\cdots,m,\ K(x,z) xi∈X, i=1,2,⋯,m, K(x,z) 对应的 Gram 矩阵 K = [ K ( x i , x j ) ] m × m K=[K(x_i,x_j)]_{m\times m} K=[K(xi,xj)]m×m 是半正定矩阵。
对于一个具体函数 K ( x , z ) K(x,z) K(x,z) 来说,检验它是否为正定函数并不容易,因为要求对任意有限输入集 { x 1 , x 2 , ⋯ , x m } \{x_1,x_2,\cdots,x_m\} { x1,x2,⋯,xm} 验证 K K K 对应的 Gram 矩阵是否为半正定的。在实际问题中往往应用已有的核函数,下面介绍一些常用的核函数。
常用核函数
多项式核函数(polynomial kernel function)
K ( x , z ) = ( x ⋅ z + 1 ) p K(x,z)=(x\cdot z + 1)^p K(x,z)=(x⋅z+1)p对应的支持向量机是一个 p p p 次多项式分类器。
高斯核函数(Gaussian kernel function)
K ( x , z ) = exp ( − ∥ x − z ∥ 2 2 σ 2 ) K(x,z)=\exp\left(-\frac{\|x-z\|^2}{2\sigma^2}\right) K(x,z)=exp(−2σ2∥x−z∥2)对应的支持向量机是高斯径向基函数。
支持向量机的优势在于:
- 在高维空间中非常高效;
- 即使在数据维度比样本数量大的情况下仍然有效;
- 在决策函数(称为支持向量)中使用训练集的子集,因此它也是高效利用内存的;
- 通用性: 不同的核函数与特定的决策函数一一对应。常见的 kernel 已经提供,也可以指定定制的内核.
支持向量机的缺点包括:
- 如果特征数量比样本数量大得多,在选择核函数时要避免过拟合,而且正则化项是非常重要的;
- 支持向量机不直接提供概率估计,这些都是使用昂贵的五次交叉验算计算的。
我们使用不同的核函数来对鸢尾花数据集进行分类:
import matplotlib.pyplot as plt
from sklearn import svm, datasets
import numpy as np
iris = datasets.load_iris()
X = iris.data[:, :2]
y = iris.target
C = 1.0 # SVM regularization parameter
models = (
svm.SVC(kernel='linear', C=C),
svm.LinearSVC(C=C, max_iter=10000),
svm.SVC(kernel='rbf', gamma=0.7, C=C),
svm.SVC(kernel='poly', degree=3, gamma='auto', C=C)
)
models = (clf.fit(X, y) for clf in models)
titles = (
"SVC with linear kernel",
"LinearSVC (linear kernel)",
"SVC with RBF kernel",
"SVC with polynomial (degree 3) kernel",
)
fig, sub = plt.subplots(2, 2)
plt.subplots_adjust(wspace=0.4, hspace=0.4)
def make_meshgrid(x, y, h=.02):
x_min, x_max = x.min() - 1, x.max() + 1
y_min, y_max = y.min() - 1, y.max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
return xx, yy
def plot_contours(ax, clf, xx, yy, **params):
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
out = ax.contourf(xx, yy, Z, **params)
return out
X0, X1 = X[:, 0], X[:, 1]
xx, yy = make_meshgrid(X0, X1)
for clf, title, ax in zip(models, titles, sub.flatten()):
plot_contours(ax, clf, xx, yy, cmap=plt.cm.coolwarm, alpha=0.8)
ax.scatter(X0, X1, c=y, cmap=plt.cm.coolwarm, s=20, edgecolors="k")
ax.set_xticks(())
ax.set_yticks(())
ax.set_title(title)
plt.show()
References
[1] 《机器学习方法》,李航,清华大学出版社。
[2] sklearn 中文文档,https://www.sklearncn.cn/5/。