一、SVM 是什么?
支持向量机(Support Vector Machine, SVM) 是一种监督学习算法,主要用于分类(也可用于回归,称为 SVR)。其核心思想是:
在特征空间中找到一个最优的超平面(decision boundary),使得不同类别的样本被尽可能清晰地分开,并且分类边界到最近样本点的距离(即“间隔”)最大化。
SVM 属于判别模型,追求结构风险最小化(而非经验风险最小化),具有良好的泛化能力。
二、几何直观:最大间隔分类器
2.1 线性可分情况
假设我们有两类数据(+1 和 -1),且线性可分。存在无数个超平面可以将它们分开:
- 但 SVM 选择间隔(margin)最大的那个超平面。
- 间隔:两个平行支持超平面之间的距离。
- 支持向量(Support Vectors):距离决策边界最近的那些样本点,它们“支撑”了边界。
✅ 关键思想:最大间隔 ⇒ 更强的泛化能力,对噪声更鲁棒。
三、数学建模与优化推导
3.1 决策函数
设输入样本为 $\mathbf{x} \in \mathbb{R}^d$,决策超平面为:
$$ \mathbf{w}^\top \mathbf{x} + b = 0 $$
其中:
- $\mathbf{w}$:法向量(决定方向)
- $b$:偏置(决定位置)
分类规则:
$$ f(\mathbf{x}) = \operatorname{sign}(\mathbf{w}^\top \mathbf{x} + b) $$
💡 注:KaTeX 支持\operatorname{sign}
,比\text{sign}
更规范。
3.2 间隔(Margin)的定义
点 $\mathbf{x}_i$ 到超平面的距离为:
$$ \text{distance} = \frac{|\mathbf{w}^\top \mathbf{x}_i + b|}{\lVert \mathbf{w} \rVert} $$
对于正确分类的样本(标签 $y_i \in \{+1, -1\}$),有:
$$ y_i (\mathbf{w}^\top \mathbf{x}_i + b) \geq 1 $$
此时,函数间隔为 $y_i (\mathbf{w}^\top \mathbf{x}_i + b)$,几何间隔为 $\dfrac{y_i (\mathbf{w}^\top \mathbf{x}_i + b)}{\lVert \mathbf{w} \rVert}$。
目标:最大化最小几何间隔 ⇒ 等价于 最小化 $\lVert \mathbf{w} \rVert$。
3.3 原始优化问题(Primal Form)
在线性可分条件下,SVM 的优化问题为:
$$ \begin{array}{ll} \min_{\mathbf{w}, b} & \dfrac{1}{2} \lVert \mathbf{w} \rVert^2 \\ \text{subject to} & y_i (\mathbf{w}^\top \mathbf{x}_i + b) \geq 1, \quad \forall i = 1, \dots, n \end{array} $$
💡 为什么是 $\dfrac{1}{2} \lVert \mathbf{w} \rVert^2$?
为了求导方便(平方可导),且最小化 $\lVert \mathbf{w} \rVert$ 与最小化 $\lVert \mathbf{w} \rVert^2$ 等价。
这是一个凸二次规划(QP)问题,有唯一全局最优解。
四、对偶问题(Dual Form)与拉格朗日乘子法
4.1 引入拉格朗日函数
对每个约束引入拉格朗日乘子 $\alpha_i \geq 0$,构造拉格朗日函数:
$$ \mathcal{L}(\mathbf{w}, b, \boldsymbol{\alpha}) = \frac{1}{2} \lVert \mathbf{w} \rVert^2 - \sum_{i=1}^n \alpha_i \left[ y_i (\mathbf{w}^\top \mathbf{x}_i + b) - 1 \right] $$
4.2 求极小(对 $\mathbf{w}, b$)
令偏导为 0:
$$ \frac{\partial \mathcal{L}}{\partial \mathbf{w}} = 0 \quad \Rightarrow \quad \mathbf{w} = \sum_{i=1}^n \alpha_i y_i \mathbf{x}_i $$
$$ \frac{\partial \mathcal{L}}{\partial b} = 0 \quad \Rightarrow \quad \sum_{i=1}^n \alpha_i y_i = 0 $$
代入原式,得到对偶问题:
$$ \begin{array}{ll} \max_{\boldsymbol{\alpha}} & \displaystyle \sum_{i=1}^n \alpha_i - \frac{1}{2} \sum_{i=1}^n \sum_{j=1}^n \alpha_i \alpha_j y_i y_j \, \mathbf{x}_i^\top \mathbf{x}_j \\ \text{subject to} & \alpha_i \geq 0, \quad \forall i \\ & \displaystyle \sum_{i=1}^n \alpha_i y_i = 0 \end{array} $$
4.3 KKT 条件与支持向量
根据 KKT 条件,最优解满足:
$$ \alpha_i \left[ y_i (\mathbf{w}^\top \mathbf{x}_i + b) - 1 \right] = 0 $$
这意味着:
- 若 $\alpha_i > 0$,则 $y_i (\mathbf{w}^\top \mathbf{x}_i + b) = 1$ → 该样本是支持向量
- 若 $\alpha_i = 0$,则样本不在边界上,对决策无影响
✅ SVM 的稀疏性:最终模型仅由少数支持向量决定!
4.4 决策函数(对偶形式)
将 $\mathbf{w} = \sum \alpha_i y_i \mathbf{x}_i$ 代入,得到:
$$ f(\mathbf{x}) = \operatorname{sign} \left( \sum_{i=1}^n \alpha_i y_i \, \mathbf{x}_i^\top \mathbf{x} + b \right) $$
注意:只有支持向量的 $\alpha_i > 0$,其余为 0。
五、软间隔 SVM(Soft Margin)——处理线性不可分
现实中数据往往线性不可分或含噪声。引入松弛变量(slack variables) $\xi_i \geq 0$:
$$ y_i (\mathbf{w}^\top \mathbf{x}_i + b) \geq 1 - \xi_i $$
优化目标变为:
$$ \begin{array}{ll} \min_{\mathbf{w}, b, \boldsymbol{\xi}} & \dfrac{1}{2} \lVert \mathbf{w} \rVert^2 + C \sum_{i=1}^n \xi_i \\ \text{subject to} & y_i (\mathbf{w}^\top \mathbf{x}_i + b) \geq 1 - \xi_i \\ & \xi_i \geq 0 \end{array} $$
$C$:正则化参数,控制间隔最大化与分类错误容忍度的权衡
- $C \to \infty$:硬间隔(不允许错误)
- $C \to 0$:允许更多错误,间隔更大
对偶问题变为:
$$ 0 \leq \alpha_i \leq C, \quad \sum_{i=1}^n \alpha_i y_i = 0 $$
六、核技巧(Kernel Trick)——处理非线性问题
SVM 的强大之处在于可通过核函数将数据映射到高维空间,实现非线性分类,而无需显式计算高维坐标。
6.1 映射思想
设映射 $\phi: \mathbb{R}^d \to \mathcal{H}$(高维特征空间),则决策函数为:
$$ f(\mathbf{x}) = \operatorname{sign} \left( \sum_{i=1}^n \alpha_i y_i \, \phi(\mathbf{x}_i)^\top \phi(\mathbf{x}) + b \right) $$
但计算 $\phi(\mathbf{x}_i)^\top \phi(\mathbf{x})$ 可能非常昂贵。
6.2 核函数定义
核函数 $K(\mathbf{x}_i, \mathbf{x}_j) = \phi(\mathbf{x}_i)^\top \phi(\mathbf{x}_j)$
只要 $K$ 是正定核(Mercer 核),就存在对应的 $\phi$。
6.3 常用核函数
核函数 | 公式 | 适用场景 |
---|---|---|
线性核 | $K(\mathbf{x}, \mathbf{y}) = \mathbf{x}^\top \mathbf{y}$ | 线性可分 |
多项式核 | $K(\mathbf{x}, \mathbf{y}) = (\gamma \mathbf{x}^\top \mathbf{y} + r)^d$ | 特征交互 |
RBF(高斯)核 | $K(\mathbf{x}, \mathbf{y}) = \exp(-\gamma \lVert \mathbf{x} - \mathbf{y} \rVert^2)$ | 最常用,适合非线性 |
Sigmoid 核 | $K(\mathbf{x}, \mathbf{y}) = \tanh(\gamma \mathbf{x}^\top \mathbf{y} + r)$ | 类神经网络 |
✅ RBF 核优势:能拟合任意复杂边界,但需调参($\gamma, C$)
七、SVM 用于回归(SVR)
支持向量回归(SVR)的目标是:找到一个函数 $f(\mathbf{x})$,使得尽可能多的样本落在宽度为 $2\epsilon$ 的“管子”内。
优化问题:
$$ \min_{\mathbf{w}, b, \boldsymbol{\xi}, \boldsymbol{\xi}^*} \frac{1}{2} \lVert \mathbf{w} \rVert^2 + C \sum_{i=1}^n (\xi_i + \xi_i^*) $$
subject to
$$ \begin{cases} y_i - (\mathbf{w}^\top \mathbf{x}_i + b) \leq \epsilon + \xi_i \\ (\mathbf{w}^\top \mathbf{x}_i + b) - y_i \leq \epsilon + \xi_i^* \\ \xi_i, \xi_i^* \geq 0 \end{cases} $$
同样可使用核技巧。
八、SVM 的优缺点
✅ 优点
- 在高维空间表现优异(如文本分类)
- 内存效率高(仅存储支持向量)
- 通过核函数可处理非线性问题
- 泛化能力强(结构风险最小化)
- 对过拟合有一定抵抗力(尤其在高维低样本时)
❌ 缺点
- 不适合大规模数据集(训练复杂度 $O(n^2) \sim O(n^3)$)
- 对噪声和异常值敏感(尤其在小 $C$ 时)
- 不直接提供概率输出(需通过 Platt scaling 校准)
- 调参较复杂($C, \gamma, \text{kernel}$)
- 难以解释(黑盒模型)
九、实际应用与调参建议
9.1 典型应用场景
- 文本分类(垃圾邮件检测、情感分析)
- 图像识别(手写数字识别)
- 生物信息学(基因分类)
- 小样本高维数据
9.2 调参建议(使用 sklearn)
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
param_grid = {
'C': [0.1, 1, 10, 100],
'gamma': ['scale', 'auto', 0.001, 0.01, 0.1, 1],
'kernel': ['rbf', 'linear']
}
grid = GridSearchCV(SVC(), param_grid, cv=5)
grid.fit(X_train, y_train)
- 默认使用 RBF 核
先标准化数据(SVM 对特征尺度敏感!)
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_train = scaler.fit_transform(X_train)
十、总结:SVM 的核心思想图谱
最大间隔 → 凸优化 → 对偶问题 → 支持向量 → 核技巧 → 非线性分类
↑
软间隔(C参数)
📌 一句话记住 SVM:
“找一个最宽的马路,把两类人分开,只靠站在路边的几个人(支持向量)来定义马路边界。”
附录 详细对比
【以下是对 支持向量机(SVM) 的 Python 代码示例、可视化图解,以及与 逻辑回归(Logistic Regression) 的 详细对比】
一、Python 代码示例(使用 scikit-learn
)
我们将使用一个简单的 2D 人工数据集 来演示 SVM 的分类效果,并对比不同核函数和参数。
1.1 导入库 & 生成数据
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
# 生成非线性可分的 2D 数据(月亮形)
X, y = datasets.make_moons(n_samples=200, noise=0.2, random_state=42)
# 标准化(SVM 对尺度敏感!)
scaler = StandardScaler()
X = scaler.fit_transform(X)
# 划分训练/测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
1.2 训练 SVM(不同核)
# 创建多个 SVM 模型
models = {
"Linear SVM": SVC(kernel='linear', C=1),
"RBF SVM (C=1)": SVC(kernel='rbf', C=1, gamma='scale'),
"RBF SVM (C=100)": SVC(kernel='rbf', C=100, gamma='scale'),
"Poly SVM": SVC(kernel='poly', degree=3, C=1)
}
# 训练并预测
for name, model in models.items():
model.fit(X_train, y_train)
acc = model.score(X_test, y_test)
print(f"{name} 测试准确率: {acc:.3f}")
输出示例:
Linear SVM 测试准确率: 0.833
RBF SVM (C=1) 测试准确率: 0.917
RBF SVM (C=100) 测试准确率: 0.933
Poly SVM 测试准确率: 0.900
✅ 观察:RBF 核在非线性数据上显著优于线性核;高 C
更拟合训练数据(可能过拟合)。
1.3 可视化决策边界
def plot_decision_boundary(model, X, y, title):
h = 0.02
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.coolwarm)
scatter = plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.coolwarm, edgecolors='k')
plt.title(title)
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
return scatter
# 可视化多个模型
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes = axes.ravel()
for idx, (name, model) in enumerate(models.items()):
model.fit(X_train, y_train)
plt.sca(axes[idx])
plot_decision_boundary(model, X, y, name)
# 标出支持向量(仅 SVM 有)
if hasattr(model, 'support_vectors_'):
plt.scatter(model.support_vectors_[:, 0], model.support_vectors_[:, 1],
s=100, facecolors='none', edgecolors='black', linewidth=1.5, label='Support Vectors')
plt.legend()
plt.tight_layout()
plt.show()
🔍 可视化图解说明:
模型 | 决策边界特点 | 支持向量 |
---|---|---|
Linear SVM | 直线分割,无法很好拟合月亮形 | 少量点在边界附近 |
RBF SVM (C=1) | 光滑曲线,泛化好 | 支持向量适中 |
RBF SVM (C=100) | 边界更复杂,贴近训练点(可能过拟合) | 支持向量更多 |
Poly SVM | 多项式曲线,有一定拟合能力 | 支持向量较多 |
📌 关键观察:
- 支持向量 是那些被黑色圆圈标出的点,它们决定了决策边界。
- C 越大,边界越“贴合”数据,间隔越小 → 更容易过拟合。
二、SVM vs 逻辑回归(Logistic Regression)详细对比
维度 | SVM | 逻辑回归 | |
---|---|---|---|
目标函数 | 最大化间隔(几何间隔) | 最大化似然(概率) | |
损失函数 | Hinge Loss: ( \max(0, 1 - y(\mathbf{w}^\top \mathbf{x} + b)) ) | Log Loss: ( \log(1 + e^{-y(\mathbf{w}^\top \mathbf{x} + b)}) ) | |
输出 | 类别标签(±1) (可通过 Platt Scaling 输出概率) | 直接输出概率 ( P(y=1 | \mathbf{x}) ) |
对异常值敏感度 | 较敏感(支持向量可能被异常点拉偏) | 相对鲁棒(所有点都参与损失计算) | |
高维表现 | 极佳(如文本分类,n_features >> n_samples) | 也不错,但可能过拟合 | |
训练速度 | 慢(O(n²~n³)),不适合大数据 | 快(可用 SGD 优化),适合大规模数据 | |
可解释性 | 低(黑盒,尤其用核函数后) | 高(系数可解释特征重要性) | |
是否需要特征缩放 | 必须(距离敏感) | 推荐(加速收敛,影响正则化) | |
是否天然支持多分类 | 是(One-vs-Rest 或 One-vs-One) | 是(Softmax 回归) | |
是否稀疏 | 是(仅支持向量影响模型) | 否(所有样本都影响参数) |
2.1 损失函数对比图
import matplotlib.pyplot as plt
z = np.linspace(-3, 3, 100)
hinge = np.maximum(0, 1 - z)
log_loss = np.log(1 + np.exp(-z))
plt.figure(figsize=(8, 5))
plt.plot(z, hinge, label='Hinge Loss (SVM)', linewidth=2)
plt.plot(z, log_loss, label='Log Loss (Logistic Regression)', linewidth=2)
plt.axvline(1, color='gray', linestyle='--', alpha=0.5, label='Margin boundary (z=1)')
plt.xlabel('z = y * f(x)')
plt.ylabel('Loss')
plt.legend()
plt.title('SVM vs Logistic Regression Loss Functions')
plt.grid(True)
plt.show()
📈 图解说明:
- 当 ( z \geq 1 )(正确分类且在间隔外),SVM 损失为 0,不再优化 → 体现“只关心支持向量”。
- 逻辑回归对所有点都有损失,即使分类正确也会继续优化概率。
- SVM 有“安全间隔”,逻辑回归没有。
2.2 在相同数据上对比 SVM 与逻辑回归
# 训练逻辑回归
lr = LogisticRegression()
lr.fit(X_train, y_train)
lr_acc = lr.score(X_test, y_test)
# 训练 RBF SVM
svm = SVC(kernel='rbf', C=10, gamma='scale', probability=True) # 启用概率
svm.fit(X_train, y_train)
svm_acc = svm.score(X_test, y_test)
print(f"逻辑回归准确率: {lr_acc:.3f}")
print(f"RBF SVM 准确率: {svm_acc:.3f}")
# 可视化对比
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# 逻辑回归
plt.sca(ax1)
plot_decision_boundary(lr, X, y, "Logistic Regression")
ax1.set_title(f"Logistic Regression (Acc: {lr_acc:.2f})")
# SVM
plt.sca(ax2)
plot_decision_boundary(svm, X, y, "RBF SVM")
# 标出支持向量
ax2.scatter(svm.support_vectors_[:, 0], svm.support_vectors_[:, 1],
s=100, facecolors='none', edgecolors='black', linewidth=1.5)
ax2.set_title(f"RBF SVM (Acc: {svm_acc:.2f})")
plt.tight_layout()
plt.show()
💡 结论:
- 在非线性数据上,SVM(RBF)明显优于逻辑回归。
- 逻辑回归只能画出线性边界,而 SVM 可通过核函数拟合复杂形状。
三、何时选择 SVM?何时选择逻辑回归?
场景 | 推荐模型 |
---|---|
小/中等数据集(< 10k 样本) | ✅ SVM |
高维稀疏数据(如文本 TF-IDF) | ✅ SVM(线性核即可) |
需要概率输出 | ✅ 逻辑回归(或 SVM + Platt Scaling) |
大数据集(> 100k 样本) | ✅ 逻辑回归 / 随机森林 / 神经网络 |
需要模型可解释性 | ✅ 逻辑回归 |
特征维度低,边界复杂 | ✅ SVM(RBF 核) |
实时预测要求高 | ✅ 逻辑回归(预测更快) |
四、总结
- SVM 是一个强大的分类器,尤其适合小样本、高维、非线性问题。
- 核技巧使其能处理复杂边界,但需谨慎调参(
C
,gamma
)。 - 逻辑回归更简单、更快、可解释,适合线性问题或需要概率的场景。
- 两者互补:在实际项目中,可先用逻辑回归作为 baseline,再尝试 SVM 提升性能。
📌 实践建议:
- 永远先标准化数据!
- 用
GridSearchCV
调参。- 对于文本分类,线性 SVM 往往比 RBF 更快更好。
- 若数据量大,考虑使用
LinearSVC
(基于 liblinear,比 SVC 快)。