ML 学习站
跳到正文

支持向量机

最大间隔、核函数、SVM 在非线性问题上的威力。

30 分钟3 / 51,849
加载中...

支持向量机(SVM)是一种经典的分类算法,其核心在于寻找一个最大间隔的超平面来分隔不同类别的数据点。SVM 的**最大间隔**概念确保了分类器具有较好的泛化能力,而**支持向量**是指那些距离超平面最近的样本点,它们决定了超平面的位置。对于线性不可分的数据,SVM 通过**核函数**(如线性核、多项式核、RBF 核和 Sigmoid 核)将数据映射到高维空间,从而实现线性可分。核函数的引入使得 SVM 在处理非线性数据时具有很强的灵活性。此外,SVM 还引入了**软间隔**来处理噪声和异常值,通过调整参数 C 来控制对误分类的容忍度。读者学习后,能够理解 SVM 的工作原理,掌握如何使用核函数处理非线性问题,并能够利用 scikit-learn 等工具进行 SVM 模型的训练和超参数调优。

支持向量机

支持向量机(Support Vector Machine, SVM)是 1990 年代最火的分类算法。它有个非常漂亮的几何直觉:找一条最"宽"的马路,把两类数据分开

核心直觉:最大间隔

假设我们要在二维平面上分两类点。很多条直线都能分开它们,但哪条最好?

       ○ ○                ● ●
     ○ ○ ○              ● ● ●
    ○ ○                  ● ●
   ────────────────────────────  ← 候选分界线 1
       ○ ○                ● ●
        ○               ●
        ──────────────  ← 候选分界线 2 (更靠中间)
       ○ ○                ● ●
        ○               ●
        ──────────────  ← 候选分界线 3 (SVM 选的)

SVM 选的不是"任意分界线",而是到两类最近点距离最大的那条。这就是最大间隔(Maximum Margin)。

那些离分界线最近的样本点叫做支持向量(Support Vector)——它们决定了分界线的位置。其它点爱去哪去哪,不影响结果。

形式化:优化目标

设分界线是 w*x + b = 0。最大间隔等价于最小化 ||w||:

min  (1/2) * ||w||^2
subject to:  y_i * (w*x_i + b) >= 1,  对所有 i

这就是 SVM 的原始优化问题。用拉格朗日乘子法转化成对偶问题后,只有支持向量的 alpha_i > 0,其它点 alpha_i = 0。

核函数:把低维不可分变高维可分

很多真实数据线性不可分——比如经典的"异或"问题:

●  ○
○  ●

2D 平面上一条直线分不开。怎么办?映射到高维!

比如把 (x1, x2) 映射到 (x1, x2, x1^2 + x2^2)。在高维空间里,可能就线性可分了

但显式计算高维映射代价太大。核函数(Kernel Trick)的妙处是:你不需要真的映射,只需要在低维空间里算一个核函数 K(x_i, x_j) = phi(x_i) * phi(x_j)

常用核函数:

核函数公式擅长
线性核K(x_i, x_j) = x_i * x_j线性可分,数据量大
多项式核K(x_i, x_j) = (x_i*x_j + c)^d低维简单非线性
RBF 核(高斯核)`K(x_i, x_j) = exp(-gamma *
Sigmoid 核K(x_i, x_j) = tanh(kappa * x_i*x_j + c)类似神经网络

软间隔:处理噪声和 outlier

现实数据没有完全线性可分的。SVM 引入软间隔(Soft Margin),允许一些样本被分错:

y_i * (w*x_i + b) >= 1 - xi_i,   xi_i >= 0

并把 sum(xi_i) 加到目标函数里作为惩罚。C 参数控制惩罚力度:

  • C 大:对误分类惩罚重 → 间隔窄,过拟合风险高
  • C 小:容忍更多误分类 → 间隔宽,泛化更好

实战 sklearn

from sklearn.svm import SVC
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report

# 1. 数据
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 2. SVM 对特征缩放敏感,必须先标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 3. RBF 核 SVM
model = SVC(kernel='rbf', C=1.0, gamma='scale', random_state=42)
model.fit(X_train, y_train)

# 4. 评估
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred, target_names=['恶性', '良性']))

超参数调优

SVM 有两个关键超参数,通常用 GridSearch 一起调:

from sklearn.model_selection import GridSearchCV

param_grid = {
    'C': [0.1, 1, 10, 100],
    'gamma': [0.001, 0.01, 0.1, 1, 'scale'],
    'kernel': ['rbf']
}

grid = GridSearchCV(SVC(), param_grid, cv=5, scoring='f1')
grid.fit(X_train, y_train)
print(f"最佳参数: {grid.best_params_}")
print(f"最佳 F1: {grid.best_score_:.3f}")

SVM 的优缺点

优点:

  • 几何直觉漂亮,可解释性中等
  • 核函数让它在中小数据集上威力很大
  • 对高维数据(文本)效果好
  • 泛化能力通常不错

缺点:

  • 训练慢:样本量 > 10万 时变得不实用
  • 对特征缩放敏感
  • 超参数(C, gamma)多,调起来费劲
  • 不直接输出概率(可以用 Platt scaling,但代价高)

小结

  • SVM 找最大间隔分界,几何直觉强
  • 核函数让它能处理非线性,是 SVM 最有魅力的设计
  • RBF 核 + 标准化是默认起点
  • 数据规模小到中、特征维度高时,SVM 是首选

练习思考

  1. 为什么 SVM 对特征缩放很敏感?想想距离计算。
  2. sklearn.datasets.make_circles 生成一个同心圆数据,线性核和 RBF 核分别能分开吗?
  3. Cgamma 各自控制什么?尝试用 make_classification 跑一个网格搜索,看参数对边界形状的影响。

章末小测验

检验你对《支持向量机》的掌握程度。

1

SVM 找的超平面有什么特点?

2

SVM 的核函数(Kernel)是用来做什么的?

讨论区(0)

加载评论中...