SVM 支持向量机
SVM(支持向量机,Support Vector Machine)是传统机器学习中最大间隔方法(Maximum Margin Method)的代表,由 Vapnik 等人在 1990 年代基于统计学习理论(Statistical Learning Theory)提出。它在整体分类中位于:AI → 机器学习 → 监督学习 → 最大间隔方法(核方法家族)。在 2012 年深度学习崛起之前,SVM 是分类任务的”王者”方法;即使在今天,它在中小样本、高维特征(如基因数据、文本分类)场景中仍有不可替代的优势。监督学习的基础概念见监督学习。
SVM 要解决的问题用一句话概括:在两类点之间修一条尽可能宽的马路。
想象两类数据是马路两边的人群,分类边界就是马路中间的分道线。马路越宽(间隔越大),新数据点就越不容易被”站错边”——这就是**最大间隔(Maximum Margin)**原则。
但现实不是完美的:
- 硬间隔(Hard Margin):要求所有点必须严格分到马路正确的一侧。如果数据有噪声或本身有重叠,硬间隔优化问题根本无解。
- 软间隔(Soft Margin):允许少量点”越线”或落在马路中间,但每越线一个点就施加惩罚(由参数
C控制罚多少)。C大 → 不许犯错(可能过拟合);C小 → 宽容犯错(间隔更宽,泛化更好)。 - 核技巧(Kernel Trick):如果数据在当前空间里无法用一条直线分开,就把它映射到更高维的空间——在那里可能就能分开了。妙处是不需要真的计算高维映射,只需换一个”距离度量”(核函数)。
类比:把红豆和黄豆混在桌上一刀切开。如果混得太均匀切不开(非线性可分),就把桌面”抖”成 3D 的——在空中更容易一刀分开。核技巧就是”不真的抖,但效果一样”。
为什么最大间隔是好策略?——偏差-方差视角
Section titled “为什么最大间隔是好策略?——偏差-方差视角”从偏差-方差分解(Bias-Variance Decomposition)的角度看,SVM 选择最大间隔超平面(而不是任意一个能分开两类的超平面),本质上是在控制模型的假设空间复杂度——间隔越大,模型的 VC 维(Vapnik-Chervonenkis Dimension,一种衡量模型表达能力(即”能画出多复杂的边界”)的理论指标)越低,泛化误差上界越紧。这就是统计学习理论的核心洞见:结构风险最小化(Structural Risk Minimization, SRM)——不仅要拟合训练数据(经验风险小),还要控制模型复杂度(结构风险小)。
线性可分 SVM:硬间隔的优化问题
Section titled “线性可分 SVM:硬间隔的优化问题”给定训练集 ,其中 。我们要找一个超平面 ,使得:
- 所有样本被正确分类:(令间隔为 ,取函数间隔为 1)
- 间隔 最大,等价于最小化
原始优化问题(Primal Problem):
这是一个凸二次规划(Convex Quadratic Programming, QP)问题——目标函数是凸的(二次函数),约束是线性的,因此有唯一全局最优解。
为什么间隔是 ? 对于超平面 ,正类最近的点到平面的函数距离为 ,负类最近的点为 。在函数间隔归一化(令 )后,两条间隔边界分别为 ,几何间隔为 ,总间隔为 。
对偶问题与 KKT 条件
Section titled “对偶问题与 KKT 条件”原始问题不容易直接求解(约束多),通过拉格朗日对偶(Lagrangian Duality)转化为对偶问题后更容易处理,且自然引出核技巧。
构造拉格朗日函数:
其中 是拉格朗日乘子。对 和 求偏导并令其为零(KKT 条件的平稳性条件):
回代得到对偶问题:
关键观察:对偶问题中,样本仅以内积 的形式出现——这正是核技巧得以引入的原因。
KKT 互补条件与支持向量
Section titled “KKT 互补条件与支持向量”KKT 互补条件(Complementarity Condition)给出:
这有两种情况:
- :对应的样本满足 ,即恰好落在间隔边界上——这些就是支持向量(Support Vectors)。
- :对应的样本在间隔边界之外,对模型没有任何影响——删除它们不会改变结果。
支持向量的深刻含义:SVM 的解只由少数支持向量决定,其余样本的增减不影响模型。这种稀疏性(Sparsity)使 SVM 在高维空间中仍能有效泛化——即使特征维度远大于样本数,只要支持向量数有限,模型就不会过拟合。这正是 SVM 在小样本高维场景(如基因数据:几十个样本、上万维特征)中至今仍有优势的原因。
软间隔 SVM:处理不可分数据
Section titled “软间隔 SVM:处理不可分数据”当数据线性不可分时,引入松弛变量(Slack Variable),允许个别样本违反间隔约束:
- 是正则化参数(Regularization Parameter),控制对违反间隔的惩罚力度。
- :退化为硬间隔(不容忍任何违反)。
- 较小:容忍更多违反,间隔更宽,模型更平滑(更强的正则化)。
与正则化的直觉: 等价于正则化系数的倒数—— 大意味着模型复杂度高(弱正则化),容易过拟合; 小意味着模型简单(强正则化),容易欠拟合。实践中用交叉验证选择最优 。
核技巧:高维空间的免费入场券
Section titled “核技巧:高维空间的免费入场券”核心动机:如果数据在原始空间中非线性可分,可以将其映射到更高维的特征空间 ,在那里线性可分。但高维映射的计算代价太高。
核技巧的巧妙之处:注意到对偶问题中样本只以内积形式出现,如果我们能高效计算高维空间中的内积 ,就不需要显式计算 。定义核函数:
只要 满足Mercer 条件(Mercer’s Condition,即核矩阵半正定),它就对应某个高维空间的有效内积。
常用核函数:
| 核函数 | 公式 | 特点 |
|---|---|---|
| 线性核(Linear) | 无映射,高维稀疏数据(文本)首选 | |
| RBF 核 / 高斯核 | 最常用,隐式映射到无穷维空间 | |
| 多项式核(Polynomial) | 适合特征交互已知的场景 | |
| Sigmoid 核 | 类似神经网络的隐层 | |
| 拉普拉斯核 | 比 RBF 更鲁棒于异常值 |
RBF 核为什么映射到无穷维? 的 Taylor 展开包含无限多项,对应无穷维特征空间。这意味着 RBF 核 SVM 理论上可以拟合任意复杂的决策边界——但也因此容易过拟合,需要仔细调 (gamma 越大,每个支持向量影响范围越小,边界越复杂)。
(Gamma)参数的作用
Section titled “γ\gammaγ(Gamma)参数的作用”RBF 核中 (gamma)控制单个样本的影响范围:
- 大: 随距离快速衰减,每个样本影响范围很小 → 决策边界复杂(可能过拟合)
- 小:每个样本影响范围大,远处样本也有影响 → 决策边界平滑(可能欠拟合)
调参经验: 和 通常一起调。常用的网格搜索范围为 ,(指数级搜索比均匀搜索更有效,因为参数的影响是对数尺度的)。
支持向量回归(SVR)
Section titled “支持向量回归(SVR)”SVM 也可推广到回归任务——支持向量回归(Support Vector Regression, SVR)。与分类 SVM 对偶:分类 SVM 要求间隔内的样本”越多越好”(间隔最大化),SVR 则要求间隔内的样本”误差越小越好”(-不敏感损失)。
SVR 的损失函数为 -insensitive loss:
即预测值与真实值偏差在 以内时损失为零(不惩罚小误差),超出 的部分线性惩罚。这种损失使 SVR 对噪声鲁棒,且同样具有支持向量的稀疏性——只有落在 -管(-tube)之外的样本才贡献损失。
与其他方法的联系
Section titled “与其他方法的联系”- SVM vs 逻辑回归:两者都是线性分类器,但 SVM 最大化间隔(只关注边界附近的样本),逻辑回归最大化似然(关注所有样本的概率)。SVM 对异常值更鲁棒,逻辑回归输出有概率解释。当样本量远大于特征数时,逻辑回归通常更好;反之 SVM 更有优势。
- SVM vs 深度学习:深度学习在感知任务(图像、语音、NLP)上全面碾压 SVM,但在小样本、高维结构化数据上 SVM 仍有一席之地——它不需要大量数据来学习特征表示,直接在原始特征空间中找最优边界。
- 核方法家族:核技巧不只用于 SVM。核 PCA(Kernel PCA)做非线性降维、核岭回归(Kernel Ridge Regression)做非线性回归、高斯过程(Gaussian Process)做贝叶斯非线性回归——它们共享”用核函数隐式映射到高维空间”的核心思想。
软间隔 vs 硬间隔
Section titled “软间隔 vs 硬间隔”超平面(决策边界)只由离它最近的几个点撑住——这些点叫支持向量(图中标 ✕ 的点)。删掉其他点不影响结果,这也是 SVM 名字的由来。
核技巧的几何直觉
Section titled “核技巧的几何直觉”核技巧的本质:用核函数代替内积,让模型隐式地在高维空间工作——不需要真的计算 ,只需计算 ,计算量与原始维度相同。
SVM 参数选择决策
Section titled “SVM 参数选择决策”四种核函数对比
Section titled “四种核函数对比”from sklearn.datasets import make_moonsfrom sklearn.svm import SVCfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.metrics import accuracy_score
# 生成月牙形非线性数据(无法用直线分开)X, y = make_moons(n_samples=300, noise=0.2, random_state=42)X = StandardScaler().fit_transform(X) # SVM 对量纲敏感,必须标准化X_tr, X_te, y_tr, y_te = train_test_split(X, y, random_state=42)
# 对比四种核函数for kernel in ["linear", "poly", "rbf", "sigmoid"]: clf = SVC(kernel=kernel, C=1.0, random_state=42) clf.fit(X_tr, y_tr) acc = accuracy_score(y_te, clf.predict(X_te)) n_sv = len(clf.support_) # 支持向量数量 print(f"{kernel:8s} 核 → 准确率 {acc:.2%} 支持向量数 {n_sv}")# 输出示例:# linear 核 → 准确率 82.67% 支持向量数 52# poly 核 → 准确率 90.67% 支持向量数 40# rbf 核 → 准确率 93.33% 支持向量数 33 ← 月牙形数据 RBF 最佳# sigmoid 核 → 准确率 76.00% 支持向量数 61观察:RBF 核不仅准确率最高,支持向量数也最少——说明它用最少的”关键样本”就刻画出了月牙形边界。
网格搜索找最优 C 和 γ
Section titled “网格搜索找最优 C 和 γ”from sklearn.svm import SVCfrom sklearn.model_selection import GridSearchCV, StratifiedKFoldfrom sklearn.datasets import make_classificationfrom sklearn.preprocessing import StandardScaler
# 生成数据并标准化X, y = make_classification(n_samples=500, n_features=10, n_informative=5, random_state=42)X = StandardScaler().fit_transform(X)
# 指数级网格搜索(比均匀搜索更有效)param_grid = { 'C': [0.001, 0.01, 0.1, 1, 10, 100, 1000], 'gamma': [0.001, 0.01, 0.1, 1, 10, 100],}cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)search = GridSearchCV(SVC(kernel='rbf'), param_grid, cv=cv, scoring='accuracy', n_jobs=-1)search.fit(X, y)print(f"最优参数: {search.best_params_}")print(f"5 折交叉验证准确率: {search.best_score_:.2%}")SVR:支持向量回归
Section titled “SVR:支持向量回归”from sklearn.svm import SVRfrom sklearn.datasets import make_regressionfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.metrics import mean_squared_errorimport numpy as np
# 生成非线性回归数据X, y = make_regression(n_samples=300, n_features=5, noise=10, random_state=42)X = StandardScaler().fit_transform(X)y = (y - y.mean()) / y.std() # 标准化目标值
X_tr, X_te, y_tr, y_te = train_test_split(X, y, random_state=42)
# SVR with RBF 核svr = SVR(kernel='rbf', C=1.0, epsilon=0.1, gamma='scale')svr.fit(X_tr, y_tr)pred = svr.predict(X_te)rmse = np.sqrt(mean_squared_error(y_te, pred))print(f"SVR RMSE: {rmse:.3f}")print(f"支持向量数: {len(svr.support_)} / {len(X_tr)} ({len(svr.support_)/len(X_tr):.0%})")# 只有落在 ε-tube 之外的样本成为支持向量从零实现线性 SVM(梯度下降法)
Section titled “从零实现线性 SVM(梯度下降法)”"""用梯度下降(Subgradient Method)求解线性软间隔 SVM 的原始问题。最小化: (1/2)||w||^2 + C * Σ max(0, 1 - y_i*(w·x_i + b))等价于 Hinge Loss + L2 正则。"""import numpy as np
class LinearSVM: def __init__(self, C=1.0, lr=0.01, n_epochs=1000): self.C = C self.lr = lr self.n_epochs = n_epochs
def fit(self, X, y): n, d = X.shape self.w = np.zeros(d) self.b = 0.0 y_signed = np.where(y == 0, -1, 1).astype(float) # 标签转为 ±1
for epoch in range(self.n_epochs): for i in range(n): margin = y_signed[i] * (X[i] @ self.w + self.b) if margin < 1: # Hinge loss 的次梯度: -y_i * x_i(对 w),-y_i(对 b) grad_w = self.w - self.C * y_signed[i] * X[i] grad_b = -self.C * y_signed[i] else: grad_w = self.w # 只剩正则项梯度 grad_b = 0.0 self.w -= self.lr * grad_w self.b -= self.lr * grad_b
def predict(self, X): return np.where(X @ self.w + self.b >= 0, 1, 0)
# 测试from sklearn.datasets import make_classificationX, y = make_classification(n_samples=200, n_features=5, random_state=42)svm = LinearSVM(C=1.0, lr=0.001, n_epochs=500)svm.fit(X, y)acc = (svm.predict(X) == y).mean()print(f"训练集准确率: {acc:.2%}")print(f"权重 w: {svm.w.round(3)}")print(f"偏置 b: {svm.b:.3f}")- 必须标准化:SVM 基于距离计算(特别是 RBF 核的 ),大量纲特征会”淹没”小范围特征。用
StandardScaler或MinMaxScaler预处理是必须步骤。 - 核函数选择经验:
- 样本少、特征多(如文本 TF-IDF)→ 线性核,快且好。使用
LinearSVC(基于 liblinear)比SVC(kernel='linear')(基于 libsvm)在大数据上快得多。 - 样本中等、特征少 → 先试 RBF 核,多数情况表现最好。
- 样本量 > 10 万 → 核 SVM 训练太慢(时间复杂度约 到 ),换随机森林、GBDT 或线性方法。
- 样本少、特征多(如文本 TF-IDF)→ 线性核,快且好。使用
C参数调优:C越大越不许犯错(过拟合风险);C越小越宽容(欠拟合风险)。用网格搜索 + 交叉验证调。- RBF 核的
gamma:gamma 大 → 每个点影响范围小 → 边界复杂(过拟合);gamma 小 → 影响范围大 → 边界平滑。推荐用对数尺度网格搜索。 - 类别不平衡时设
class_weight='balanced':自动按反频率加权,缓解少数类被忽略。 - 概率输出代价高:SVM 的
probability=True内部用 Platt Scaling(在 SVM 输出上再拟合一个逻辑回归)做概率校准,需要额外的 5 折交叉验证,训练时间翻数倍。如果只需要类别标签,不要开。 - Pipeline 防泄漏:标准化和 SVM 必须放进同一个 sklearn Pipeline 中,确保交叉验证时每折只对训练数据做 fit_transform。
- 2025 年实践建议:对于表格数据,优先尝试 XGBoost/LightGBM(见梯度提升树详解),它们通常比 SVM 更快且精度相当。SVM 在小样本高维(< 10k 样本、> 1k 特征)或需要强理论保证的场景中仍有独特价值。
- 文本分类:新闻自动归类到体育/财经/科技等栏目、垃圾邮件过滤——文本经 TF-IDF 向量化后是典型的高维稀疏特征(几万维、大量零值),线性核 SVM 在深度学习普及前是工业界默认方案,至今在小数据集上仍然有效。
- 生物信息学:蛋白质功能分类、基因表达谱分析——样本量小(几十到几百)但特征维度极高(上万个基因),SVM 在小样本高维场景下的泛化能力至今仍有优势。这正是统计学习理论设计的目标场景。
- 人脸识别(早期方案):2000 年代的人脸识别系统(如部分安防门禁)用 PCA 降维后接 SVM 分类,是深度学习取代前的主流方案。
- 手写数字识别:MNIST 数据集上的经典基线,美国邮政 ZIP 编码自动识别系统曾用 SVM 达到工业可用精度。
- 医学诊断:从少量临床指标中预测疾病风险,SVM 的强正则化特性使其在小样本医疗数据上不易过拟合。
- 金融信用评分(传统方案):在 GBDT 普及之前,线性 SVM 曾是信用评分的常用方法之一,尤其适合高维稀疏特征(如 one-hot 编码后的类别特征)。
典型类库与工具
Section titled “典型类库与工具”| 类库 | 语言 | 说明 |
|---|---|---|
| scikit-learn | Python | SVC / SVR / LinearSVC,封装完善、API 统一,中小数据集首选 |
| LIBSVM | C / Java / Python 等 | 台湾大学出品的 SVM 核心实现,scikit-learn 底层也调用它,是业界最广泛使用的 SVM 求解器 |
| LIBLINEAR | C / Python 等 | 专为线性 SVM 和逻辑回归设计,大规模稀疏数据(如文本分类)训练速度远快于核 SVM |
| ThunderSVM | Python / C++ | GPU 加速的 SVM 库,兼容 LIBSVM 接口,大幅缩短大规模数据的训练和推理时间 |
| 术语 | 英文 | 解释 |
|---|---|---|
| 间隔 | Margin | 决策边界到最近样本点(支持向量)的距离,SVM 的目标是使这个间隔最大化 |
| 软间隔 / 硬间隔 | Soft / Hard Margin | 硬间隔要求所有样本严格分类正确;软间隔允许少量样本越线但施加惩罚,更适合有噪声的真实数据 |
| 核函数 | Kernel Function | 在不显式映射到高维空间的情况下计算样本间内积的函数,常用 linear / rbf / poly |
| 支持向量 | Support Vector | 离决策边界最近的样本点,它们”撑住”了超平面,删掉其他样本不影响模型 |
| C 参数 | Regularization Parameter C | 控制对误分类的惩罚力度:C 大→不许犯错(倾向过拟合),C 小→宽容犯错(间隔更宽) |
| gamma | Gamma (RBF Kernel) | RBF 核的参数,控制单个样本的影响范围:gamma 大→边界复杂,gamma 小→边界平滑 |
| VC 维 | VC Dimension | 衡量假设空间复杂度的理论指标,是统计学习理论中泛化能力分析的核心概念 |
| 原始问题 | Primal Problem | SVM 的原始优化问题,最小化 w 的范数平方(即权重向量的模长平方)并受约束于分类约束 |
| 对偶问题 | Dual Problem | 通过拉格朗日对偶转化得到的等价问题,样本以内积形式出现,核技巧的自然入口 |
| KKT 条件 | Karush-Kuhn-Tucker Conditions | 约束优化问题的最优性条件,SVM 的互补松弛条件决定了支持向量的稀疏性 |
| 松弛变量 | Slack Variable (ξ) | 软间隔 SVM 中允许样本违反间隔约束的变量,ξ 越大违反越多 |
| 统计学习理论 | Statistical Learning Theory | Vapnik 等人建立的机器学习泛化理论框架,SVM 的理论基础 |
| 结构风险最小化 | Structural Risk Minimization (SRM) | 同时最小化经验风险(训练误差)和模型复杂度的原则,SVM 的设计哲学 |
| Hinge 损失 | Hinge Loss | ,SVM 软间隔等价的损失函数,对正确分类的样本不产生梯度 |
| 不敏感损失 | ε-Insensitive Loss | SVR 中使用的损失函数,偏差在 ε 内不计损失,使回归对噪声鲁棒 |
- 理论根基:Vapnik–Chervonenkis 统计学习理论(1960s–70s)——VC 维、结构风险最小化(SRM)。推荐教材:Vapnik,《The Nature of Statistical Learning Theory》(1995, 2nd ed. 2000)。
- 关键论文:Boser, Guyon & Vapnik 1992(COLT,引入 kernel trick)→ Cortes & Vapnik 1995 “Support-vector networks”(soft margin 定型,Machine Learning 20:273–297)→ Vapnik 1997 “Support Vector Method for Function Approximation”(SVR)。
- SMO 算法:Platt 1998 “Sequential Minimal Optimization: A Fast Algorithm for Training Support Vector Machines”——高效求解 SVM 对偶问题的启发式算法,LIBSVM 的核心。
- 核方法谱系:核 PCA(Schölkopf et al. 1998,非线性降维)、核岭回归、高斯过程(Rasmussen & Williams 2006)——核技巧的广泛应用远超 SVM 本身。
- LIBSVM:Chang & Lin 2011 “LIBSVM: A library for support vector machines”(ACM TIST)——业界最广泛使用的 SVM 实现的论文。
- 鼎盛期:1990s–2010s,文本分类、生物信息、图像识别的默认方法。
- 后深度学习时代:在感知类任务上被深度学习取代,但在中小样本、高维场景(如基因数据)仍有价值。核方法家族(核 PCA、核回归、高斯过程)仍是活跃理论方向。推荐教材:Schölkopf & Smola,《Learning with Kernels》(2002),核方法的权威著作。