机器学习:支持向量机 SVM 原理与 Python 实战
介绍支持向量机(SVM)的核心原理,包括最优超平面、最大间隔、支持向量、软间隔及核函数机制。通过 Python sklearn 库结合鸢尾花数据集进行实战演示,涵盖二维特征线性分类可视化与全特征多分类任务,并详解模型评估指标与核心 API 参数,帮助读者掌握 SVM 从理论到应用的全流程。

介绍支持向量机(SVM)的核心原理,包括最优超平面、最大间隔、支持向量、软间隔及核函数机制。通过 Python sklearn 库结合鸢尾花数据集进行实战演示,涵盖二维特征线性分类可视化与全特征多分类任务,并详解模型评估指标与核心 API 参数,帮助读者掌握 SVM 从理论到应用的全流程。

支持向量机(Support Vector Machine,SVM)是机器学习领域经典的有监督分类算法,自诞生以来凭借扎实的数学理论、优秀的小样本学习能力、强大的非线性拟合能力,在分类、回归等任务中得到了广泛应用。本文将从通俗的原理讲解入手,深入拆解 SVM 的核心逻辑,再基于 Python+sklearn 实现完整的 SVM 分类任务,包含可视化、模型训练、评估全流程,帮助读者从入门到实战彻底掌握 SVM。
我们用一个经典的故事理解 SVM 的核心思想:很久以前,公主被魔鬼绑架,王子需要完成魔鬼的挑战:用一根棍子分开桌子上两种颜色的球,并且要求后续加入更多球时,这根棍子依然能有效分类。




对应到 SVM 的核心概念里:
两种颜色的球 = 我们的训练数据 棍子 / 纸 = 分类决策边界(超平面) 让棍子两边间隙最大的操作 = 最大间隔最优化 拍桌子让球飞起来 = 核函数(低维映射到高维) 离棍子最近、决定棍子位置的球 = 支持向量
SVM 的核心目标,就是找到一个最优超平面,让不同类别的样本被完美分开,且两类样本到超平面的最小距离(间隔)最大化。
超平面是分类的决策边界,在不同维度空间有不同的表达形式:
二维平面:一条直线,方程为 $w^T x + b = 0$
三维空间:一个平面,方程为 $w^T x + b = 0$
更高维空间:超平面,通用方程为 $w^T x + b = 0$。
其中 $\omega$ 为超平面的法向量(决定超平面方向),$b$ 为偏置项(决定超平面的位置)。
最终的分类决策函数为:$f(x) = \text{sign}(\omega^T x + b)$。
其中 sign 为符号函数,输入大于 0 输出 1(正例),小于 0 输出 -1(负例)。
样本点到超平面的距离,是衡量分类置信度的核心指标,公式为:
结合分类的正确性,我们可以得到几何间隔:当样本分类正确时,$y_i(\omega^T x_i + b) > 0$,因此样本到超平面的几何间隔可写为:
我们的目标是:让离超平面最近的样本点(支持向量)到超平面的距离最大化。通过数学放缩,我们可以约束支持向量满足 $y_i(\omega^T x_i + b) = 1$,此时最大间隔的优化目标可转化为:
约束条件:
这个优化问题可以通过拉格朗日乘子法转化为对偶问题求解,最终得到最优的 $\omega$ 和 $b$,也就是超平面的参数。
在求解过程中,只有满足 $y_i(\omega^T x_i + b) = 1$ 的样本点,对应的拉格朗日乘子 $\alpha_i \neq 0$,这些样本就是支持向量。
SVM 的核心特性之一就是:最终的决策超平面只由少数支持向量决定,哪怕移除其他所有样本,超平面的位置也不会改变。这也是 SVM 在小样本场景下表现优异的核心原因。
现实场景中,很多数据存在噪声点,无法实现完美的线性可分,如果强行追求 100% 分类正确,会导致模型泛化能力极差。因此 SVM 引入了软间隔的概念:允许少数样本点违反约束、出现在间隔带内,甚至被误分类,以此提升模型的泛化能力。
我们引入松弛因子 $\xi_i \geq 0$,将约束条件放宽为:
同时优化目标更新为:
其中 C 为惩罚因子,是 SVM 的核心超参数:
C 越大:对误分类的惩罚越重,模型越不允许出现误分类,容易过拟合,泛化能力弱;
C 越小:对误分类的惩罚越轻,允许更多样本违反约束,模型泛化能力强,容易欠拟合。
对于完全线性不可分的数据,SVM 通过核函数解决问题:将低维空间的线性不可分数据,映射到高维特征空间,使其在高维空间中线性可分,再在高维空间中学习最优超平面。
直接在高维空间计算会带来巨大的计算量,而核函数的核心优势是:在低维空间完成高维空间的内积运算,结果完全一致,大幅降低计算复杂度。
常用的核函数有以下几种:
线性核:$K(x, y) = x^T y$,适用于线性可分的数据,计算速度快,可解释性强;
多项式核:$K(x, y) = (x^T y + 1)^d$,适用于中等规模的非线性数据,可通过 degree 调整多项式维度;
高斯核(RBF,径向基函数):$K(x, y) = \exp(-\gamma ||x-y||^2)$,默认核函数,适用于绝大多数非线性场景,通过 $\gamma$ 调整映射范围:
越小:正态分布越'胖',辐射范围越大,过拟合风险越低;
越大:正态分布越'瘦',辐射范围越小,过拟合风险越高。
有严格的数学理论支撑,可解释性强,不同于黑盒模型;小样本场景下表现优异,最终决策仅由少数支持向量决定;软间隔机制可有效提升模型泛化能力,适配带噪声的现实数据;核函数可完美解决非线性分类问题,避免'维数灾难';泛化能力强,在分类任务中不易过拟合。
对大规模训练样本适配性差,样本量超过 10 万时,核矩阵的存储和计算会耗费大量内存和时间;对核函数和超参数的选择非常敏感,不同参数对模型效果影响极大;预测速度与支持向量的数量成正比,支持向量过多时,预测效率较低。
本次实战使用经典的鸢尾花数据集,分为两个部分:
需要提前安装相关依赖库:
pip install pandas numpy matplotlib scikit-learn
本部分选取鸢尾花数据集的 2 个特征,训练线性核 SVM,并可视化超平面、间隔边界和支持向量,直观理解 SVM 的核心逻辑。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.svm import SVC
data = pd.read_csv("iris.csv", header=None)
data1 = data.iloc[:50, :]
data2 = data.iloc[50:100, :]
data3 = data.iloc[100:, :]
plt.scatter(data1[1], data1[3], marker="^")
plt.scatter(data2[1], data2[3], marker="o")
# 使用 svm 训练
x = data.iloc[:, [1, 3]]
y = data.iloc[:, -1]
svm = SVC(kernel="linear", C=100, random_state=0)
# c 无穷大 float('inf'),则软间隔为 0,不容有其他点进入软间隔内
svm.fit(x, y)
# 可视化 svm 结果
# 参数 w【原始数据为二维数组】
w = svm.coef_[0]
b = svm.intercept_[0]
# 超平面方程 w1*1+w2*2+b=0
x1 = np.linspace(0, 5, 700)
# 超平面方程
x2 = -(w[0]*x1+b)/w[1]
# 上超平面方程
x3 = (1-(w[0]*x1+b))/w[1]
# 下超平面方程
x4 = (-1-(w[0]*x1+b))/w[1]
# 可视化超平面
plt.plot(x1, x2, linewidth=2, color='r')
plt.plot(x1, x3, linewidth=1, color=, linestyle=)
plt.plot(x1, x4, linewidth=, color=, linestyle=)
vet = svm.support_vectors_
plt.scatter(vet[:, ], vet[:, ], c=, marker=)
plt.show()

从可视化结果中我们可以清晰看到:
红色实线为 SVM 学习到的最优分类超平面,完美分隔了两类样本;两条红色虚线为间隔边界,两类样本的间隔被最大化;蓝色 + 标记的点就是支持向量,这些点落在间隔边界上,是决定超平面位置的核心样本,其他样本的移除不会改变超平面的位置。
本部分使用鸢尾花数据集的全部 4 个特征,基于 RBF 核 SVM 完成三分类任务,包含数据划分、模型训练、混淆矩阵可视化、分类报告输出全流程。
鸢尾花数据集包含 3 类鸢尾花,每类 50 个样本,共 150 条数据,4 个特征分别为花萼长度、花萼宽度、花瓣长度、花瓣宽度,我们按照 8:2 划分训练集和测试集。
'''四个特征全训练'''
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
from sklearn import metrics
from sklearn.svm import SVC
datas = pd.read_csv("iris.csv", header=None)
data = datas.iloc[:, :-1].values
target = datas.iloc[:, -1].values
# 数据切分
x_train, x_test, y_train, y_test = train_test_split(
data, target, test_size=0.2, random_state=0
)
# 可视化混淆矩阵
def cm_plot(ah, yp):
cm = confusion_matrix(ah, yp)
plt.matshow(cm, cmap=plt.cm.Blues)
plt.colorbar()
for x in range(len(cm)):
for y in range(len(cm[x])):
plt.annotate(cm[x][y], xy=(y, x), horizontalalignment="center",
color="white", verticalalignment="center")
plt.ylabel('True label')
plt.xlabel('Predicted label')
plt.show()
return plt
# 模型训练
svm = SVC(kernel='rbf', C=10)
svm.fit(x_train, y_train)
# 模型自测试
y_pred = svm.predict(x_train)
cm_plot(y_train, y_pred)
# 测试集测试
y_test_pred = svm.predict(x_test)
cm_plot(y_test, y_test_pred)
# 测试集测试获得分类结果报告
(metrics.classification_report(y_test, y_test_pred))
可视化视图

训练集共 120 个样本,仅出现 2 个误分类样本,整体分类准确率超过 98%,模型在训练数据上拟合效果良好,没有出现欠拟合。
可视化视图

测试集共 30 个样本,所有样本均被正确分类,无任何误分类情况,模型在未见过的测试数据上表现完美,泛化能力优异。

从分类报告可以看到,3 个类别的精确率(precision)、召回率(recall)、F1-score 均为 1.00,整体准确率(accuracy)达到 100%,进一步验证了 SVM 在该分类任务上的优秀表现。
本文使用 sklearn 的 SVC 类实现 SVM 分类,核心参数如下:
| 参数名 | 作用 | 核心说明 |
|---|---|---|
| C | 惩罚因子 | 浮点数,默认 1.0。C 越大,对误分类惩罚越重,易过拟合;C 越小,容错率越高,易欠拟合 |
| kernel | 核函数 | 默认 rbf,可选 linear(线性核)、poly(多项式核)、sigmoid |
| degree | 多项式维度 | 整数,默认 3,仅对 poly 核生效,其他核函数会忽略该参数 |
| gamma | 核函数系数 | 仅对 rbf、poly、sigmoid 生效。gamma 越大,过拟合风险越高;gamma 越小,泛化能力越强 |
| random_state | 随机种子 | 固定随机种子,保证实验结果可复现 |
其中,C、kernel、gamma是对模型效果影响最大的三个超参数,实际使用中建议通过网格搜索 + 交叉验证的方式选择最优参数组合。
本文从通俗的原理入手,深入讲解了 SVM 的最优超平面、最大间隔、支持向量、软间隔、核函数等核心概念,同时基于 Python+sklearn 实现了完整的 SVM 分类任务,包含可视化、模型训练、评估全流程。SVM 作为经典的机器学习算法,在小样本、中等样本量的分类任务中有着不可替代的优势,掌握其核心原理和实战技巧,是机器学习入门的必备技能。读者可以基于本文的代码,更换自己的数据集,调整超参数,进一步深入理解 SVM 的特性。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online