支持向量机(SVM)全体系梳理

支持向量机(Support Vector Machine,SVM)是机器学习中经典的分类/回归算法,核心思想是找到最优超平面最大化分类间隔,可处理线性可分、线性不可分、非线性及回归任务,泛化能力强。以下从核心概念、分类体系、语法、案例等维度系统梳理。

一、核心基础概念

概念 定义
超平面 n维空间中分割样本的线性边界,方程为 w⋅x+b=0w·x + b = 0wx+b=0www 为法向量,bbb 为截距)
分类间隔 两类样本到超平面的最小距离之和,SVM目标是最大化此间隔
支持向量 距离超平面最近的样本点(决定超平面位置,其他样本不影响)
松弛变量 软间隔SVM中引入的 ξi≥0\xi_i \geq 0ξi0,允许少量样本违反间隔约束
核函数 将低维非线性数据映射到高维线性可分空间的函数,避免高维直接计算(降计算成本)

二、SVM分类体系(方法总览)

SVM类型 适用场景 核心思想 关键参数 sklearn实现类
硬间隔线性SVM 严格线性可分、无噪声 最大化间隔,无惩罚(不允许样本越界) 无(仅线性核) SVC(kernel='linear', C=1e9)(近似)
软间隔线性SVM 线性不可分(少量噪声) 允许少量样本越界,CCC 控制越界惩罚强度 CCC(惩罚系数) SVC(kernel='linear', C=xx)
非线性SVM(核函数) 非线性可分数据集 核函数映射到高维,转化为线性可分问题 kernel、gamma、Ckernel、gamma、CkernelgammaC SVC(kernel='rbf'/'poly'/'sigmoid')
SVM回归(SVR) 连续值回归任务 允许预测值与真实值有 ε\varepsilonε 偏差,最小化间隔 C、epsilon、kernelC、epsilon、kernelCepsilonkernel SVR(kernel='linear'/'rbf')
多分类SVM 多类别分类任务(≥3类) 一对一对(OVO)/一对多(OVR)策略 decisionfunctionshapedecision_function_shapedecisionfunctionshape SVC(decision_function_shape='ovo'/'ovr')

三、各类型SVM详解(语法+参数)

1. 硬间隔线性SVM

核心限制

仅适用于严格线性可分数据,无噪声;实际中几乎不用(数据多含噪声),可通过将惩罚系数 CCC 设为极大值(如1e9)近似实现。

语法(sklearn)
from sklearn.svm import SVC
from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split

# 生成线性可分数据
X, y = make_blobs(n_samples=100, n_features=2, centers=2, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 硬间隔线性SVM(C设为极大值)
hard_svm = SVC(kernel='linear', C=1e9, random_state=42)
hard_svm.fit(X_train, y_train)
y_pred = hard_svm.predict(X_test)
print("硬间隔SVM准确率:", hard_svm.score(X_test, y_test))

2. 软间隔线性SVM

核心改进

引入惩罚系数 CCC

  • C↑C \uparrowC:惩罚越重,模型越接近硬间隔(易过拟合);
  • C↓C \downarrowC:允许更多样本越界(易欠拟合)。
语法(sklearn)
# 软间隔线性SVM(C=1.0为默认值)
soft_svm = SVC(kernel='linear', C=1.0, random_state=42)
soft_svm.fit(X_train, y_train)

# 关键属性
print("支持向量:", soft_svm.support_vectors_)  # 输出支持向量坐标
print("支持向量索引:", soft_svm.support_)      # 支持向量在训练集中的索引
print("每类支持向量数:", soft_svm.n_support_)  # 每类的支持向量数量

3. 非线性SVM(核函数)

核心:核函数选择(关键表格)
核函数 公式 适用场景 sklearn参数设置
线性核 K(xi,xj)=xi⋅xjK(x_i, x_j) = x_i·x_jK(xi,xj)=xixj 线性/近似线性可分数据 kernel='linear'
多项式核 K(xi,xj)=(γxi⋅xj+r)dK(x_i, x_j) = (\gamma x_i·x_j + r)^dK(xi,xj)=(γxixj+r)d 中等复杂度非线性数据 kernel='poly' + degree(次数)、gammacoef0(r)
高斯核(RBF) $K(x_i, x_j) = exp(-\gamma x_i - x_j
Sigmoid核 K(xi,xj)=tanh(γxi⋅xj+r)K(x_i, x_j) = tanh(\gamma x_i·x_j + r)K(xi,xj)=tanh(γxixj+r) 类神经网络场景 kernel='sigmoid' + gammacoef0(r)
关键参数说明
  • γ\gammaγ:核函数系数,γ↑\gamma \uparrowγ 模型越复杂(易过拟合),γ=′scale′\gamma='scale'γ=scale(默认)表示 γ=1/(nfeatures⋅X.var())\gamma=1/(n_{features}·X.var())γ=1/(nfeaturesX.var())
  • degreedegreedegree:多项式核次数,默认3;
  • coef0coef0coef0:多项式/Sigmoid核的常数项,默认0。
语法(sklearn)
# 1. RBF核SVM(最常用)
rbf_svm = SVC(kernel='rbf', C=1.0, gamma='scale', random_state=42)
rbf_svm.fit(X_train, y_train)

# 2. 多项式核SVM
poly_svm = SVC(kernel='poly', degree=3, gamma='scale', coef0=0.0, C=1.0, random_state=42)
poly_svm.fit(X_train, y_train)

# 3. Sigmoid核SVM
sigmoid_svm = SVC(kernel='sigmoid', gamma='scale', coef0=0.0, C=1.0, random_state=42)
sigmoid_svm.fit(X_train, y_train)

4. SVM回归(SVR)

核心思想

不再追求分类间隔,而是允许预测值与真实值有 ε\varepsilonε(epsilon)的偏差,目标是最小化间隔 + 惩罚越界样本。

关键参数
  • ϵ\epsilonϵ:允许的偏差范围,ϵ↑\epsilon \uparrowϵ 模型越简单;
  • 其他参数(C、kernel、gammaC、kernel、gammaCkernelgamma)与分类SVM一致。
语法(sklearn)
from sklearn.svm import SVR
from sklearn.datasets import load_diabetes
from sklearn.metrics import mean_absolute_error

# 加载回归数据集
data = load_diabetes()
X, y = data.data, data.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 线性SVR
linear_svr = SVR(kernel='linear', C=1.0, epsilon=0.1)
linear_svr.fit(X_train, y_train)
y_pred = linear_svr.predict(X_test)
print("线性SVR MAE:", mean_absolute_error(y_test, y_pred))

# RBF核SVR
rbf_svr = SVR(kernel='rbf', C=1.0, gamma='scale', epsilon=0.1)
rbf_svr.fit(X_train, y_train)

5. 多分类SVM

两种策略
  • OVO(One-Vs-One,默认):两两类别构建二分类SVM,共 n(n−1)/2n(n-1)/2n(n1)/2 个模型,预测时投票;
  • OVR(One-Vs-Rest):一类对其余所有类构建二分类SVM,共 nnn 个模型,预测时选概率最大类。
语法(sklearn)
from sklearn.datasets import load_iris
from sklearn.metrics import classification_report

# 加载多分类数据集(鸢尾花,3类)
iris = load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# OVR策略多分类SVM
multi_svm = SVC(kernel='linear', decision_function_shape='ovr', C=1.0, random_state=42)
multi_svm.fit(X_train, y_train)
y_pred = multi_svm.predict(X_test)
print(classification_report(y_test, y_pred))

四、完整案例实战

案例1:非线性SVM分类(月亮数据集)

目标:对比不同核函数的决策边界,处理非线性可分数据。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split

# 1. 生成非线性数据(月亮数据集)
X, y = make_moons(n_samples=200, noise=0.1, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 2. 训练不同核函数的SVM
models = {
    "线性核": SVC(kernel='linear', C=1.0, random_state=42),
    "RBF核": SVC(kernel='rbf', C=1.0, gamma='scale', random_state=42),
    "多项式核(degree=2)": SVC(kernel='poly', degree=2, gamma='scale', random_state=42)
}

# 3. 可视化决策边界
plt.figure(figsize=(15, 5))
x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
xx, yy = np.meshgrid(np.linspace(x_min, x_max, 200), np.linspace(y_min, y_max, 200))

for idx, (name, model) in enumerate(models.items()):
    model.fit(X_train, y_train)
    score = model.score(X_test, y_test)
    
    # 绘制决策边界
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    
    plt.subplot(1, 3, idx+1)
    plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.Spectral)
    plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap=plt.cm.Spectral, edgecolors='k')
    plt.title(f"{name} (准确率:{score:.2f})")
    plt.xlabel("特征1")
    plt.ylabel("特征2")

plt.tight_layout()
plt.show()
结果分析
  • 线性核:无法拟合月亮数据的非线性边界,准确率约0.8;
  • RBF核:完美拟合非线性边界,准确率≈1.0;
  • 二次多项式核:拟合效果接近RBF核,准确率≈0.98。

案例2:SVR回归(波士顿房价预测)

from sklearn.svm import SVR
from sklearn.datasets import fetch_california_housing
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score

# 1. 加载数据并预处理(SVM对特征缩放敏感)
data = fetch_california_housing()
X, y = data.data, data.target
scaler = StandardScaler()  # 特征标准化
X_scaled = scaler.fit_transform(X)

# 2. 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)

# 3. 训练SVR
svr = SVR(kernel='rbf', C=10, gamma='scale', epsilon=0.1)
svr.fit(X_train, y_train)

# 4. 评估
y_pred = svr.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"均方误差(MSE):{mse:.2f}")
print(f"决定系数(R²):{r2:.2f}")
结果分析
  • SVR对特征缩放敏感,必须先标准化;
  • 调整 C=10C=10C=10(增大惩罚)、ϵ=0.1\epsilon=0.1ϵ=0.1 后,R²可达0.8以上,拟合效果较好。

五、关键技巧与注意事项

  1. 特征缩放:SVM基于距离计算,对特征量纲敏感,必须标准化/归一化;
  2. 参数调优
    • CCC:平衡“间隔最大化”和“样本越界惩罚”,建议用网格搜索(GridSearchCV);
    • γ\gammaγ(RBF核):越大模型越复杂,越小越简单;
    • ϵ\epsilonϵ(SVR):根据业务允许的误差范围调整;
  3. 核函数选择
    • 线性/低维数据:线性核(速度快,可解释性强);
    • 复杂非线性数据:RBF核(通用性最强);
    • 中等复杂度数据:多项式核(需调次数);
  4. 样本量:SVM在小样本上表现优秀,大样本(>10万)建议用SGDClassifier(随机梯度下降)或核近似方法。

六、总结

SVM是兼顾理论优美和实践效果的算法,核心优势是小样本下泛化能力强、抗过拟合,缺点是大样本训练慢、对参数和特征缩放敏感。掌握“间隔最大化”核心思想,结合核函数处理非线性问题,配合参数调优,可高效解决分类/回归任务。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐