Appearance
04 — SVM & Kernel Methods / 支持向量机与核方法
支持向量机(Support Vector Machine, SVM)是经典机器学习的巅峰之一。它的核(kernel /ˈkɜːrnl/)心思想简洁而优美:找到一个能将两类数据分开且间隔最大的超平面。而核技巧(Kernel Trick)更让 SVM 能够在不显式计算高维映射的情况下处理非线性分类(classification /ˌklæsɪfɪˈkeɪʃən/)问题——这一思想深刻影响了后来的核方法(Kernel Methods)乃至高斯过程(Gaussian Processes)。
时间线:
- 1963: Vapnik & Chervonenkis 提出线性支持向量机基本思想
- 1992: Boser, Guyon & Vapnik 引入核技巧(Kernel Trick)
- 1995: Cortes & Vapnik 正式发表 SVM(支持向量机)
1. 最大间隔分类器(Maximum Margin Classifier)
1.1 问题设定
假设我们有一个二分类数据集
决策规则为:
1.2 什么是间隔?
直观上,可以分开两类的超平面有无数个。但哪一个最好?
两类数据点及多个候选超平面:
○ ○ ○ ● ● ●
\ /
○ \ (1) / ●
○ \ / ●
\ /
× ← 超平面 (2) 似乎更"居中"
/ \
○ / \ ●
/ \
○ ○ ○ ● ● ●间隔(Margin) 定义为:到超平面最近的样本点(即支持向量,Support Vectors)到超平面的距离。
- 函数间隔(Functional Margin):
,符号表示分类是否正确,绝对值表示"确信度"。 - 几何间隔(Geometric Margin):
,即函数间隔除以 ,表示样本到超平面的实际欧氏距离。
最大间隔分类器就是在所有能将数据正确分类的超平面中,选择几何间隔最大的那个。
1.3 为什么最大化间隔能带来更好的泛化?
这是 SVM 最深刻的理论洞见之一:
结构风险最小化(Structural Risk Minimization):大间隔意味着超平面两侧有更大的"缓冲带",对小扰动更鲁棒。一个小的输入变化不太可能使样本越过决策边界。
VC 维(Vapnik-Chervonenkis Dimension):间隔
与 VC 维之间存在关系: 其中
是数据分布的半径。间隔越大,VC 维越小,模型的**容量(Capacity)**越低,泛化误差上界越小。 直观理解:想象两块紧挨着的不同颜色的磁铁——如果你只要求它们被隔开,可以有一万种方式。但如果你要求"隔得越远越好",这个分隔方案就唯一确定了,而且对新的磁铁位置最不敏感。
这是奥卡姆剃刀原则(Occam's Razor)在分类问题上的体现:在能正确分类所有样本的超平面中,间隔最大的那个是最简单的。
1.4 形式化定义
最大间隔分类器的目标函数:
等价地(更方便优化):
这里的约束条件将函数间隔归一化(normalization /ˌnɔːrmələˈzeɪʃən/)为 1。因为缩放
和 不会改变超平面本身,我们可以固定 来简化问题。
2. 对偶问题(Dual Problem) 📐
2.1 为什么要转对偶?
上述优化问题是一个凸二次规划(Convex Quadratic Programming),可以直接求解。但转成对偶形式有两个关键好处:
- 对偶问题只涉及数据点的内积(Dot Product)——这为核技巧铺平了道路
- 对偶形式自然引入了稀疏性——只有支持向量对应的拉格朗日乘子非零
2.2 简要推导(Primal → Lagrangian → Dual)
Step 1 — 构造拉格朗日函数(Lagrangian):
为每个约束引入拉格朗日乘子
Step 2 — 对原始变量求极小:
令
Step 3 — 回代得到对偶问题:
将
把"消去 和 "这步算给你看
很多教程到"代回即得"就停了,下面把代数补全。从拉格朗日函数出发,先把括号展开:
用第二步的两个条件做替换。 条件
第一项(范数):
第二项(同样代入
关键:这两项形式完全相同。 第一项是
这正是上面的对偶目标。约束
2.3 核心洞察
注意对偶问题中,数据点
此外,KKT 条件(Karush-Kuhn-Tucker Conditions)告诉我们:
这意味着
这就是 SVM 的稀疏性(Sparsity):最终的决策函数仅由少数支持向量决定。
2.4 软间隔(Soft Margin)
当数据不可分时,我们引入松弛变量(Slack Variable)
越大 → 对误分类的惩罚越重 → 决策边界越复杂(可能过拟合(overfitting /ˈoʊvərˈfɪtɪŋ/)) 越小 → 允许更多误分类 → 决策边界更平滑(可能欠拟合(underfitting /ˈʌndərˈfɪtɪŋ/))
🔍 完整演算:拉格朗日对偶推导 — 4 样本手算
📐 公式
原始问题(Primal Problem):
拉格朗日函数(Lagrangian):
对偶问题(Dual Problem):
📖 参数含义
| 符号 | 名称 | 含义 |
|---|---|---|
| 权重向量 | 超平面的法向量,决定决策边界方向 | |
| 偏置 | 超平面到原点的偏移量 | |
| 拉格朗日乘子 | 第 | |
| 输入样本 | 第 | |
| 类别标签 | ||
| 内积 |
📝 公式来源
对偶推导分三步:
- 构造 Lagrangian: 将约束
以 为权重加入目标函数 - 对
求极小: 令偏导为零得到 的表达式和 的约束条件 - 回代消去
: 代入 Lagrangian 后得到只含 的对偶目标
核心公式
✏️ 手算演示
给定 4 个样本:正类
| 样本 | 特征 | 标签 |
|---|---|---|
Step 1: 计算核矩阵(内积矩阵)
Step 2: 写出对偶目标
其中
展开二次项:
Step 3: 约束条件
Step 4: 求解(示意)
解此二次规划可得最优
🌍 实际意义
- 对偶形式 是核技巧的入口——目标函数只依赖样本内积,替换为核函数即得非线性 SVM
- 稀疏性:
仅对支持向量成立,使得模型在推理时只计算少数样本的核函数 - 实际库:LIBSVM、scikit-learn 的 SVC 均使用对偶形式求解,内部通过 SMO 算法高效迭代
3. 核技巧(Kernel Trick)⭐
3.1 核心问题
现实世界的数据很少是线性可分的。传统的做法是:将数据映射到高维特征空间
原始空间 (2D) 特征空间 (3D)
○ ● ○
○ ○ ● ● ○ ○
○ ● ● → ○ ● ●
○ ● ● ○ ● ●
● ●
两类交织在一起 高维投影后线性可分但直接计算
的维度可能极高(甚至无穷维) - 显式计算和存储高维向量开销巨大
- 我们其实只关心高维空间中的内积,而不是坐标本身
3.2 核函数的定义
核技巧(Kernel Trick) 的核心洞察是:
我们不需要显式地计算
,只需要定义一个核函数(Kernel Function) ,它直接给出了两个数据点在高维特征空间中的内积。
回想对偶问题的目标函数,只需将内积替换为核函数:
决策函数也相应地变为:
这是整个 SVM 中最重要的公式。注意我们从头到尾都没有计算
,只计算了 。
3.3 常用核函数
| 核函数 | 公式 | 关键参数 | 特点 |
|---|---|---|---|
| 线性核(Linear) | 无 | 相当于无映射,用于线性可分数据 | |
| 多项式核(Polynomial) | 有限维映射, | ||
| RBF 核(高斯核) | 映射到无穷维,最常用 | ||
| Sigmoid(/ˈsɪɡmɔɪd/) 核 | 类似两层神经网络的激活 |
3.4 RBF 核详解 📐
RBF(Radial Basis Function)核,也称为高斯核(Gaussian Kernel),是实践中使用最广泛的核函数:
参数
小 → 核函数随距离衰减慢 → 每个样本的影响范围大 → 决策边界平滑 → 欠拟合风险 大 → 核函数随距离衰减快 → 每个样本只影响其附近区域 → 决策边界曲折 → 过拟合风险
不同 γ 下的决策边界(详见配套代码 svm_demo.py):
γ = 0.1 (欠拟合) γ = 1.0 (合适) γ = 10 (过拟合)
╱╲ ╱ ╲ ╱╱╱╲╲╲
╱ ╲ ○ ● ╱ ╲ ╱╱ ╲╲ ╲
╱ ╲ ○ ● ● ╱ ○ ╲ ● ╱ ○ ╲ ● ╲
╲ ╱ ○ ● ● ╲ ○○ ●╱ ╲ ○● ●╱
╲ ╱ ● ○ ╲ ● ╱ ╲● ○ ╱
╲╱ ╲ ╱ ╲╱╲╱
边界过于平滑, 边界较好地分离 边界紧紧包住
误分类较多 两类数据 每个样本,过拟合为什么 RBF 核映射到无穷维空间?
将指数展开:
这意味着
这就是核技巧的威力:我们在原始空间中用一行代码计算
,却等价于在无穷维空间中计算了两个向量的内积。
🔍 完整演算:RBF 核手算 — 两样本不同 对比
📐 公式
RBF 核(高斯核)定义:
其中
📖 参数含义
| 符号 | 名称 | 含义 |
|---|---|---|
| 输入样本 | 两个数据点的特征向量 | |
| 欧氏距离平方 | 两点在原始空间中的距离 | |
| 核宽度参数 | 控制核函数的衰减速度, | |
| 指数函数 | 将距离映射到 |
📝 公式来源
RBF 核来源于高斯函数的形状:
其中
核函数值域为
- 当
时取最大值 - 距离越远,值越接近
✏️ 手算演示
给定两点:
Step 1: 计算欧氏距离平方
Step 2: 分别计算两种
情形一:
情形二:
Step 3: 对比分析
| 含义 | |||
|---|---|---|---|
| 距离 5 个单位时仍有 8% 的"相似度" | |||
| 距离 5 个单位时几乎完全不相似 |
🌍 实际意义
控制每个支持向量的影响半径: 越小,每个点的影响范围越大; 越大,每个点只影响其极近邻 - 参数选择直接影响泛化:
太小(如 ):每个点影响全局,边界过于平滑,欠拟合 适中(如 ):边界合理,泛化良好 太大(如 ):每个点只影响自身附近,边界围绕每个样本,过拟合
- 实际调参:常用网格搜索(Grid Search)配合交叉验证选择最优
,典型范围
3.5 Mercer 条件
什么样的函数可以作为核函数?Mercer 条件(Mercer's Condition) 给出了答案:对于任意有限个数据点
这保证了存在某个特征空间
3.6 核技巧的应用范围
核技巧不限于 SVM。任何算法如果其计算只依赖于样本间的内积(即可以写成
- 核感知机(Kernel Perceptron)
- 核 PCA(Kernel PCA)
- 核岭回归(regression /rɪˈɡreʃən/)(Kernel Ridge Regression)
- 核 K-means(Kernel K-means)
核技巧是"将线性算法推广到非线性"的通用框架。
3.7 代码精读:sklearn SVM API 内部结构
调用 SVC.fit() 之后,sklearn 把什么存到模型里?预测时到底算的是哪个公式?下面逐行拆开:
python
from sklearn.svm import SVC
from sklearn.datasets import make_moons
import numpy as np
X, y = make_moons(n_samples=200, noise=0.15, random_state=42)
# kernel='rbf' → 高斯核 K(xi, xj) = exp(-γ||xi - xj||²)
# C=1.0 → 软间隔惩罚(越大越严格分类,边界越复杂)
# gamma='scale' → γ = 1 / (n_features * X.var()),自动缩放
svm = SVC(kernel='rbf', C=1.0, gamma='scale')
svm.fit(X, y)fit() 内部运行的是 SMO 算法(Sequential Minimal Optimization,Platt 1998)——它把大二次规划问题分解成每次只求解两个 fit() 把结果存进以下几个关键属性:
python
print("支持向量数量:", svm.n_support_) # 例如 [32, 28],各类各多少个
print("支持向量坐标:", svm.support_vectors_.shape) # (60, 2) — 这60个点在间隔边界上
print("支持向量下标:", svm.support_.shape) # 在原始 X 中的索引,用于追溯
print("对偶系数 α*y:", svm.dual_coef_.shape) # (1, 60) — 即 α_i * y_i
print("决策边界偏置:", svm.intercept_) # [b],一个标量逐个解释这些属性对应的数学含义:
| 属性 | 数学符号 | 来源 |
|---|---|---|
support_vectors_ | KKT 条件:只有间隔边界上的样本 | |
dual_coef_ | 对偶问题的解,已乘上标签;符号对应 §2.3 公式 | |
intercept_ | 由支持向量的 KKT 互补条件 | |
n_support_ | 各类的支持向量个数 | C 越大 → 间隔越小 → 支持向量越少(更紧贴边界) |
预测时的计算流程:
python
# predict() 内部等价于:
def _predict_manual(svm, X_test):
# 1. 计算测试点与所有支持向量的核函数值
# K[i, j] = exp(-γ * ||X_test[i] - support_vectors[j]||²)
from sklearn.metrics.pairwise import rbf_kernel
gamma = svm._gamma # 实际 γ 值
K = rbf_kernel(X_test, svm.support_vectors_, gamma=gamma)
# K.shape = (n_test, n_sv)
# 2. 决策函数 f(x) = Σ_j (α_j * y_j) * K(x, x_j) + b
# dual_coef_[0] 就是 α_j * y_j
decision = K @ svm.dual_coef_.T + svm.intercept_
# decision.shape = (n_test, 1)
# 3. 取符号得到类别预测
return np.sign(decision).ravel().astype(int)关键点:预测只用到支持向量,不是全部训练数据。这就是 SVM 的稀疏性——60 个支持向量 vs 200 个训练点,推理时只算 60 次核函数。
参数调优的直觉与代码:
python
from sklearn.model_selection import GridSearchCV
param_grid = {
'C': [0.1, 1, 10, 100], # 软间隔惩罚:越大 → 边界越复杂
'gamma': [0.01, 0.1, 1, 10], # RBF 宽度:越大 → 影响范围越小
}
grid = GridSearchCV(SVC(kernel='rbf'), param_grid, cv=5, scoring='accuracy')
grid.fit(X, y)
print("最优参数:", grid.best_params_) # e.g. {'C': 10, 'gamma': 0.1}
print("最优精度:", grid.best_score_)调参的"感知器":
C小 +gamma小 → 决策边界很平滑(欠拟合)C大 +gamma大 → 决策边界紧贴每个点(过拟合)- 最优区间 通常在两者中间,交叉验证找到的"峡谷"处
4. SVM vs 神经网络(Neural Networks)
4.1 哲学对比
| 维度 | SVM | 神经网络 |
|---|---|---|
| 核心思想 | 最大化间隔 + 核技巧 | 层次化特征学习 |
| 优化目标 | 凸优化(保证全局最优) | 非凸优化(可能局部最优) |
| 特征工程 | 依赖核函数的设计 | 自动学习特征表示 |
| 数据效率 | 小样本下表现优异 | 通常需要大量数据 |
| 可解释性 | 支持向量直观可解释 | 黑箱,难以解释 |
| 计算复杂度 | 可大规模并行,GPU 加速 |
4.2 什么时候用 SVM?
- 小样本(
):SVM 通常优于或不输神经网络 - 特征维度高(
):如文本分类,SVM 天然擅长 - 需要可解释性:支持向量提供了模型决策的依据
- 数据量巨大(
):此时 SVM 的二次规划开销过高,神经网络的 minibatch 训练更具优势
4.3 有趣的联系
- SVM 使用 hinge loss + 最大间隔;神经网络通常使用 cross-entropy(/ˈentrəpi/) loss
- 现代深度学习中的"权重衰减(Weight Decay)" 本质上就是 SVM 的最大间隔思想的延续
- 最后一个隐藏层的输出可以看作神经网络学习的特征表示
,而输出层则类似于线性 SVM
2012 年之前,SVM 是机器学习的主导范式。深度学习崛起后,SVM 在大规模任务上被取代,但它在小样本场景、核方法理论以及可解释性方面的价值仍然不可替代。
本章演算盒索引
| 位置 | 演算盒 | 跳转 |
|---|---|---|
| §2 | 🔍 拉格朗日对偶推导 — 4 样本 | 跳转 |
| §3.4 | 🔍 RBF 核手算 — 不同 γ 对比 | 跳转 |
5. 本章小结
| 概念 | 要点 |
|---|---|
| 最大间隔分类器 | 找到几何间隔最大的超平面,泛化误差有理论保证 |
| 支持向量 | 仅位于间隔边界上的样本点决定决策边界,其余样本不影响模型 |
| 对偶问题 | 将原始优化转对偶,目标只依赖数据点的内积 |
| 核技巧 ⭐ | 不计算 |
| RBF 核 | |
| 小 → 欠拟合(边界平滑);大 → 过拟合(边界曲折) | |
| 小 → 更大间隔但可能误分类;大 → 更严格分类但可能过拟合 | |
| SVM vs NN | 小样本选 SVM,大样本选 NN;SVM 凸优化保证全局最优 |
6. 进一步阅读
- The Kernel Trick — 直观解释 (YouTube)
- Support Vector Machines — 3Blue1Brown 可视化讲解
- A Tutorial on Support Vector Machines for Pattern Recognition — Burges, 1998
- LIBSVM: A Library for Support Vector Machines — Chih-Chung Chang & Chih-Jen Lin
- Pattern Recognition and Machine Learning — Christopher Bishop, Chapter 7
- Scikit-learn SVM 文档 — RBF 参数详解
下一章:第5章 — 无监督学习
配套代码:svm_demo.py — SVM 核函数对比实验,RBF 参数
参考文献 (References)
- Vapnik, V. & Chervonenkis, A. (1963). On the uniform convergence of relative frequencies. Doklady Akademii Nauk USSR. — VC 维理论。
- Cortes, C. & Vapnik, V. (1995). Support-vector networks. Machine Learning, 20(3), 273–297. — 正式提出 SVM。
- Boser, B. E., Guyon, I. M. & Vapnik, V. N. (1992). A training algorithm for optimal margin classifiers. COLT, 144–152. — 核技巧的引入。