7
支持向量机 SVM
Support Vector Machine
SVM 就是"找最宽的马路把两群人分开"——在两类之间画一条间隔最大的超平面。小样本、高维场景强;数据一大就慢,现在更多作为理论经典。
数学原理
论最大间隔 + 核技巧
间隔(Margin):两条虚线之间的距离。SVM 要让这个间隔最大。支持向量:落在虚线上的样本,它们决定了超平面位置,其他样本无所谓。软间隔:现实里数据不一定线性可分,允许几个样本走错(Slack 变量),用 C 控制惩罚——C 大 = 不允许走错,C 小 = 容忍更多错分。核技巧:低维线性不可分,映射到高维就可分了——但高维算内积太贵,核函数直接在低维算"等价于高维内积"。
常用核函数
| 核 | 什么时候用 |
|---|---|
| linear | 特征多(文本)时用,和逻辑回归差不多。 |
| rbf(高斯) | 默认万能核,中小数据集首选。 |
| poly | 多项式核,少用。 |
| sigmoid | 少用。 |
完整案例:手写数字识别
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
digits = load_digits()
X, y = digits.data, digits.target
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)
# 网格搜索 C 和 gamma(SVM 两个最重要的超参)
param_grid = {
"C": [0.1, 1, 10, 100],
"gamma": [0.001, 0.01, 0.1, 1]
}
grid = GridSearchCV(SVC(kernel="rbf", random_state=42),
param_grid, cv=5, n_jobs=-1)
grid.fit(X_train_s, y_train)
print("最优参数:", grid.best_params_)
best = grid.best_estimator_
pred = best.predict(X_test_s)
print("测试准确率:", accuracy_score(y_test, pred))
# 测试准确率:0.9861
SVM 必须标准化
SVM 用距离度量,特征量纲差 100 倍会被距离吃掉。不标准化的 RBF 核基本废了。另外 SVM 训练复杂度 O(n²),样本超过 10 万就很慢,这种场景换逻辑回归或线性 SVM(LinearSVC)。
SVM 多分类与回归
# SVM 回归:SVR
from sklearn.svm import SVR
svr = SVR(kernel="rbf", C=1.0, epsilon=0.1)
svr.fit(X_train_s, y_train)
pred = svr.predict(X_test_s)
# SVM 多分类:sklearn 自动用 OvR
svc = SVC(kernel="rbf", decision_function_shape="ovr")
svc.fit(X_train_s, y_train)
本章面试题
面试 · SVM
Q1. 什么是支持向量?
查看答案
离决策超平面最近的样本点。它们决定了间隔的大小,其他样本不影响模型。
Q2. C 大了会怎样?
查看答案
C 大 = 严格分类,不允许错分,容易过拟合;C 小 = 容忍错分,间隔更宽,可能欠拟合。
Q3. 核技巧解决什么问题?
查看答案
把线性不可分问题映射到高维变得可分,同时避免显式映射的计算成本。
Q4. SVM 现在还常用吗?
查看答案
小样本高维(文本、生物信息)还用;大数据表格场景基本被 GBDT 取代;图像/文本被深度学习取代。