支持向量机(SVM)原理详解与Python代码实战
1. 什么是支持向量机?
支持向量机(Support Vector Machine,SVM)是一种监督学习算法,常用于分类和回归。它的核心思路是找一个最优超平面把不同类别的数据分开,并让两类数据到超平面的距离尽可能大。简单理解:画一条线(或一个面),让两边数据离它都足够远。
2. 算法核心概念(简要)
2.1 线性可分与最大间隔
SVM 的优化目标就是最大化间隔(Margin),间隔越大,模型泛化能力越强。数学上等价于最小化 ||w||²,约束条件是每个样本都被正确分类。落在边界上的样本点就是支持向量。
2.2 软间隔与松弛变量
实际数据往往有噪声或不是完全线性可分的。SVM 通过引入松弛变量允许少量样本越界,用惩罚参数C控制容忍度:C 大 → 严格分类(容易过拟合),C 小 → 容忍更多错误(模型更平滑)。
2.3 核技巧
对于非线性数据,SVM 通过核函数把数据映射到高维空间,使其线性可分。常用核函数:线性核、多项式核、RBF(高斯核)、Sigmoid 核。选择哪个核函数直接决定模型能处理多复杂的数据分布。
3. 重点:SVM 参数详解与代码实战
SVM 的使用核心在于理解参数和核函数的选择。下面用代码演示各参数的实际效果。
3.1 环境准备与数据生成
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
生成模拟二分类数据(线性可分)
X, y = datasets.make_classification(n_samples=300, n_features=2,
n_informative=2, n_redundant=0,
n_clusters_per_class=1,
random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
print(f"训练集: {X_train.shape[0]} 样本, 测试集: {X_test.shape[0]} 样本")
3.2 核心参数:kernel(核函数)
kernel 决定了 SVM 用什么样的方式去划分数据,是最重要的参数。
linear:适合线性可分数据,速度快,参数少。
poly:多项式核,适合有一定非线性结构的数据,需要调 degree(多项式次数)。
rbf:高斯核(默认值),最通用,能处理各种非线性数据,需要调 gamma。
sigmoid:类似神经网络的激活函数,较少使用。
# 对比不同核函数的效果
kernels = ['linear', 'poly', 'rbf', 'sigmoid']
for k in kernels:
clf = SVC(kernel=k, gamma='scale') # gamma='scale' 是默认值
clf.fit(X_train, y_train)
score = clf.score(X_test, y_test)
print(f"kernel='{k}' → 测试准确率: {score:.4f}")
3.3 核心参数:C(惩
罚系数)
C 控制模型对错误分类的惩罚力度。C 越大,越不允许分错,决策边界会更复杂;C 越小,允许更多错误,边界更平滑。合理范围通常在 0.1~100。
# 对比不同 C 值(使用 RBF 核)
for c in [0.01, 0.1, 1, 10, 100]:
clf = SVC(kernel='rbf', C=c, gamma='scale')
clf.fit(X_train, y_train)
score = clf.score(X_test, y_test)
n_sv = len(clf.support_vectors_)
print(f"C={c:>5} → 准确率: {score:.4f}, 支持向量数: {n_sv}")
3.4 核心参数:gamma(核系数)
gamma 控制单个样本的影响范围,是 RBF、poly、sigmoid 核的关键参数。
gamma 小:单个样本影响范围大,决策边界平滑(可能欠拟合)。
gamma 大:单个样本影响范围小,决策边界紧贴样本(容易过拟合)。
# 对比不同 gamma 值(固定 C=1)
for g in [0.001, 0.01, 0.1, 1, 10]:
clf = SVC(kernel='rbf', C=1, gamma=g)
clf.fit(X_train, y_train)
score = clf.score(X_test, y_test)
n_sv = len(clf.support_vectors_)
print(f"gamma={g:>6} → 准确率: {score:.4f}, 支持向量数: {n_sv}")
3.5 核心参数:degree(多项式次数)
degree 只在 kernel='poly' 时生效,默认值为 3。degree 越大,模型能拟合越复杂的曲线,但也更容易过拟合。
# 对比不同 degree 值(固定 C=1, gamma='scale')
for d in [1, 2, 3, 4, 5]:
clf = SVC(kernel='poly', degree=d, C=1, gamma='scale')
clf.fit(X_train, y_train)
score = clf.score(X_test, y_test)
print(f"degree={d} → 准确率: {score:.4f}")
3.6 参数调优实战:GridSearchCV
使用网格搜索自动找到最佳参数组合,这是实际项目中最常用的方式。
from sklearn.model_selection import GridSearchCV
定义候选参数范围
param_grid = {
'C': [0.1, 1, 10, 100],
'gamma': [0.001, 0.01, 0.1, 1, 'scale', 'auto'],
'kernel': ['rbf', 'poly', 'linear']
}
5 折交叉验证搜索最佳参数
grid = GridSearchCV(SVC(), param_grid, cv=5, scoring='accuracy', n_jobs=-1)
grid.fit(X_train, y_train)
print("最佳参数组合:", grid.best_params_)
print("最佳交叉验证分数:", grid.best_score_)
用最佳模型评估
best_model = grid.best_estimator_
test_score = best_model.score(X_test, y_test)
print(f"最佳模型测试准确率: {test_score:.4f}")
print(f"支持向量数量: {len(best_model.support_vectors_)}")
3.7 参数速查表
| 参数 | 含义 | 常用取值 | 调参建议 |
|---|---|---|---|
| kernel | 核函数类型 | 'linear', 'poly', 'rbf', 'sigmoid' | 先用默认的 'rbf',线性数据换 'linear' |
| C | 误差惩罚系数 | 0.001~1000 | 在 log 尺度上调,如 [0.01, 0.1, 1, 10, 100] |
| gamma | 单个样本影响半径 | 0.0001~10 或 'scale'/'auto' | 与 C 配合调,先固定 C 再调 gamma |
| degree | 多项式核的次数 | 1~5 | 仅在 kernel='poly' 时有效,一般 2 或 3 |
| class_weight | 类别权重 | None / 'balanced' / dict | 样本不均衡时设为 'balanced' |
4. 优缺点与应用场景
优点
高维有效:特征维度很高时仍能正常工作。
内存高效:只存支持向量,不是全部训练数据。
泛化能力强:通过最大化间隔降低过拟合风险。
核技巧灵活:通过选核函数适应不同数据分布。
缺点
大数据训练慢:样本量超过 10 万时训练开销大。
参数敏感:C、gamma、kernel 的选择直接影响效果。
不直接输出概率:需要额外用 Platt scaling 转换。
典型应用
文本分类:垃圾邮件、情感分析。
图像识别:手写数字、人脸检测。
生物信息学:基因分类、蛋白质分类。
金融风控:信用评分、欺诈检测。
5. 总结
SVM 的核心就是选核函数 + 调 C 和 gamma。实际使用流程:先把 kernel 设为 'rbf',在 log 尺度上对 C 和 gamma 做网格搜索,找到最佳组合后再微调。如果数据显示明显的线性特征,直接改用 kernel='linear',参数更少、训练更快。掌握了参数的含义和调试方法,SVM 就是一个非常可靠实用的分类工具。
更多推荐
所有评论(0)