跳转至

14.4   支持向量机

小率把两类同学画在散点图上:一类更适合艺术活动,一类更适合运动活动。两类点之间有一条空带。小率想画一条分界线,但可画的线不止一条。

均哥问他:“哪条线更让人放心?”小率发现,离两边点都远的那条线最稳。这个“尽量留出安全距离”的模型,就是 支持向量机(Support Vector Machine, SVM)

图 14.4.0 在操场上寻找最宽的分隔通道

SVM 不是只找能分开的线,而是找最有余量的线。
对。它追求的是最大间隔,而不是刚好擦边通过。

14.4.1   最大间隔让边界更稳

在线性可分时,SVM 寻找一个超平面:

\[ \mathbf{w}^\top\mathbf{x}+b=0 \]

让两类点被分开,并且到边界最近的点距离尽量大。那些卡住间隔的关键样本叫 支持向量(Support Vectors)

如果标签 \(y_i\in\{-1,+1\}\),硬间隔 SVM 可以写成:

\[ \min_{\mathbf{w},b}\frac{1}{2}\|\mathbf{w}\|^2 \]

约束条件是:

\[ y_i(\mathbf{w}^\top\mathbf{x}_i+b)\ge 1 \]

间隔越大,\(\|\mathbf{w}\|\) 越小。


14.4.2   C 控制犯错的宽容度

现实数据通常不是完全可分。软间隔 SVM 允许少量样本越界,用参数 \(C\) 控制宽容度。

C 的大小 含义 风险
更宽容,允许更多错分 可能欠拟合
更严格,尽量不犯错 可能过拟合
C 越大,模型越不肯放过训练集里的错误?
是的。C 太大时,边界可能被少数噪声点拖着走。

14.4.3   核函数把弯边界变成直问题

当两类点不是直线能分开的,SVM 可以用 核函数(Kernel Function) 隐式把数据映射到更高维,在高维里找线性边界。

常见核函数:

核函数 直觉 适用
线性核 原空间画直线 高维文本、稀疏数据
多项式核 加入特征交互 中小数据
RBF 核 局部相似性 非线性边界

RBF 核常见形式是:

\[ K(\mathbf{x},\mathbf{z})=\exp(-\gamma\|\mathbf{x}-\mathbf{z}\|^2) \]

\(\gamma\) 越大,影响范围越局部,边界越容易弯得很细。


14.4.4   用 Python 调 SVM

from sklearn.datasets import make_moons
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC

X, y = make_moons(n_samples=300, noise=0.25, random_state=2026)

pipe = make_pipeline(StandardScaler(), SVC(kernel="rbf"))
grid = {
    "svc__C": [0.1, 1, 10],
    "svc__gamma": [0.1, 1, 10],
}

search = GridSearchCV(pipe, grid, cv=5, scoring="f1")
search.fit(X, y)

print("最佳参数 =", search.best_params_)
print("交叉验证 F1 =", round(search.best_score_, 3))

SVM 也需要标准化

SVM 依赖距离和内积,特征尺度会影响间隔与核函数。数值特征通常要标准化,并放进 Pipeline 防泄漏。

小率的笔记本

SVM 寻找最大间隔边界,支持向量决定关键边界位置。\(C\) 控制对错分的宽容度,核函数处理非线性。它适合中小规模、高维或边界清晰的数据,但大样本 RBF SVM 会比较慢。