支持向量机(SVM)
1. 间隔与支持向量
给定训练样本集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ... , ( x m , y m ) } D = \{(x_1, y_1), (x_2, y_2), \dots, (x_m, y_m)\} D={(x1,y1),(x2,y2),...,(xm,ym)},其中 y i ∈ { − 1 , + 1 } y_i \in \{-1, +1\} yi∈{−1,+1}。分类学习最基本的想法就是基于训练集 D D D 在样本空间中找到一个划分超平面,将不同类别的样本分开。但能将训练样本分开的划分超平面可能有很多,我们应该努力去找到哪一个呢?
直观上看,应该去找位于两类训练样本"正中间"的划分超平面,即图中红色的那个,因为该划分超平面对训练样本局部扰动的"容忍"性最好。例如,由于训练集的局限性或噪声的因素,训练集外的样本可能比图中的训练样本更接近两个类的分隔界,这将使许多划分超平面出现错误,而红色的超平面受影响最小。换言之,这个划分超平面所产生的分类结果是最鲁棒的,对未见示例的泛化能力最强。
在样本空间中,划分超平面可通过如下线性方程来描述:
w T x + b = 0 , (1.1) w^T x + b = 0, \tag{1.1} wTx+b=0,(1.1)
其中 w = ( w 1 ; w 2 ; ... ; w d ) w = (w_1; w_2; \dots; w_d) w=(w1;w2;...;wd) 为法向量,决定了超平面的方向; b b b 为位移项,决定了超平面与原点之间的距离。显然,划分超平面可被法向量 w w w 和位移 b b b 确定,下面我们将与其记为 ( w , b ) (w, b) (w,b)。样本空间中任意点 x x x 到超平面 ( w , b ) (w, b) (w,b) 的距离可写为
r = ∣ w T x + b ∣ ∣ ∣ w ∣ ∣ . (1.2) r = \frac{|w^T x + b|}{||w||}. \tag{1.2} r=∣∣w∣∣∣wTx+b∣.(1.2)
假设超平面 ( w , b ) (w, b) (w,b) 能将训练样本正确分类,即对于 ( x i , y i ) ∈ D (x_i, y_i) \in D (xi,yi)∈D,若 y i = + 1 y_i = +1 yi=+1,则有 w T x i + b > 0 w^T x_i + b > 0 wTxi+b>0;若 y i = − 1 y_i = -1 yi=−1,则有 w T x i + b < 0 w^T x_i + b < 0 wTxi+b<0。令
{ w T x i + b ⩾ + 1 , y i = + 1 ; w T x i + b ⩽ − 1 , y i = − 1. (1.3) \begin{cases} w^T x_i + b \geqslant +1, & y_i = +1; \\ w^T x_i + b \leqslant -1, & y_i = -1. \end{cases} \tag{1.3} {wTxi+b⩾+1,wTxi+b⩽−1,yi=+1;yi=−1.(1.3)
如图所示,距离超平面最近的这几个训练样本点使式(1.3)的等号成立,它们被称为**"支持向量"(support vector),两个异类支持向量到超平面的距离之和为
γ = 2 ∣ ∣ w ∣ ∣ , (1.4) \gamma = \frac{2}{||w||}, \tag{1.4} γ=∣∣w∣∣2,(1.4)
它被称为"间隔"(margin)**。
欲找到具有"最大间隔"(maximum margin)的划分超平面,也就是要找到能满足式(1.3)中约束的参数 w w w 和 b b b,使得 γ \gamma γ 最大,即
max w , b 2 ∣ ∣ w ∣ ∣ s.t. y i ( w T x i + b ) ⩾ 1 , i = 1 , 2 , ... , m . (1.5) \begin{aligned} & \max_{w,b} \frac{2}{||w||} \\ & \text{s.t. } y_i(w^T x_i + b) \geqslant 1, \quad i = 1, 2, \dots, m. \end{aligned} \tag{1.5} w,bmax∣∣w∣∣2s.t. yi(wTxi+b)⩾1,i=1,2,...,m.(1.5)
显然,为了最大化间隔,仅需最大化 ∣ ∣ w ∣ ∣ − 1 ||w||^{-1} ∣∣w∣∣−1,这等价于最小化 ∣ ∣ w ∣ ∣ 2 ||w||^2 ∣∣w∣∣2。于是,式(1.5)可重写为
min w , b 1 2 ∣ ∣ w ∣ ∣ 2 s.t. y i ( w T x i + b ) ⩾ 1 , i = 1 , 2 , ... , m . (1.6) \begin{aligned} & \min_{w,b} \frac{1}{2}||w||^2 \\ & \text{s.t. } y_i(w^T x_i + b) \geqslant 1, \quad i = 1, 2, \dots, m. \end{aligned} \tag{1.6} w,bmin21∣∣w∣∣2s.t. yi(wTxi+b)⩾1,i=1,2,...,m.(1.6)
这就是支持向量机(Support Vector Machine, 简称 SVM)的基本型。
python
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import make_blobs
# 1. 生成线性可分数据
X, y = make_blobs(n_samples=40, centers=2, random_state=6)
# 2. 训练线性 SVM 模型
clf = svm.SVC(kernel='linear', C=1000)
clf.fit(X, y)
# 3. 绘制数据点
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
# 4. 绘制决策边界和最大间隔
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
# 创建网格来评估模型
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
# 绘制边界和间隔 (Z=0 是决策面, Z=1 和 Z=-1 是间隔边界)
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
# 圈出支持向量
ax.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100,
linewidth=1, facecolors='none', edgecolors='k')
plt.title("Linear SVM: Decision Boundary & Margins")
plt.show()
2. 对偶问题
我们希望求解式(1.6)来得到大间隔划分超平面所对应的模型
f ( x ) = w T x + b , (2.1) f(x) = w^T x + b, \tag{2.1} f(x)=wTx+b,(2.1)
其中 w w w 和 b b b 是模型参数。注意到式(1.6)本身是一个凸二次规划(convex quadratic programming)问题,能直接用现成的优化计算包求解,但我们可以有更高效的办法。
对式(1.6)使用拉格朗日乘子法可得到其"对偶问题"(dual problem)。具体来说,对式(1.6)的每条约束添加拉格朗日乘子 α i ⩾ 0 \alpha_i \geqslant 0 αi⩾0,则该问题的拉格朗日函数可写为
L ( w , b , α ) = 1 2 ∣ ∣ w ∣ ∣ 2 + ∑ i = 1 m α i ( 1 − y i ( w T x i + b ) ) , (2.2) L(w, b, \alpha) = \frac{1}{2}||w||^2 + \sum_{i=1}^m \alpha_i (1 - y_i(w^T x_i + b)), \tag{2.2} L(w,b,α)=21∣∣w∣∣2+i=1∑mαi(1−yi(wTxi+b)),(2.2)
其中 α = ( α 1 ; α 2 ; ... ; α m ) \alpha = (\alpha_1; \alpha_2; \dots; \alpha_m) α=(α1;α2;...;αm)。令 L ( w , b , α ) L(w, b, \alpha) L(w,b,α) 对 w w w 和 b b b 的偏导为零可得
w = ∑ i = 1 m α i y i x i , (2.3) w = \sum_{i=1}^m \alpha_i y_i x_i, \tag{2.3} w=i=1∑mαiyixi,(2.3)
0 = ∑ i = 1 m α i y i . (2.4) 0 = \sum_{i=1}^m \alpha_i y_i. \tag{2.4} 0=i=1∑mαiyi.(2.4)
将式(2.3)代入(2.2),即可将 L ( w , b , α ) L(w, b, \alpha) L(w,b,α) 中的 w w w 和 b b b 消去,再考虑式(2.4)的约束,就得到式(1.6)的对偶问题
max α ∑ i = 1 m α i − 1 2 ∑ i = 1 m ∑ j = 1 m α i α j y i y j x i T x j s.t. ∑ i = 1 m α i y i = 0 , α i ⩾ 0 , i = 1 , 2 , ... , m . (2.5) \begin{aligned} & \max_{\alpha} \sum_{i=1}^m \alpha_i - \frac{1}{2} \sum_{i=1}^m \sum_{j=1}^m \alpha_i \alpha_j y_i y_j x_i^T x_j \\ & \text{s.t. } \sum_{i=1}^m \alpha_i y_i = 0, \\ & \quad \quad \alpha_i \geqslant 0, \quad i = 1, 2, \dots, m. \end{aligned} \tag{2.5} αmaxi=1∑mαi−21i=1∑mj=1∑mαiαjyiyjxiTxjs.t. i=1∑mαiyi=0,αi⩾0,i=1,2,...,m.(2.5)
解出 α \alpha α 后,求出 w w w 与 b b b 即可得到模型
f ( x ) = w T x + b = ∑ i = 1 m α i y i x i T x + b . (2.6) \begin{aligned} f(x) &= w^T x + b \\ &= \sum_{i=1}^m \alpha_i y_i x_i^T x + b. \end{aligned} \tag{2.6} f(x)=wTx+b=i=1∑mαiyixiTx+b.(2.6)
从对偶问题(2.5)解出的 α i \alpha_i αi 是式(2.2)中的拉格朗日乘子,它恰对应着训练样本 ( x i , y i ) (x_i, y_i) (xi,yi)。注意到式(1.6)中有不等式约束,因此上述过程需满足 KKT (Karush-Kuhn-Tucker) 条件,即要求
{ α i ⩾ 0 ; y i f ( x i ) − 1 ⩾ 0 ; α i ( y i f ( x i ) − 1 ) = 0. (2.7) \begin{cases} \alpha_i \geqslant 0; \\ y_i f(x_i) - 1 \geqslant 0; \\ \alpha_i (y_i f(x_i) - 1) = 0. \end{cases} \tag{2.7} ⎩ ⎨ ⎧αi⩾0;yif(xi)−1⩾0;αi(yif(xi)−1)=0.(2.7)
于是,对任意训练样本 ( x i , y i ) (x_i, y_i) (xi,yi),总有 α i = 0 \alpha_i = 0 αi=0 或 y i f ( x i ) = 1 y_i f(x_i) = 1 yif(xi)=1。若 α i = 0 \alpha_i = 0 αi=0,则该样本将不会在式(2.6)的求和中出现,也就不会对 f ( x ) f(x) f(x) 有任何影响;若 α i > 0 \alpha_i > 0 αi>0,则必有 y i f ( x i ) = 1 y_i f(x_i) = 1 yif(xi)=1,所对应的样本点位于最大间隔边界上,是一个支持向量。这显示出支持向量机的一个重要性质:训练完成后,大部分的训练样本都不需保留,最终模型仅与支持向量有关。
那么,如何求解式(2.5)呢?不难发现,这是一个二次规划问题,可使用通用的二次规划算法来求解;然而,该问题的规模正比于训练样本数,这会在实际任务中造成很大的开销。为了避开这个障碍,人们通过利用问题本身的特性,提出了很多高效算法,SMO (Sequential Minimal Optimization) 是其中一个著名的代表 [Platt, 1998]。
SMO 的基本思路是先固定 α i \alpha_i αi 之外的所有参数,然后求 α i \alpha_i αi 上的极值。由于存在约束 ∑ i = 1 m α i y i = 0 \sum_{i=1}^m \alpha_i y_i = 0 ∑i=1mαiyi=0,若固定 α i \alpha_i αi 之外的其他变量,则 α i \alpha_i αi 可由其他变量导出。于是,SMO 每次选择两个变量 α i \alpha_i αi 和 α j \alpha_j αj,并固定其他参数。这样,在参数初始化后,SMO 不断执行如下两个步骤直至收敛:
- 选取一对需更新的变量 α i \alpha_i αi 和 α j \alpha_j αj;
- 固定 α i \alpha_i αi 和 α j \alpha_j αj 以外的参数,求解式(2.5)获得更新后的 α i \alpha_i αi 和 α j \alpha_j αj。
注意到只需选取的 α i \alpha_i αi 和 α j \alpha_j αj 中有一个不满足 KKT 条件(2.7),目标函数就会在迭代后减小。直观来看,KKT 条件违背的程度越大,则变量更新后可能导致的目标函数值减幅越大。于是,SMO 先选取违背 KKT 条件程度最大的变量。第二个变量应选择一个使目标函数值减小最快的变量,但由于比较各变量所对应的目标函数值减幅的复杂度过高,因此 SMO 采用了一个启发式:使选取的两变量所对应样本之间的间隔最大。一种直观的解释是,这样的两个变量有很大的差别,与对两个相似的变量进行更新相比,对它们进行更新会带给目标函数值更大的变化。
SMO 算法之所以高效,恰由于在固定其他参数后,仅优化两个参数的过程能做到非常高效。具体来说,仅考虑 α i \alpha_i αi 和 α j \alpha_j αj 时,式(2.5)中的约束可重写为
α i y i + α j y j = c , α i ⩾ 0 , α j ⩾ 0 , (2.8) \alpha_i y_i + \alpha_j y_j = c, \quad \alpha_i \geqslant 0, \quad \alpha_j \geqslant 0, \tag{2.8} αiyi+αjyj=c,αi⩾0,αj⩾0,(2.8)
其中
c = − ∑ k ≠ i , j α k y k (2.9) c = - \sum_{k \neq i, j} \alpha_k y_k \tag{2.9} c=−k=i,j∑αkyk(2.9)
是使 ∑ i = 1 m α i y i = 0 \sum_{i=1}^m \alpha_i y_i = 0 ∑i=1mαiyi=0 成立的常数。用
α i y i + α j y j = c (2.10) \alpha_i y_i + \alpha_j y_j = c \tag{2.10} αiyi+αjyj=c(2.10)
消去式(2.5)中的变量 α j \alpha_j αj,则得到一个关于 α i \alpha_i αi 的单变量二次规划问题,仅有的约束是 α i ⩾ 0 \alpha_i \geqslant 0 αi⩾0。不难发现,这样的二次规划问题具有闭式解,于是不必调用数值优化算法即可高效地计算出更新后的 α i \alpha_i αi 和 α j \alpha_j αj。
如何确定偏移项 b b b 呢?注意到对任意支持向量 ( x s , y s ) (x_s, y_s) (xs,ys) 都有 y s f ( x s ) = 1 y_s f(x_s) = 1 ysf(xs)=1,即
y s ( ∑ i ∈ S α i y i x i T x s + b ) = 1 , (2.11) y_s \left( \sum_{i \in S} \alpha_i y_i x_i^T x_s + b \right) = 1, \tag{2.11} ys(i∈S∑αiyixiTxs+b)=1,(2.11)
其中 S = { i ∣ α i > 0 , i = 1 , 2 , ... , m } S = \{i \mid \alpha_i > 0, i = 1, 2, \dots, m\} S={i∣αi>0,i=1,2,...,m} 为所有支持向量的下标集。理论上,可选取任意支持向量并通过求解式(2.11)获得 b b b,但现实任务中常采用一种更鲁棒的做法:使用所有支持向量求解的平均值
b = 1 ∣ S ∣ ∑ s ∈ S ( y s − ∑ i ∈ S α i y i x i T x s ) . (2.12) b = \frac{1}{|S|} \sum_{s \in S} \left( y_s - \sum_{i \in S} \alpha_i y_i x_i^T x_s \right). \tag{2.12} b=∣S∣1s∈S∑(ys−i∈S∑αiyixiTxs).(2.12)
python
# 接上一段代码的 clf 模型
print("--- 对偶问题验证 ---")
# 获取支持向量的索引
support_vector_indices = clf.support_
print(f"支持向量的个数: {len(support_vector_indices)}")
print(f"支持向量的索引: {support_vector_indices}")
# 获取对偶系数 alpha * y
# 注意:sklearn 存储的是 alpha_i * y_i,对于非支持向量,alpha 为 0
dual_coef = clf.dual_coef_
print(f"对偶系数 (alpha * y): \n{dual_coef}")
# 验证:决策平面参数 w 可以由支持向量重构
# w = sum(alpha_i * y_i * x_i)
w_reconstructed = np.dot(dual_coef, clf.support_vectors_)
print(f"从对偶系数重构的 w: {w_reconstructed}")
print(f"模型原始存储的 w: {clf.coef_}")
3. 核函数
在本章前面的讨论中,我们假设训练样本是线性可分的,即存在一个划分超平面能将训练样本正确分类。然而在现实任务中,原始样本空间内也许并不存在一个能正确划分两类样本的超平面。例如图 6.3 中的"异或"问题就不是线性可分的。
对这样的问题,可将样本从原始空间映射到一个更高维的特征空间,使得样本在这个特征空间内线性可分。例如在图 6.3 中,若将原始的二维空间映射到一个合适的三维空间,就能找到一个合适的划分超平面。幸运的是,如果原始空间是有限维,即属性数有限,那么一定存在一个高维特征空间使样本可分。
令 ϕ ( x ) \phi(x) ϕ(x) 表示将 x x x 映射后的特征向量,于是,在特征空间中划分超平面所对应的模型可表示为
f ( x ) = w T ϕ ( x ) + b , (3.1) f(x) = w^T \phi(x) + b, \tag{3.1} f(x)=wTϕ(x)+b,(3.1)
其中 w w w 和 b b b 是模型参数。类似式(1.6),有
min w , b 1 2 ∣ ∣ w ∣ ∣ 2 s.t. y i ( w T ϕ ( x i ) + b ) ⩾ 1 , i = 1 , 2 , ... , m . (3.2) \begin{aligned} & \min_{w,b} \frac{1}{2}||w||^2 \\ & \text{s.t. } y_i(w^T \phi(x_i) + b) \geqslant 1, \quad i = 1, 2, \dots, m. \end{aligned} \tag{3.2} w,bmin21∣∣w∣∣2s.t. yi(wTϕ(xi)+b)⩾1,i=1,2,...,m.(3.2)
其对偶问题是
max α ∑ i = 1 m α i − 1 2 ∑ i = 1 m ∑ j = 1 m α i α j y i y j ϕ ( x i ) T ϕ ( x j ) s.t. ∑ i = 1 m α i y i = 0 , α i ⩾ 0 , i = 1 , 2 , ... , m . (3.3) \begin{aligned} & \max_{\alpha} \sum_{i=1}^m \alpha_i - \frac{1}{2} \sum_{i=1}^m \sum_{j=1}^m \alpha_i \alpha_j y_i y_j \phi(x_i)^T \phi(x_j) \\ & \text{s.t. } \sum_{i=1}^m \alpha_i y_i = 0, \\ & \quad \quad \alpha_i \geqslant 0, \quad i = 1, 2, \dots, m. \end{aligned} \tag{3.3} αmaxi=1∑mαi−21i=1∑mj=1∑mαiαjyiyjϕ(xi)Tϕ(xj)s.t. i=1∑mαiyi=0,αi⩾0,i=1,2,...,m.(3.3)
求解式(3.3)涉及到计算 ϕ ( x i ) T ϕ ( x j ) \phi(x_i)^T \phi(x_j) ϕ(xi)Tϕ(xj),这是样本 x i x_i xi 与 x j x_j xj 映射到特征空间之后的内积。由于特征空间维数可能很高,甚至可能是无穷维,因此直接计算 ϕ ( x i ) T ϕ ( x j ) \phi(x_i)^T \phi(x_j) ϕ(xi)Tϕ(xj) 通常是困难的。为了避开这个障碍,可以设想这样一个函数:
κ ( x i , x j ) = ⟨ ϕ ( x i ) , ϕ ( x j ) ⟩ = ϕ ( x i ) T ϕ ( x j ) , (3.4) \kappa(x_i, x_j) = \langle \phi(x_i), \phi(x_j) \rangle = \phi(x_i)^T \phi(x_j), \tag{3.4} κ(xi,xj)=⟨ϕ(xi),ϕ(xj)⟩=ϕ(xi)Tϕ(xj),(3.4)
即 x i x_i xi 与 x j x_j xj 在特征空间的内积等于它们在原始样本空间中通过函数 κ ( ⋅ , ⋅ ) \kappa(\cdot, \cdot) κ(⋅,⋅) 计算的结果。有了这样的函数,我们就不必直接去计算高维甚至无穷维特征空间中的内积,于是式(3.3)可重写为
max α ∑ i = 1 m α i − 1 2 ∑ i = 1 m ∑ j = 1 m α i α j y i y j κ ( x i , x j ) s.t. ∑ i = 1 m α i y i = 0 , α i ⩾ 0 , i = 1 , 2 , ... , m . (3.5) \begin{aligned} & \max_{\alpha} \sum_{i=1}^m \alpha_i - \frac{1}{2} \sum_{i=1}^m \sum_{j=1}^m \alpha_i \alpha_j y_i y_j \kappa(x_i, x_j) \\ & \text{s.t. } \sum_{i=1}^m \alpha_i y_i = 0, \\ & \quad \quad \alpha_i \geqslant 0, \quad i = 1, 2, \dots, m. \end{aligned} \tag{3.5} αmaxi=1∑mαi−21i=1∑mj=1∑mαiαjyiyjκ(xi,xj)s.t. i=1∑mαiyi=0,αi⩾0,i=1,2,...,m.(3.5)
求解后即可得到
f ( x ) = w T ϕ ( x ) + b = ∑ i = 1 m α i y i ϕ ( x i ) T ϕ ( x ) + b = ∑ i = 1 m α i y i κ ( x , x i ) + b . (3.6) \begin{aligned} f(x) &= w^T \phi(x) + b \\ &= \sum_{i=1}^m \alpha_i y_i \phi(x_i)^T \phi(x) + b \\ &= \sum_{i=1}^m \alpha_i y_i \kappa(x, x_i) + b. \end{aligned} \tag{3.6} f(x)=wTϕ(x)+b=i=1∑mαiyiϕ(xi)Tϕ(x)+b=i=1∑mαiyiκ(x,xi)+b.(3.6)
这里的函数 κ ( ⋅ , ⋅ ) \kappa(\cdot, \cdot) κ(⋅,⋅) 就是**"核函数"(kernel function)**。式(3.6)显示出模型最优解可通过训练样本的核函数展开,这一展式亦称"支持向量展开"(support vector expansion)。
显然,若已知合适映射 ϕ ( ⋅ ) \phi(\cdot) ϕ(⋅) 的具体形式,则可写出核函数 κ ( ⋅ , ⋅ ) \kappa(\cdot, \cdot) κ(⋅,⋅)。但在现实任务中我们通常不知道 ϕ ( ⋅ ) \phi(\cdot) ϕ(⋅) 是什么形式,那么,合适的核函数是否一定存在呢?什么样的函数能做核函数呢?我们有下面的定理:
定理 1 (核函数) 令 X \mathcal{X} X 为输入空间, κ ( ⋅ , ⋅ ) \kappa(\cdot, \cdot) κ(⋅,⋅) 是定义在 X × X \mathcal{X} \times \mathcal{X} X×X 上的对称函数,则 κ \kappa κ 是核函数当且仅当对于任意数据 D = { x 1 , x 2 , ... , x m } D = \{x_1, x_2, \dots, x_m\} D={x1,x2,...,xm},"核矩阵"(kernel matrix) K \mathbf{K} K 总是半正定的:
K = [ κ ( x 1 , x 1 ) ⋯ κ ( x 1 , x j ) ⋯ κ ( x 1 , x m ) ⋮ ⋱ ⋮ ⋱ ⋮ κ ( x i , x 1 ) ⋯ κ ( x i , x j ) ⋯ κ ( x i , x m ) ⋮ ⋱ ⋮ ⋱ ⋮ κ ( x m , x 1 ) ⋯ κ ( x m , x j ) ⋯ κ ( x m , x m ) ] \mathbf{K} = \begin{bmatrix} \kappa(x_1, x_1) & \cdots & \kappa(x_1, x_j) & \cdots & \kappa(x_1, x_m) \\ \vdots & \ddots & \vdots & \ddots & \vdots \\ \kappa(x_i, x_1) & \cdots & \kappa(x_i, x_j) & \cdots & \kappa(x_i, x_m) \\ \vdots & \ddots & \vdots & \ddots & \vdots \\ \kappa(x_m, x_1) & \cdots & \kappa(x_m, x_j) & \cdots & \kappa(x_m, x_m) \end{bmatrix} K= κ(x1,x1)⋮κ(xi,x1)⋮κ(xm,x1)⋯⋱⋯⋱⋯κ(x1,xj)⋮κ(xi,xj)⋮κ(xm,xj)⋯⋱⋯⋱⋯κ(x1,xm)⋮κ(xi,xm)⋮κ(xm,xm)
定理 1 表明,只要一个对称函数所对应的核矩阵半正定,它就能作为核函数使用。事实上,对于一个半正定核矩阵,总能找到一个与之对应的映射 ϕ \phi ϕ。换言之,任何一个核函数都隐式地定义了一个称为"再生核希尔伯特空间"(Reproducing Kernel Hilbert Space, 简称 RKHS)的特征空间。
通过前面的讨论可知,我们希望样本在特征空间内线性可分,因此特征空间的好坏对支持向量机的性能至关重要。需注意的是,在不知道特征映射的形式时,我们并不知道什么样的核函数是合适的,而核函数也仅是隐式地定义了这个特征空间。于是,"核函数选择"成为支持向量机的最大变数。若核函数选择不合适,则意味着将样本映射到了一个不合适的特征空间,很可能导致性能不佳。
下表列出了几种常用的核函数:
| 名称 | 表达式 | 参数 |
|---|---|---|
| 线性核 | κ ( x i , x j ) = x i T x j \kappa(x_i, x_j) = x_i^T x_j κ(xi,xj)=xiTxj | |
| 多项式核 | κ ( x i , x j ) = ( x i T x j ) d \kappa(x_i, x_j) = (x_i^T x_j)^d κ(xi,xj)=(xiTxj)d | d ⩾ 1 d \geqslant 1 d⩾1 为多项式的次数 |
| 高斯核 | $\kappa(x_i, x_j) = \exp \left( - \frac{ | |
| 拉普拉斯核 | $\kappa(x_i, x_j) = \exp \left( - \frac{ | |
| Sigmoid 核 | κ ( x i , x j ) = tanh ( β x i T x j + θ ) \kappa(x_i, x_j) = \tanh(\beta x_i^T x_j + \theta) κ(xi,xj)=tanh(βxiTxj+θ) | tanh \tanh tanh 为双曲正切函数, β > 0 , θ < 0 \beta > 0, \theta < 0 β>0,θ<0 |
此外,还可通过函数组合得到,例如:
-
若 κ 1 \kappa_1 κ1 和 κ 2 \kappa_2 κ2 为核函数,则对于任意正数 γ 1 , γ 2 \gamma_1, \gamma_2 γ1,γ2,其线性组合
γ 1 κ 1 + γ 2 κ 2 (3.7) \gamma_1 \kappa_1 + \gamma_2 \kappa_2 \tag{3.7} γ1κ1+γ2κ2(3.7)也是核函数;
-
若 κ 1 \kappa_1 κ1 和 κ 2 \kappa_2 κ2 为核函数,则核函数的直积
κ 1 ⊗ κ 2 ( x , z ) = κ 1 ( x , z ) κ 2 ( x , z ) (3.8) \kappa_1 \otimes \kappa_2(x, z) = \kappa_1(x, z)\kappa_2(x, z) \tag{3.8} κ1⊗κ2(x,z)=κ1(x,z)κ2(x,z)(3.8)也是核函数;
-
若 κ 1 \kappa_1 κ1 为核函数,则对于任意函数 g ( x ) g(x) g(x),
κ ( x , z ) = g ( x ) κ 1 ( x , z ) g ( z ) (3.9) \kappa(x, z) = g(x)\kappa_1(x, z)g(z) \tag{3.9} κ(x,z)=g(x)κ1(x,z)g(z)(3.9)也是核函数。
python
from sklearn.datasets import make_circles
# 1. 生成非线性数据 (环形数据)
X, y = make_circles(n_samples=100, factor=0.1, noise=0.1, random_state=0)
# 2. 定义绘图函数
def plot_boundary(model, X, y, title):
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = model.decision_function(xy).reshape(XX.shape)
ax.contour(XX, YY, Z, colors='k', levels=[0], alpha=0.5, linestyles=['-'])
plt.title(title)
plt.figure(figsize=(10, 4))
# 3. 线性核 SVM (失败案例)
plt.subplot(1, 2, 1)
clf_linear = svm.SVC(kernel='linear').fit(X, y)
plot_boundary(clf_linear, X, y, "Linear Kernel (Failed)")
# 4. RBF 核 SVM (成功案例)
plt.subplot(1, 2, 2)
clf_rbf = svm.SVC(kernel='rbf', C=10).fit(X, y)
plot_boundary(clf_rbf, X, y, "RBF Kernel (Success)")
plt.show()
4. 软间隔与正则化
在前面的讨论中,我们一直假定训练样本在样本空间或特征空间中是线性可分的,即存在一个超平面能将不同类的样本完全划分开。然而,在现实任务中往往很难确定合适的核函数使得训练样本在特征空间中线性可分;退一步说,即便恰好找到了某个核函数使训练集在特征空间中线性可分,也很难断定这个貌似线性可分的结果不是由于过拟合所造成的。
缓解该问题的一个办法是允许支持向量机在一些样本上出错。为此,要引入**"软间隔"(soft margin)**的概念,如下图所示。
具体来说,前面介绍的支持向量机形式是要求所有样本均满足约束:
y i ( w T x i + b ) ⩾ 1. (4.1) y_i(w^T x_i + b) \geqslant 1. \tag{4.1} yi(wTxi+b)⩾1.(4.1)
即所有样本都必须划分正确,这称为**"硬间隔"(hard margin)**,而软间隔则是允许某些样本不满足约束
y i ( w T x i + b ) ⩾ 1. (4.2) y_i(w^T x_i + b) \geqslant 1. \tag{4.2} yi(wTxi+b)⩾1.(4.2)
当然,在最大化间隔的同时,不满足约束的样本应尽可能少。于是,优化目标可写为
min w , b 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i = 1 m ℓ 0 / 1 ( y i ( w T x i + b ) − 1 ) , (4.3) \min_{w,b} \frac{1}{2}||w||^2 + C \sum_{i=1}^m \ell_{0/1} \left( y_i(w^T x_i + b) - 1 \right), \tag{4.3} w,bmin21∣∣w∣∣2+Ci=1∑mℓ0/1(yi(wTxi+b)−1),(4.3)
其中 C > 0 C > 0 C>0 是一个常数, ℓ 0 / 1 \ell_{0/1} ℓ0/1 是"0/1损失函数"
ℓ 0 / 1 ( z ) = { 1 , if z < 0 ; 0 , otherwise. (4.4) \ell_{0/1}(z) = \begin{cases} 1, & \text{if } z < 0; \\ 0, & \text{otherwise.} \end{cases} \tag{4.4} ℓ0/1(z)={1,0,if z<0;otherwise.(4.4)
显然,当 C C C 为无穷大时,式(4.3)迫使所有样本均满足约束(4.1),于是式(4.3)等价于硬间隔下的优化目标;当 C C C 取有限值时,式(4.3)允许一些样本不满足约束。
然而, ℓ 0 / 1 \ell_{0/1} ℓ0/1 非凸、非连续,数学性质不太好,使得式(4.3)不易直接求解。于是,人们通常用其他一些函数来代替 ℓ 0 / 1 \ell_{0/1} ℓ0/1,称为**"替代损失"(surrogate loss)**。替代损失函数一般具有较好的数学性质,如它们通常是凸的连续函数且是 ℓ 0 / 1 \ell_{0/1} ℓ0/1 的上界。下图给出了三种常用的替代损失函数:
- hinge 损失 : ℓ h i n g e ( z ) = max ( 0 , 1 − z ) \ell_{hinge}(z) = \max(0, 1-z) ℓhinge(z)=max(0,1−z); \tag{4.5}
- 指数损失(exponential loss) : ℓ e x p ( z ) = exp ( − z ) \ell_{exp}(z) = \exp(-z) ℓexp(z)=exp(−z); \tag{4.6}
- 对率损失(logistic loss) : ℓ l o g ( z ) = log ( 1 + exp ( − z ) ) \ell_{log}(z) = \log(1 + \exp(-z)) ℓlog(z)=log(1+exp(−z)). \tag{4.7}
若采用 hinge 损失,则式(4.3)变成
min w , b 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i = 1 m max ( 0 , 1 − y i ( w T x i + b ) ) . (4.8) \min_{w,b} \frac{1}{2}||w||^2 + C \sum_{i=1}^m \max \left( 0, 1 - y_i(w^T x_i + b) \right). \tag{4.8} w,bmin21∣∣w∣∣2+Ci=1∑mmax(0,1−yi(wTxi+b)).(4.8)
引入**"松弛变量"(slack variables)** ξ i ⩾ 0 \xi_i \geqslant 0 ξi⩾0,可将式(4.8)重写为
min w , b , ξ 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i = 1 m ξ i s.t. y i ( w T x i + b ) ⩾ 1 − ξ i ξ i ⩾ 0 , i = 1 , 2 , ... , m . (4.9) \begin{aligned} & \min_{w,b,\xi} \frac{1}{2}||w||^2 + C \sum_{i=1}^m \xi_i \\ & \text{s.t. } y_i(w^T x_i + b) \geqslant 1 - \xi_i \\ & \quad \quad \xi_i \geqslant 0, \quad i = 1, 2, \dots, m. \end{aligned} \tag{4.9} w,b,ξmin21∣∣w∣∣2+Ci=1∑mξis.t. yi(wTxi+b)⩾1−ξiξi⩾0,i=1,2,...,m.(4.9)
这就是常用的"软间隔支持向量机"。
显然,式(4.9)中每个样本都有一个对应的松弛变量,用以表征该样本不满足约束的程度。但是,与硬间隔的基本型相似,这仍是一个二次规划问题。于是,通过拉格朗日乘子法可得到式(4.9)的拉格朗日函数
L ( w , b , α , ξ , μ ) = 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i = 1 m ξ i + ∑ i = 1 m α i ( 1 − ξ i − y i ( w T x i + b ) ) − ∑ i = 1 m μ i ξ i , (4.10) \begin{aligned} L(w, b, \alpha, \xi, \mu) &= \frac{1}{2}||w||^2 + C \sum_{i=1}^m \xi_i \\ &\quad + \sum_{i=1}^m \alpha_i \left( 1 - \xi_i - y_i(w^T x_i + b) \right) - \sum_{i=1}^m \mu_i \xi_i, \end{aligned} \tag{4.10} L(w,b,α,ξ,μ)=21∣∣w∣∣2+Ci=1∑mξi+i=1∑mαi(1−ξi−yi(wTxi+b))−i=1∑mμiξi,(4.10)
其中 α i ⩾ 0 , μ i ⩾ 0 \alpha_i \geqslant 0, \mu_i \geqslant 0 αi⩾0,μi⩾0 是拉格朗日乘子。
令 L ( w , b , α , ξ , μ ) L(w, b, \alpha, \xi, \mu) L(w,b,α,ξ,μ) 对 w , b , ξ i w, b, \xi_i w,b,ξi 的偏导为零可得
w = ∑ i = 1 m α i y i x i , (4.11) w = \sum_{i=1}^m \alpha_i y_i x_i, \tag{4.11} w=i=1∑mαiyixi,(4.11)
0 = ∑ i = 1 m α i y i , (4.12) 0 = \sum_{i=1}^m \alpha_i y_i, \tag{4.12} 0=i=1∑mαiyi,(4.12)
C = α i + μ i . (4.13) C = \alpha_i + \mu_i. \tag{4.13} C=αi+μi.(4.13)
将式(4.11)-(4.13)代入式(4.10)即可得到式(4.9)的对偶问题
max α ∑ i = 1 m α i − 1 2 ∑ i = 1 m ∑ j = 1 m α i α j y i y j x i T x j s.t. ∑ i = 1 m α i y i = 0 , 0 ⩽ α i ⩽ C , i = 1 , 2 , ... , m . (4.14) \begin{aligned} & \max_{\alpha} \sum_{i=1}^m \alpha_i - \frac{1}{2} \sum_{i=1}^m \sum_{j=1}^m \alpha_i \alpha_j y_i y_j x_i^T x_j \\ & \text{s.t. } \sum_{i=1}^m \alpha_i y_i = 0, \\ & \quad \quad 0 \leqslant \alpha_i \leqslant C, \quad i = 1, 2, \dots, m. \end{aligned} \tag{4.14} αmaxi=1∑mαi−21i=1∑mj=1∑mαiαjyiyjxiTxjs.t. i=1∑mαiyi=0,0⩽αi⩽C,i=1,2,...,m.(4.14)
将式(4.14)与硬间隔下的对偶问题对比可看出,两者唯一的差别就在于对偶变量的约束不同:前者是 0 ⩽ α i ⩽ C 0 \leqslant \alpha_i \leqslant C 0⩽αi⩽C,后者是 0 ⩽ α i 0 \leqslant \alpha_i 0⩽αi。于是,可采用与硬间隔支持向量机同样的算法求解式(4.14);在引入核函数后也能得到同样的"支持向量展开"。
类似硬间隔,对软间隔支持向量机,KKT 条件要求
{ α i ⩾ 0 , μ i ⩾ 0 , y i f ( x i ) − 1 + ξ i ⩾ 0 , α i ( y i f ( x i ) − 1 + ξ i ) = 0 , ξ i ⩾ 0 , μ i ξ i = 0. (4.15) \begin{cases} \alpha_i \geqslant 0, \quad \mu_i \geqslant 0, \\ y_i f(x_i) - 1 + \xi_i \geqslant 0, \\ \alpha_i (y_i f(x_i) - 1 + \xi_i) = 0, \\ \xi_i \geqslant 0, \quad \mu_i \xi_i = 0. \end{cases} \tag{4.15} ⎩ ⎨ ⎧αi⩾0,μi⩾0,yif(xi)−1+ξi⩾0,αi(yif(xi)−1+ξi)=0,ξi⩾0,μiξi=0.(4.15)
于是,对任意训练样本 ( x i , y i ) (x_i, y_i) (xi,yi),总有 α i = 0 \alpha_i = 0 αi=0 或 y i f ( x i ) = 1 − ξ i y_i f(x_i) = 1 - \xi_i yif(xi)=1−ξi。若 α i = 0 \alpha_i = 0 αi=0,则该样本不会对 f ( x ) f(x) f(x) 有任何影响;若 α i > 0 \alpha_i > 0 αi>0,则必有 y i f ( x i ) = 1 − ξ i y_i f(x_i) = 1 - \xi_i yif(xi)=1−ξi,即该样本是支持向量:由式(4.13)可知,若 α i < C \alpha_i < C αi<C,则 μ i > 0 \mu_i > 0 μi>0,进而有 ξ i = 0 \xi_i = 0 ξi=0,即该样本恰在最大间隔边界上;若 α i = C \alpha_i = C αi=C,则有 μ i = 0 \mu_i = 0 μi=0,此时若 ξ i ⩽ 1 \xi_i \leqslant 1 ξi⩽1 则该样本落在最大间隔内部,若 ξ i > 1 \xi_i > 1 ξi>1 则该样本被错误分类。由此可看出,软间隔支持向量机的最终模型仅与支持向量有关,即通过采用 hinge 损失函数仍保持了稀疏性。
那么,能否对式(4.3)使用其他的替代损失函数呢?
可以发现,如果使用对率损失函数 ℓ l o g \ell_{log} ℓlog 来替代式(4.3)中的 0/1 损失函数,则几乎就得到了对率回归模型(Logistic Regression)。实际上,支持向量机与对率回归的优化目标相近,通常情形下它们的性能也相当。对率回归的优势主要在于其输出具有自然的概率意义,即在给出预测标记的同时也给出了概率,而支持向量机的输出不具有概率意义,欲得到概率输出需进行特殊处理 [Platt, 2000];此外,对率回归能直接用于多分类任务,支持向量机为此则需进行推广 [Hsu and Lin, 2002]。另一方面,从图 6.5 可看出,hinge 损失有一块"平坦"的零区域,这使得支持向量机的解具有稀疏性,而对率损失是光滑的单调递减函数,不能导出类似支持向量的概念,因此对率回归的解依赖于更多的训练样本,其预测开销更大。
我们还可以把式(4.3)中的 0/1 损失函数换成别的替代损失函数以得到其他学习模型,这些模型的性质与所用的替代损失函数直接相关,但它们具有一个共性:优化目标中的第一项用来描述划分超平面的"间隔"大小,另一项 ∑ i = 1 m ℓ ( f ( x i ) , y i ) \sum_{i=1}^m \ell(f(x_i), y_i) ∑i=1mℓ(f(xi),yi) 用来表述训练集上的误差,可写为更一般的形式
min f Ω ( f ) + C ∑ i = 1 m ℓ ( f ( x i ) , y i ) , (4.16) \min_{f} \Omega(f) + C \sum_{i=1}^m \ell(f(x_i), y_i), \tag{4.16} fminΩ(f)+Ci=1∑mℓ(f(xi),yi),(4.16)
其中 Ω ( f ) \Omega(f) Ω(f) 称为**"结构风险"(structural risk),用于描述模型 f f f 的某些性质;第二项 ∑ i = 1 m ℓ ( f ( x i ) , y i ) \sum_{i=1}^m \ell(f(x_i), y_i) ∑i=1mℓ(f(xi),yi) 称为 "经验风险"(empirical risk),用于描述模型与训练数据的契合程度; C C C 用于对二者进行折中。从经验风险最小化的角度来看, Ω ( f ) \Omega(f) Ω(f) 表述了我们希望获得具有何种性质的模型(例如希望获得复杂度较小的模型),这为引入领域知识和用户意图提供了途径;另一方面,该信息有助于削减假设空间,从而降低了最小化训练误差的过拟合风险。从这个角度来说,式(4.16)称为 "正则化"(regularization)**问题, Ω ( f ) \Omega(f) Ω(f) 称为正则化项, C C C 则称为正则化常数。 L p L_p Lp 范数(norm)是常用的正则化项,其中 L 2 L_2 L2 范数 ∣ ∣ w ∣ ∣ 2 ||w||_2 ∣∣w∣∣2 倾向于 w w w 的分量取值尽量均衡,即非零分量个数尽量稠密,而 L 0 L_0 L0 范数 ∣ ∣ w ∣ ∣ 0 ||w||_0 ∣∣w∣∣0 和 L 1 L_1 L1 范数 ∣ ∣ w ∣ ∣ 1 ||w||_1 ∣∣w∣∣1 则倾向于 w w w 的分量尽量稀疏,即非零分量个数尽量少。
python
# 生成有一些重叠的数据
X, y = make_blobs(n_samples=100, centers=2, random_state=6, cluster_std=1.2)
plt.figure(figsize=(12, 5))
# 对比不同的 C 值
C_values = [0.1, 100]
for i, C_val in enumerate(C_values):
plt.subplot(1, 2, i + 1)
# 训练模型
clf = svm.SVC(kernel='linear', C=C_val)
clf.fit(X, y)
# 绘图
plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.Paired)
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim()
xx = np.linspace(xlim[0], xlim[1], 30)
yy = np.linspace(ylim[0], ylim[1], 30)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
# 绘制边界和间隔
ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])
# 圈出支持向量
ax.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100,
linewidth=1, facecolors='none', edgecolors='r')
plt.title(f"Soft Margin SVM (C={C_val})")
plt.show()
5. 支持向量回归 (SVR)
现在我们来考虑回归问题。给定训练样本 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ... , ( x m , y m ) } D = \{(x_1, y_1), (x_2, y_2), \dots, (x_m, y_m)\} D={(x1,y1),(x2,y2),...,(xm,ym)}, y i ∈ R y_i \in \mathbb{R} yi∈R,希望学得一个形如 f ( x ) = w T x + b f(x) = w^T x + b f(x)=wTx+b 的回归模型,使得 f ( x ) f(x) f(x) 与 y y y 尽可能接近, w w w 和 b b b 是待确定的模型参数。
对样本 ( x , y ) (x, y) (x,y),传统回归模型通常直接基于模型输出 f ( x ) f(x) f(x) 与真实输出 y y y 之间的差别来计算损失,当且仅当 f ( x ) f(x) f(x) 与 y y y 完全相同时,损失才为零。与此不同,**支持向量回归(Support Vector Regression, 简称 SVR)**假设我们能容忍 f ( x ) f(x) f(x) 与 y y y 之间最多有 ϵ \epsilon ϵ 的偏差,即仅当 f ( x ) f(x) f(x) 与 y y y 之间的差别绝对值大于 ϵ \epsilon ϵ 时才计算损失。如图 6.6 所示,这相当于以 f ( x ) f(x) f(x) 为中心,构建了一个宽度为 2 ϵ 2\epsilon 2ϵ 的间隔带,若训练样本落入此间隔带,则认为是被预测正确的。
于是,SVR 问题可形式化为
min w , b 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i = 1 m ℓ ϵ ( f ( x i ) − y i ) , (5.1) \min_{w,b} \frac{1}{2}||w||^2 + C \sum_{i=1}^m \ell_{\epsilon}(f(x_i) - y_i), \tag{5.1} w,bmin21∣∣w∣∣2+Ci=1∑mℓϵ(f(xi)−yi),(5.1)
其中 C C C 为正则化常数, ℓ ϵ \ell_{\epsilon} ℓϵ 是图 6.7 所示的 ϵ \epsilon ϵ-不敏感损失( ϵ \epsilon ϵ-insensitive loss)函数
ℓ ϵ ( z ) = { 0 , if ∣ z ∣ ⩽ ϵ ; ∣ z ∣ − ϵ , otherwise. (5.2) \ell_{\epsilon}(z) = \begin{cases} 0, & \text{if } |z| \leqslant \epsilon; \\ |z| - \epsilon, & \text{otherwise.} \end{cases} \tag{5.2} ℓϵ(z)={0,∣z∣−ϵ,if ∣z∣⩽ϵ;otherwise.(5.2)
引入松弛变量 ξ i \xi_i ξi 和 ξ ^ i \hat{\xi}i ξ^i,可将式(5.1)重写为
min w , b , ξ , ξ ^ 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i = 1 m ( ξ i + ξ ^ i ) s.t. f ( x i ) − y i ⩽ ϵ + ξ i , y i − f ( x i ) ⩽ ϵ + ξ ^ i , ξ i ⩾ 0 , ξ ^ i ⩾ 0 , i = 1 , 2 , ... , m . (5.3) \begin{aligned} & \min{w,b,\xi,\hat{\xi}} \frac{1}{2}||w||^2 + C \sum_{i=1}^m (\xi_i + \hat{\xi}_i) \\ & \text{s.t. } f(x_i) - y_i \leqslant \epsilon + \xi_i, \\ & \quad \quad y_i - f(x_i) \leqslant \epsilon + \hat{\xi}_i, \\ & \quad \quad \xi_i \geqslant 0, \hat{\xi}_i \geqslant 0, \quad i = 1, 2, \dots, m. \end{aligned} \tag{5.3} w,b,ξ,ξ^min21∣∣w∣∣2+Ci=1∑m(ξi+ξ^i)s.t. f(xi)−yi⩽ϵ+ξi,yi−f(xi)⩽ϵ+ξ^i,ξi⩾0,ξ^i⩾0,i=1,2,...,m.(5.3)
类似软间隔支持向量机,通过引入拉格朗日乘子 μ i ⩾ 0 , μ ^ i ⩾ 0 , α i ⩾ 0 , α ^ i ⩾ 0 \mu_i \geqslant 0, \hat{\mu}i \geqslant 0, \alpha_i \geqslant 0, \hat{\alpha}i \geqslant 0 μi⩾0,μ^i⩾0,αi⩾0,α^i⩾0,由拉格朗日乘子法可得到式(5.3)的拉格朗日函数
L ( w , b , α , α ^ , ξ , ξ ^ , μ , μ ^ ) = 1 2 ∣ ∣ w ∣ ∣ 2 + C ∑ i = 1 m ( ξ i + ξ ^ i ) − ∑ i = 1 m μ i ξ i − ∑ i = 1 m μ ^ i ξ ^ i + ∑ i = 1 m α i ( f ( x i ) − y i − ϵ − ξ i ) + ∑ i = 1 m α ^ i ( y i − f ( x i ) − ϵ − ξ ^ i ) . (5.4) \begin{aligned} L(w, b, \alpha, \hat{\alpha}, \xi, \hat{\xi}, \mu, \hat{\mu}) &= \frac{1}{2}||w||^2 + C \sum{i=1}^m (\xi_i + \hat{\xi}i) - \sum{i=1}^m \mu_i \xi_i - \sum{i=1}^m \hat{\mu}i \hat{\xi}i \\ &\quad + \sum{i=1}^m \alpha_i (f(x_i) - y_i - \epsilon - \xi_i) + \sum{i=1}^m \hat{\alpha}_i (y_i - f(x_i) - \epsilon - \hat{\xi}_i). \end{aligned} \tag{5.4} L(w,b,α,α^,ξ,ξ^,μ,μ^)=21∣∣w∣∣2+Ci=1∑m(ξi+ξ^i)−i=1∑mμiξi−i=1∑mμ^iξ^i+i=1∑mαi(f(xi)−yi−ϵ−ξi)+i=1∑mα^i(yi−f(xi)−ϵ−ξ^i).(5.4)
将 f ( x ) = w T x + b f(x) = w^T x + b f(x)=wTx+b 代入,再令 L ( w , b , α , α ^ , ξ , ξ ^ , μ , μ ^ ) L(w, b, \alpha, \hat{\alpha}, \xi, \hat{\xi}, \mu, \hat{\mu}) L(w,b,α,α^,ξ,ξ^,μ,μ^) 对 w , b , ξ i w, b, \xi_i w,b,ξi 和 ξ ^ i \hat{\xi}i ξ^i 的偏导为零可得
w = ∑ i = 1 m ( α ^ i − α i ) x i , (5.5) w = \sum{i=1}^m (\hat{\alpha}i - \alpha_i) x_i, \tag{5.5} w=i=1∑m(α^i−αi)xi,(5.5)
0 = ∑ i = 1 m ( α ^ i − α i ) , (5.6) 0 = \sum{i=1}^m (\hat{\alpha}_i - \alpha_i), \tag{5.6} 0=i=1∑m(α^i−αi),(5.6)
C = α i + μ i , (5.7) C = \alpha_i + \mu_i, \tag{5.7} C=αi+μi,(5.7)
C = α ^ i + μ ^ i . (5.8) C = \hat{\alpha}_i + \hat{\mu}_i. \tag{5.8} C=α^i+μ^i.(5.8)
将式(5.5)-(5.8)代入式(5.4),即可得到 SVR 的对偶问题
max α , α ^ ∑ i = 1 m y i ( α ^ i − α i ) − ϵ ( α ^ i + α i ) − 1 2 ∑ i = 1 m ∑ j = 1 m ( α ^ i − α i ) ( α ^ j − α j ) x i T x j s.t. ∑ i = 1 m ( α ^ i − α i ) = 0 , 0 ⩽ α i , α ^ i ⩽ C . (5.9) \begin{aligned} & \max_{\alpha, \hat{\alpha}} \sum_{i=1}^m y_i (\hat{\alpha}i - \alpha_i) - \epsilon(\hat{\alpha}i + \alpha_i) \\ & \quad \quad - \frac{1}{2} \sum{i=1}^m \sum{j=1}^m (\hat{\alpha}_i - \alpha_i)(\hat{\alpha}j - \alpha_j) x_i^T x_j \\ & \text{s.t. } \sum{i=1}^m (\hat{\alpha}_i - \alpha_i) = 0, \\ & \quad \quad 0 \leqslant \alpha_i, \hat{\alpha}_i \leqslant C. \end{aligned} \tag{5.9} α,α^maxi=1∑myi(α^i−αi)−ϵ(α^i+αi)−21i=1∑mj=1∑m(α^i−αi)(α^j−αj)xiTxjs.t. i=1∑m(α^i−αi)=0,0⩽αi,α^i⩽C.(5.9)
上述过程中需满足 KKT 条件,即要求
{ α i ( f ( x i ) − y i − ϵ − ξ i ) = 0 , α ^ i ( y i − f ( x i ) − ϵ − ξ ^ i ) = 0 , α i α ^ i = 0 , ξ i ξ ^ i = 0 , ( C − α i ) ξ i = 0 , ( C − α ^ i ) ξ ^ i = 0. (5.10) \begin{cases} \alpha_i (f(x_i) - y_i - \epsilon - \xi_i) = 0, \\ \hat{\alpha}_i (y_i - f(x_i) - \epsilon - \hat{\xi}_i) = 0, \\ \alpha_i \hat{\alpha}_i = 0, \quad \xi_i \hat{\xi}_i = 0, \\ (C - \alpha_i)\xi_i = 0, \quad (C - \hat{\alpha}_i)\hat{\xi}_i = 0. \end{cases} \tag{5.10} ⎩ ⎨ ⎧αi(f(xi)−yi−ϵ−ξi)=0,α^i(yi−f(xi)−ϵ−ξ^i)=0,αiα^i=0,ξiξ^i=0,(C−αi)ξi=0,(C−α^i)ξ^i=0.(5.10)
可以看出,当且仅当 f ( x i ) − y i − ϵ − ξ i = 0 f(x_i) - y_i - \epsilon - \xi_i = 0 f(xi)−yi−ϵ−ξi=0 时 α i \alpha_i αi 能取非零值,当且仅当 y i − f ( x i ) − ϵ − ξ ^ i = 0 y_i - f(x_i) - \epsilon - \hat{\xi}_i = 0 yi−f(xi)−ϵ−ξ^i=0 时 α ^ i \hat{\alpha}_i α^i 能取非零值。换言之,仅当样本 ( x i , y i ) (x_i, y_i) (xi,yi) 不落入 ϵ \epsilon ϵ-间隔带中,相应的 α i \alpha_i αi 和 α ^ i \hat{\alpha}_i α^i 才能取非零值。此外,约束 f ( x i ) − y i − ϵ − ξ i = 0 f(x_i) - y_i - \epsilon - \xi_i = 0 f(xi)−yi−ϵ−ξi=0 和 y i − f ( x i ) − ϵ − ξ ^ i = 0 y_i - f(x_i) - \epsilon - \hat{\xi}_i = 0 yi−f(xi)−ϵ−ξ^i=0 不能同时成立,因此 α i \alpha_i αi 和 α ^ i \hat{\alpha}_i α^i 中至少有一个为零。
将式(5.5)代入 f ( x ) = w T x + b f(x) = w^T x + b f(x)=wTx+b,则 SVR 的解形如
f ( x ) = ∑ i = 1 m ( α ^ i − α i ) x i T x + b . (5.11) f(x) = \sum_{i=1}^m (\hat{\alpha}_i - \alpha_i) x_i^T x + b. \tag{5.11} f(x)=i=1∑m(α^i−αi)xiTx+b.(5.11)
能使式(5.11)中的 ( α ^ i − α i ) ≠ 0 (\hat{\alpha}_i - \alpha_i) \neq 0 (α^i−αi)=0 的样本即为 SVR 的支持向量,它们必落在 ϵ \epsilon ϵ-间隔带之外。显然,SVR 的支持向量仅是训练样本的一部分,即其解仍具有稀疏性。
由 KKT 条件(5.10)可看出,对每个样本 ( x i , y i ) (x_i, y_i) (xi,yi) 都有 ( C − α i ) ξ i = 0 (C - \alpha_i)\xi_i = 0 (C−αi)ξi=0 且 α i ( f ( x i ) − y i − ϵ − ξ i ) = 0 \alpha_i(f(x_i) - y_i - \epsilon - \xi_i) = 0 αi(f(xi)−yi−ϵ−ξi)=0。于是,在得到 α i \alpha_i αi 后,若 0 < α i < C 0 < \alpha_i < C 0<αi<C,则必有 ξ i = 0 \xi_i = 0 ξi=0,进而有
b = y i + ϵ − ∑ i = 1 m ( α ^ i − α i ) x i T x . (5.12) b = y_i + \epsilon - \sum_{i=1}^m (\hat{\alpha}_i - \alpha_i) x_i^T x. \tag{5.12} b=yi+ϵ−i=1∑m(α^i−αi)xiTx.(5.12)
因此,在求解式(5.9)得到 α i \alpha_i αi 后,理论上来说,可任意选取满足 0 < α i < C 0 < \alpha_i < C 0<αi<C 的样本通过式(5.12)求得 b b b。实践中常采用一种更鲁棒的办法:选取多个(或所有)满足条件 0 < α i < C 0 < \alpha_i < C 0<αi<C 的样本求解 b b b 后取平均值。
若考虑特征映射形式,则相应的,式(5.5)将形如
w = ∑ i = 1 m ( α ^ i − α i ) ϕ ( x i ) . (5.13) w = \sum_{i=1}^m (\hat{\alpha}_i - \alpha_i) \phi(x_i). \tag{5.13} w=i=1∑m(α^i−αi)ϕ(xi).(5.13)
将式(5.13)代入 f ( x ) f(x) f(x),则 SVR 可表示为
f ( x ) = ∑ i = 1 m ( α ^ i − α i ) κ ( x , x i ) + b , (5.14) f(x) = \sum_{i=1}^m (\hat{\alpha}_i - \alpha_i) \kappa(x, x_i) + b, \tag{5.14} f(x)=i=1∑m(α^i−αi)κ(x,xi)+b,(5.14)
其中 κ ( x i , x j ) = ϕ ( x i ) T ϕ ( x j ) \kappa(x_i, x_j) = \phi(x_i)^T \phi(x_j) κ(xi,xj)=ϕ(xi)Tϕ(xj) 为核函数。
python
# 1. 生成回归数据
X = np.sort(5 * np.random.rand(40, 1), axis=0)
y = np.sin(X).ravel()
# 添加噪声
y[::5] += 3 * (0.5 - np.random.rand(8))
# 2. 训练 SVR 模型
# C: 正则化参数, epsilon: 管道宽度
svr_rbf = svm.SVR(kernel='rbf', C=100, gamma=0.1, epsilon=0.1)
svr_rbf.fit(X, y)
# 3. 预测
X_plot = np.linspace(0, 5, 100)[:, None]
y_pred = svr_rbf.predict(X_plot)
# 4. 绘图
plt.figure(figsize=(8, 5))
sv_ind = svr_rbf.support_ # 支持向量索引
plt.scatter(X, y, color='darkorange', label='Data')
plt.scatter(X[sv_ind], y[sv_ind], color='k', s=80, marker='x', label='Support Vectors')
plt.plot(X_plot, y_pred, color='navy', lw=2, label='SVR Model')
# 绘制 epsilon 间隔带
plt.plot(X_plot, y_pred + svr_rbf.epsilon, color='navy', lw=1, ls='--')
plt.plot(X_plot, y_pred - svr_rbf.epsilon, color='navy', lw=1, ls='--')
plt.title('SVR with RBF Kernel (Epsilon Tube)')
plt.legend()
plt.show()
6. 核方法
回顾式(4.14)和(5.14)可发现,给定训练样本 { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ... , ( x m , y m ) } \{(x_1, y_1), (x_2, y_2), \dots, (x_m, y_m)\} {(x1,y1),(x2,y2),...,(xm,ym)},若不考虑偏置项 b b b,则无论 SVM 还是 SVR,学得的模型总能表示成核函数 κ ( x , x i ) \kappa(x, x_i) κ(x,xi) 的线性组合。不仅如此,事实上我们有下面这个称为**"表示定理"(representer theorem)**的更一般的结论:
定理 6.1 (表示定理) 令 H \mathbb{H} H 为核函数 κ \kappa κ 对应的再生核希尔伯特空间, ∣ ∣ ⋅ ∣ ∣ H ||\cdot||{\mathbb{H}} ∣∣⋅∣∣H 表示 H \mathbb{H} H 空间中关于 h h h 的范数,对于任意单调递增函数 Ω : [ 0 , ∞ ] → R \Omega: [0, \infty] \to \mathbb{R} Ω:[0,∞]→R 和任意非负损失函数 ℓ : R m → [ 0 , ∞ ] \ell: \mathbb{R}^m \to [0, \infty] ℓ:Rm→[0,∞],优化问题
min h ∈ H F ( h ) = Ω ( ∣ ∣ h ∣ ∣ H ) + ℓ ( h ( x 1 ) , h ( x 2 ) , ... , h ( x m ) ) (6.1) \min{h \in \mathbb{H}} F(h) = \Omega(||h||_{\mathbb{H}}) + \ell(h(x_1), h(x_2), \dots, h(x_m)) \tag{6.1} h∈HminF(h)=Ω(∣∣h∣∣H)+ℓ(h(x1),h(x2),...,h(xm))(6.1)
的解总可写为
h ∗ ( x ) = ∑ i = 1 m α i κ ( x , x i ) . (6.2) h^*(x) = \sum_{i=1}^m \alpha_i \kappa(x, x_i). \tag{6.2} h∗(x)=i=1∑mαiκ(x,xi).(6.2)
表示定理对损失函数没有限制,对正则化项 Ω \Omega Ω 仅要求单调递增,甚至不要求 Ω \Omega Ω 是凸函数,意味着对于一般的损失函数和正则化项,优化问题(6.1)的最优解 h ∗ ( x ) h^*(x) h∗(x) 都可表示为核函数 κ ( x , x i ) \kappa(x, x_i) κ(x,xi) 的线性组合;这显示出核函数的巨大威力。
人们发展出一系列基于核函数的学习方法,统称为**"核方法"(kernel methods)。最常见的是,通过 "核化"(即引入核函数)来将线性学习器拓展为非线性学习器。下面我们以线性判别分析为例来演示如何通过核化对其进行非线性拓展,从而得到"核线性判别分析"(Kernelized Linear Discriminant Analysis, 简称 KLDA)**。
我们先假设可通过某种映射 ϕ : X → F \phi: \mathcal{X} \to \mathbb{F} ϕ:X→F 将样本映射到一个特征空间 F \mathbb{F} F,然后在 F \mathbb{F} F 中执行线性判别分析,以求得
h ( x ) = w T ϕ ( x ) . (6.3) h(x) = w^T \phi(x). \tag{6.3} h(x)=wTϕ(x).(6.3)
KLDA 的学习目标是
max w J ( w ) = w T S b ϕ w w T S w ϕ w , (6.4) \max_{w} J(w) = \frac{w^T S_b^\phi w}{w^T S_w^\phi w}, \tag{6.4} wmaxJ(w)=wTSwϕwwTSbϕw,(6.4)
其中 S b ϕ S_b^\phi Sbϕ 和 S w ϕ S_w^\phi Swϕ 分别为训练样本在特征空间 F \mathbb{F} F 中的类间散度矩阵和类内散度矩阵。令 X i X_i Xi 表示第 i ∈ { 0 , 1 } i \in \{0, 1\} i∈{0,1} 类样本的集合,其样本数为 m i m_i mi;总样本数 m = m 0 + m 1 m = m_0 + m_1 m=m0+m1。第 i i i 类样本在特征空间 F \mathbb{F} F 中的均值为
μ i ϕ = 1 m i ∑ x ∈ X i ϕ ( x ) , (6.5) \mu_i^\phi = \frac{1}{m_i} \sum_{x \in X_i} \phi(x), \tag{6.5} μiϕ=mi1x∈Xi∑ϕ(x),(6.5)
两个散度矩阵分别为
S b ϕ = ( μ 1 ϕ − μ 0 ϕ ) ( μ 1 ϕ − μ 0 ϕ ) T ; (6.6) S_b^\phi = (\mu_1^\phi - \mu_0^\phi)(\mu_1^\phi - \mu_0^\phi)^T; \tag{6.6} Sbϕ=(μ1ϕ−μ0ϕ)(μ1ϕ−μ0ϕ)T;(6.6)
S w ϕ = ∑ i = 0 1 ∑ x ∈ X i ( ϕ ( x ) − μ i ϕ ) ( ϕ ( x ) − μ i ϕ ) T . (6.7) S_w^\phi = \sum_{i=0}^1 \sum_{x \in X_i} (\phi(x) - \mu_i^\phi)(\phi(x) - \mu_i^\phi)^T. \tag{6.7} Swϕ=i=0∑1x∈Xi∑(ϕ(x)−μiϕ)(ϕ(x)−μiϕ)T.(6.7)
通常我们难以知道映射 ϕ \phi ϕ 的具体形式,因此使用核函数 κ ( x , x i ) = ϕ ( x i ) T ϕ ( x ) \kappa(x, x_i) = \phi(x_i)^T \phi(x) κ(x,xi)=ϕ(xi)Tϕ(x) 来隐式地表达这个映射和特征空间 F \mathbb{F} F。把 J ( w ) J(w) J(w) 作为式(6.1)中的损失函数 ℓ \ell ℓ,再令 Ω = 0 \Omega = 0 Ω=0,由表示定理,函数 h ( x ) h(x) h(x) 可写为
h ( x ) = ∑ i = 1 m α i κ ( x , x i ) , (6.8) h(x) = \sum_{i=1}^m \alpha_i \kappa(x, x_i), \tag{6.8} h(x)=i=1∑mαiκ(x,xi),(6.8)
于是由式(6.3)可得
w = ∑ i = 1 m α i ϕ ( x i ) . (6.9) w = \sum_{i=1}^m \alpha_i \phi(x_i). \tag{6.9} w=i=1∑mαiϕ(xi).(6.9)
令 K ∈ R m × m \mathbf{K} \in \mathbb{R}^{m \times m} K∈Rm×m 为核函数 κ \kappa κ 所对应的核矩阵, ( K ) i j = κ ( x i , x j ) (\mathbf{K})_{ij} = \kappa(x_i, x_j) (K)ij=κ(xi,xj)。令 1 i ∈ { 1 , 0 } m × 1 \mathbf{1}_i \in \{1, 0\}^{m \times 1} 1i∈{1,0}m×1 为第 i i i 类样本的指示向量,即 1 i \mathbf{1}_i 1i 的第 j j j 个分量为 1 当且仅当 x j ∈ X i x_j \in X_i xj∈Xi,否则 1 i \mathbf{1}_i 1i 的第 j j j 个分量为 0。再令
μ ^ 0 = 1 m 0 K 1 0 , (6.10) \hat{\mu}_0 = \frac{1}{m_0} \mathbf{K} \mathbf{1}_0, \tag{6.10} μ^0=m01K10,(6.10)
μ ^ 1 = 1 m 1 K 1 1 , (6.11) \hat{\mu}_1 = \frac{1}{m_1} \mathbf{K} \mathbf{1}_1, \tag{6.11} μ^1=m11K11,(6.11)
M = ( μ ^ 0 − μ ^ 1 ) ( μ ^ 0 − μ ^ 1 ) T , (6.12) \mathbf{M} = (\hat{\mu}_0 - \hat{\mu}_1)(\hat{\mu}_0 - \hat{\mu}1)^T, \tag{6.12} M=(μ^0−μ^1)(μ^0−μ^1)T,(6.12)
N = K K T − ∑ i = 0 1 m i μ ^ i μ ^ i T . (6.13) \mathbf{N} = \mathbf{K} \mathbf{K}^T - \sum{i=0}^1 m_i \hat{\mu}_i \hat{\mu}_i^T. \tag{6.13} N=KKT−i=0∑1miμ^iμ^iT.(6.13)
于是,式(6.4)等价为
max α J ( α ) = α T M α α T N α . (6.14) \max_{\alpha} J(\alpha) = \frac{\alpha^T \mathbf{M} \alpha}{\alpha^T \mathbf{N} \alpha}. \tag{6.14} αmaxJ(α)=αTNααTMα.(6.14)
显然,使用线性判别分析求解方法即可得到 α \alpha α,进而可由式(6.8)得到投影函数 h ( x ) h(x) h(x)。
python
from sklearn.decomposition import KernelPCA
from sklearn.datasets import make_swiss_roll
# 1. 生成 3D 瑞士卷数据
X, color = make_swiss_roll(n_samples=500, noise=0.1, random_state=42)
# 2. 使用 RBF 核进行降维 (Kernel PCA)
# 这一步体现了表示定理的应用,在特征空间进行线性操作(PCA)
kpca = KernelPCA(n_components=2, kernel="rbf", gamma=0.04)
X_kpca = kpca.fit_transform(X)
# 3. 绘图对比
fig = plt.figure(figsize=(12, 5))
# 原始 3D 数据
ax = fig.add_subplot(1, 2, 1, projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=color, cmap=plt.cm.Spectral)
ax.set_title("Original Data (3D)")
# 核方法映射后的 2D 数据
ax2 = fig.add_subplot(1, 2, 2)
ax2.scatter(X_kpca[:, 0], X_kpca[:, 1], c=color, cmap=plt.cm.Spectral)
ax2.set_title("Result of Kernel Method (Kernel PCA)")
plt.show()