Support Vector Machine (SVM)
支持向量机(SVM)通过最大间隔超平面分隔类别,并使用核函数处理曲线边界。了解其工作原理、调参方法和代码。
支持向量机(SVM)是一种监督学习算法,它通过寻找分隔两个类别的超平面来分类数据,并尽可能扩大边界与每个类别最近训练点之间的间隔。那些最近的点称为支持向量,是决定边界的唯一训练样本。核函数让 SVM 能够学习弯曲边界,而变体则可处理回归和异常值检测。Vladimir Vapnik 及其同事在 AT&T Bell Labs 开发了这种方法:核版本于 1992 年问世,如今使用的软间隔形式则由Cortes 和 Vapnik 于 1995 年发表。在深度学习兴起之前,SVM 曾是文本、图像和生物数据中最准确的分类器之一;如今,它们在特征众多的中小型数据集上仍然表现出色。
SVM 的工作原理#
线性 SVM 根据 w·x + b 的符号预测类别,因此其决策边界为超平面 w·x + b = 0;当权重经过缩放,使最近的点满足 |w·x + b| = 1 时,间隔宽度为 2/‖w‖。训练过程通过最小化 ‖w‖² 来最大化间隔,同时要求每个训练点都位于边界的正确一侧。现实中的类别会有重叠,因此软间隔 SVM 允许点越过间隔,并由正则化参数 C 决定代价。合页损失对间隔之外正确分类的点不计损失,而对其余点则按违反间隔的程度线性增加惩罚。较小的 C 能容忍更多违反情况,并产生更宽、更平滑的间隔;较大的 C 会更紧密地拟合训练数据,但过拟合风险也更高。在训练后的模型中,只有位于间隔上或间隔错误一侧的点具有非零权重;这些点就是支持向量,移动任何其他点而不使其越过间隔,都不会改变边界。
核技巧#
当没有超平面能够分隔类别时,将数据映射到更高维空间可能使类别变得可分:二维中的两个同心圆,在加入第三个特征 x₁² + x₂² 来衡量每个点到圆心的距离后,就能由一个平面分开。在对偶形式中,SVM 训练和预测只通过点对之间的点积来使用数据,因此核函数 k(x, x′) 可以直接返回映射空间中的点积,而无需实际计算映射后的坐标。这就是核技巧。常见的核包括线性核、多项式核和径向基函数(RBF)核 exp(−γ‖x − x′‖²),其中 γ 决定每个支持向量的影响范围。下面的示例使用线性核和 RBF 核,在两个同心圆上拟合 scikit-learn 的 SVC:
from sklearn.datasets import make_circles
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
# Two concentric rings: no straight line separates the classes
X, y = make_circles(n_samples=500, factor=0.4, noise=0.1, random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
for kernel in ("linear", "rbf"):
clf = SVC(kernel=kernel, C=1.0)
clf.fit(X_train, y_train)
print(f"{kernel}: test accuracy {clf.score(X_test, y_test):.2f}, support vectors {clf.n_support_.sum()}")线性核在留出点上的得分为 0.43,比猜测还差,并将 375 个训练点中的 360 个保留为支持向量。RBF 核仅用 42 个支持向量就完美分开了两个圆(1.00)。
选择核函数和超参数#
距离和点积取决于特征尺度,因此 SVM 输入首先要进行标准化。LIBSVM作者编写的实用指南(LIBSVM 是 scikit-learn 的 SVC 背后的库)建议缩放特征,从 RBF 核开始,并通过网格搜索和交叉验证选择 C 和 γ。当特征远多于样本时(例如文本数据),线性核的表现大致相当,而且训练速度快得多。核 SVM 的训练时间至少随样本数呈二次增长,因此当样本超过数万个时,通常会用线性 SVM 或近似核特征取代精确核模型。
SVM 在计算机视觉中的应用#
经典计算机视觉将人工设计的特征与线性 SVM 结合起来。Dalal 和 Triggs 于 2005 年提出的行人检测器使用线性 SVM 对方向梯度直方图(HOG)评分;2014 年的 R-CNN 目标检测器则用每个类别各自的线性 SVM,对每个区域提议的 CNN 特征进行分类,直到 2015 年 Fast R-CNN 用与网络共同训练的 softmax 层取代它们。现代检测器会共同学习特征和分类器,而 SVM 仍可作为固定特征上的快速分类器。对 YOLO26 从 model.embed() 返回的向量(每张图像一个嵌入)训练线性 SVM,就能得到一个线性探测器,无需重新训练网络即可添加新的图像类别。
应用场景#
- 文本分类: 词频向量有数万个稀疏维度,线性 SVM 能够据此准确区分主题、垃圾邮件和情绪。Thorsten Joachims 于 1998 年展示了这一优势。
- 生物信息学: 基因表达研究会根据数千个测量基因、仅几十或几百名患者的数据对肿瘤分类。这种场景下,间隔可以限制过拟合,而字符串核可直接比较蛋白质序列。
- 异常检测: 单类 SVM 只根据正常数据学习边界,并将边界外的点标记出来,适用于故障过于罕见而无法标注的欺诈检测和机器监控场景。
- 回归: 支持向量回归会拟合一个宽度为 ε 的管状区域,忽略小于 ε 的误差,并且只将位于管状区域边缘或之外的点保留为支持向量。
SVM 与相关算法#
- K 近邻(KNN): 保存整个训练集,并在预测时将每个新点与其邻居进行比较;而 SVM 只保留其支持向量。
- 决策树和随机森林: 每次按一个特征进行划分,不需要缩放特征,并且能处理混合的数值型和类别型列;而 SVM 需要数值型且经过缩放的输入。
- 神经网络: 从数据中学习特征映射,而不是通过核函数固定映射,因此能够扩展到数百万张图像;核 SVM 在这种规模下会变得太慢。
- 逻辑回归: 同样学习线性边界,但会针对每个训练点最小化对数损失,并输出概率。SVM 输出边界的有符号距离;scikit-learn 的 SVC 只有通过
probability=True才会生成概率,它会通过内部的 5 折交叉验证拟合 Platt scaling。










