十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SVM支持向量机原理详解:从间隔最大化到核函数与软间隔

SVM支持向量机原理详解:从间隔最大化到核函数与软间隔 简介支持向量机SVM原理PPT课件面向机器学习入门者与算法学习人员系统梳理了这一经典二分类模型的数学脉络。课件从SVM概念与超平面入手结合logistic回归引出形式化表示再逐步讲解函数间隔、几何间隔以及最大间隔分类器的构建思路并详细演示二次规划原问题、拉格朗日对偶及KKT条件等关键推导为后续理解核函数和软间隔优化打下基础。整套资源为1个pptx文件容量464KB共36页图文结合、公式清晰适合自学或备课参考。目前已有294人学习浏览内容覆盖支持向量机的核心原理与常用优化方法既能帮助初学者建立直觉也能辅助中高级读者回顾推导细节。1. 从 logistic 回归到 SVM间隔最大化到底改变了什么接触过分类问题的读者大多从 logistic 回归入手用 sigmoid 函数把线性组合映射到 (0,1)输出作为正类概率。但 logistic 回归在样本量小、特征维度高、两类边界重叠的场景里泛化能力经常不够。SVM 的切入点完全不同——它不估计概率而是直接找一个超平面让两类样本到它的最小距离最大。这个“间隔最大化”的策略最终被证明等价于求解一个凸二次规划问题。这份课件从超平面的数学定义讲起逐步推导函数间隔、几何间隔、拉格朗日对偶和 KKT 条件再用支持向量的概念收束到最终分类器。对我这种看过不少开源代码、但很少回头抠推导的人而言真正有价值的反而是那些在当时觉得“过于数学”的部分为什么约束条件要写成 (y_i(w^Tx_i b) \ge 1)为什么拉格朗日乘子只有支持向量对应的那几项非零以及核函数和软间隔在优化目标里各自改动了什么。这篇博客就按这套逻辑来拆最后补一段可运行的 Python 代码把参数对应到 scikit-learn 的 SVC 实现上。2. 函数间隔与几何间隔SVM 优化目标的度量基础2.1 超平面与分类决策函数课件里对超平面的定义是设 (d) 是 n 维欧式空间 (R^n) 中的一个非零向量(a) 是实数则满足 (dX a) 的点 (X) 组成的集合是一张超平面。写成更常见的分类器形式就是 (w^Tx b 0)。其中 (w) 就是法向量决定超平面的方向(b) 是偏置决定超平面到原点的偏移。决策函数是 (f(x) \text{sign}(w^Tx b))。这里有个多数教材一笔带过、但初学者很容易卡住的点对于任意一个满足条件的超平面 ((w, b))如果对 (w) 和 (b) 同时乘一个正标量 (k)比如 ((2w, 2b))得到的还是同一个超平面决策结果完全不变。也就是说同一张超平面有无数种参数表示。后续所有关于“间隔”的定义本质上都是在解决这个参数冗余带来的度量问题。2.2 函数间隔的定义与局限课件把单个样本的函数间隔定义为[ \hat{\gamma}^{(i)} y^{(i)}(w^Tx^{(i)} b) ]其中 (y^{(i)} \in {-1, 1})。这个定义的意义在于当分类正确时(y^{(i)}) 和 ((w^Tx^{(i)} b)) 同号乘积为正分类错误时乘积为负。乘积的绝对值越大说明样本离决策边界越远模型对这个样本的分类“确信度”越高。全局函数间隔是所有样本中函数间隔最小的那个值也就是最不确信的那个样本的间隔。但函数间隔有一个致命问题因为 (w) 和 (b) 可以任意缩放函数间隔也会跟着等比例变化。还是刚才那个例子((w, b)) 变成 ((2w, 2b)) 之后所有样本的函数间隔都变成原来的 2 倍但超平面本身没变。拿一个随参数缩放而改变的数值做优化目标显然不合理。2.3 几何间隔与参数归一化几何间隔修复了这个问题。单个样本的几何间隔定义为[ \gamma^{(i)} y^{(i)}\frac{w^Tx^{(i)} b}{|w|} ]也就是说在函数间隔的基础上除以法向量的 L2 范数。这样做的几何含义非常直接(w^Tx b 0) 这个超平面到样本点的垂直距离是 (|w^Tx^{(i)} b| / |w|)再乘上符号 (y^{(i)}) 就得到带方向的间隔。无论 (w) 和 (b) 怎么等比例缩放分母也跟着缩放几何间隔保持不变。间隔类型公式是否受参数缩放影响几何含义函数间隔(y(w^Tx b))是带符号的分类确信度几何间隔(y\frac{w^Tx b}{|w|})否样本到超平面的带符号垂直距离课件在此基础上给出的优化目标就是最大化全局几何间隔。引入一个常用的归一化技巧因为参数可以任意缩放不妨直接约束函数间隔最小值为 1即 (y_i(w^Tx_i b) \ge 1)。在这个约束下最大化几何间隔 (\min_i y_i(w^Tx_i b) / |w|) 等价于最大化 (1/|w|)也就等价于最小化 (\frac{1}{2}|w|^2)。为什么是 (\frac{1}{2}|w|^2) 而不是 (|w|)纯粹是为了求导方便平方后梯度是 (w)系数 (\frac{1}{2}) 让梯度不带系数。提示约束里取 1 不是必须的取任意正数 C 都行最后解出来的超平面是一样的。取 1 只是让支持向量的函数间隔恰好等于 1推导和代码实现都更方便。到这里SVM 的优化问题就有了一个干净的骨架在保证所有样本函数间隔不小于 1 的前提下最小化 (|w|^2)。这是一类带不等式约束的凸优化问题。后面的拉格朗日对偶和 KKT 条件都是为了求解这个问题的工具。3. 拉格朗日对偶与 KKT 条件凸二次规划的求解路径3.1 二次规划原问题课件里给出了二次规划原问题的三种形式核心都是同一个目标加一组约束。这里采用适合 SVM 推导的写法[ \min_{w,b} \frac{1}{2}|w|^2 ][ \text{s.t.} \quad y_i(w^Tx_i b) \ge 1, \quad i 1, 2, \dots, m ]这是一个凸二次规划问题目标函数是二次的约束是线性的因此没有局部最优的困扰任何满足一阶最优性条件的解都是全局最优解。但直接用现成的 QP 求解器去解这个原问题在高维特征空间里效率很低而且无法引入核函数——核技巧要求目标函数和约束只以样本内积的形式出现。这正是需要转向拉格朗日对偶的根本原因。3.2 等式约束与不等式约束的拉格朗日处理课件先讲了等式约束的情形。目标函数是 (f(w))约束是 (h_j(w) 0)引入拉格朗日乘子 (\beta_j)构造拉格朗日函数 (L(w, \beta) f(w) \sum_{j}\beta_j h_j(w))然后对 (w) 和 (\beta) 分别求偏导并令其为零联立解出极值点。这在微积分里叫拉格朗日乘数法。不等式约束比等式约束复杂一层。把 SVM 的约束写成标准形式 (g_i(w) \le 0)也就是[ g_i(w) 1 - y_i(w^Tx_i b) \le 0 ]对每个约束引入拉格朗日乘子 (\alpha_i \ge 0)构造广义拉格朗日函数[ L(w, b, \alpha) \frac{1}{2}|w|^2 - \sum_{i1}^{m}\alpha_i \left[ y_i(w^Tx_i b) - 1 \right] ]课件里对 (L) 的定义是外层取 (\max_{\alpha} L) 再对 (w, b) 取 (\min)。这样处理的原因在于如果某个样本违反了约束即 (g_i(w) 0)那么令对应的 (\alpha_i \to \infty) 可以让整个式子趋于无穷大从而这个点不可能成为极小值点。反过来如果所有约束都满足那么 (\max_{\alpha} L) 恰好等于 (\frac{1}{2}|w|^2)。于是原问题就等价于[ \min_{w,b} \max_{\alpha} L(w, b, \alpha) ]满足 Slater 条件即存在严格可行的内点时强对偶成立可以把 (\min) 和 (\max) 交换顺序得到对偶问题[ \max_{\alpha} \min_{w,b} L(w, b, \alpha) ]3.3 对偶形式的推导过程先固定 (\alpha)对 (w) 和 (b) 求偏导。令 (\nabla_w L 0)[ w \sum_{i1}^{m}\alpha_i y_i x_i ]令 (\partial L / \partial b 0)[ \sum_{i1}^{m}\alpha_i y_i 0 ]把这两个结果代回拉格朗日函数 (L(w, b, \alpha))会看到三项化简得很干净(\frac{1}{2}|w|^2) 变成 (\frac{1}{2}\sum_{i,j}\alpha_i\alpha_j y_i y_j x_i^T x_j)中间交叉项是 (\sum_{i,j}\alpha_i\alpha_j y_i y_j x_i^T x_j) 带负号最后一项是 (-\sum_i\alpha_i)。合并后得到对偶问题[ \max_{\alpha} \sum_{i1}^{m}\alpha_i - \frac{1}{2}\sum_{i1}^{m}\sum_{j1}^{m}\alpha_i\alpha_j y_i y_j x_i^T x_j ]约束条件两个(\alpha_i \ge 0) 和 (\sum_{i1}^{m}\alpha_i y_i 0)。注意推导中一个容易被忽视的细节对偶目标函数里出现了样本内积 (x_i^T x_j)原问题里根本没有这个结构。这个内积形式就是核技巧的入口——把 (x_i^T x_j) 替换成某个核函数 (K(x_i, x_j))就能在完全不显式构造高维特征映射的情况下把 SVM 推广到非线性分类。关于这一点第 4 章对接核函数时会展开。求解出 (\alpha^) 之后利用 KKT 条件可以反推 (w^ \sum_i \alpha_i^* y_i x_i)再任取一个支持向量 (x_s)对应 (\alpha_s 0)由 (y_s(w^T x_s b) 1) 解出 (b^* y_s - \sum_i \alpha_i^* y_i x_i^T x_s)。3.4 KKT 条件与支持向量的对应关系课件里给出了 Karush-Kuhn-Tucker 条件的完整表述。对 SVM 这个具体问题KKT 条件包含三组核心关系[ \alpha_i \ge 0 ][ y_i(w^Tx_i b) - 1 \ge 0 ][ \alpha_i \left[ y_i(w^Tx_i b) - 1 \right] 0 ]最后一个式子叫互补松弛条件complementary slackness。它的含义是(\alpha_i) 和 (y_i(w^Tx_i b) - 1) 不可能同时非零。对于函数间隔大于 1 的样本约束不起作用必有 (\alpha_i 0)这些样本对最终解没有任何贡献只有函数间隔恰好等于 1 的样本即落在两条间隔边界上的点才会有 (\alpha_i 0)。这些点就是支持向量。课件第 18 页用一张图展示了这个结论实线是最大间隔超平面虚线上的点正例和负例各若干个就是支持向量其他远离边界的样本对应的 (\alpha_i) 全部为 0。这也是“支持向量机”这个名字的由来——最终分类器只依赖少数几个边界样本。在超平面附近数据密集的场景里这意味着训练完成后大部分训练样本可以直接丢弃预测阶段只保留支持向量即可。提示实际编程时由于浮点误差(\alpha_i) 不会精确等于 0。通常设置一个容差如 1e-5把小于容差的 (\alpha_i) 视为 0避免把噪声样本误判为支持向量。3.5 从对偶形式到决策函数的写法对偶问题解出 (\alpha^) 之后决策函数可以完全用 (\alpha^) 和训练样本的内积表示[ f(x) \text{sign}\left(\sum_{i1}^{m}\alpha_i^* y_i x_i^T x b^*\right) ]这个形式的价值在于预测一个新样本时只需要计算它与每个支持向量的内积而不是与全部训练样本的内积。当支持向量数量远小于训练集规模时推理成本会显著降低。这在文本分类、基因表达数据这类高维小样本场景里尤其明显。4. 核函数与软间隔优化从线性到非线性的跃迁4.1 为什么线性 SVM 不够用第 2、3 章推导的硬间隔分类器假设数据是线性可分的。但真实数据几乎都不是这样要么两类样本的分布区域互相渗透要么决策边界本身就是曲线或更复杂的形状。强行用线性超平面去分即使勉强分开间隔也会很小泛化能力很差。面对这种情况常见的思路是把原始特征映射到更高维的空间让数据在高维空间里变得线性可分。比如二维平面上一个圆形的正类区域映射到三维空间后可以用一个平面把它切出来。但直接做显式映射有两个问题一是高维空间的维度可能极高甚至无穷维显式计算特征向量不现实二是映射后的维度越高参数越多过拟合风险越大。核函数解决的就是第一个问题。4.2 核函数的本质内积的隐式替换核函数的思路是不显式定义映射 (\phi(x))而是直接定义一个二元函数 (K(x_i, x_j))使得 (K(x_i, x_j) \phi(x_i)^T \phi(x_j))。也就是说核函数在原始空间里计算的结果等于两个样本映射到高维空间后的内积。这样一来前面推导的对偶问题和决策函数里所有的 (x_i^T x_j) 都替换成 (K(x_i, x_j))完全不需要知道 (\phi) 长什么样。课件第 3 章标题列出核函数但没有展开具体形式。常见做法是直接选用几类成熟核函数这里给出各自的表达式和适用场景核函数表达式典型场景线性核(K(x_i, x_j) x_i^T x_j)特征维度高、样本量大的文本分类多项式核(K(x_i, x_j) (\gamma x_i^T x_j r)^d)图像分类中特征经过归一化时RBF 核(K(x_i, x_j) \exp(-\gamma |x_i - x_j|^2))默认首选适用面最广Sigmoid 核(K(x_i, x_j) \tanh(\gamma x_i^T x_j r))某些神经网络启发场景RBF 核是实际项目里用得最多的选择。它的作用范围由 (\gamma) 控制(\gamma) 越小每个训练样本的影响半径越大决策边界越平滑(\gamma) 越大边界越曲折越容易过拟合。选定核函数后SVM 的优化框架完全不用改动对偶问题的形式、KKT 条件、求解算法都照旧只是把内积换成核函数的值。这种“算法框架不变、只换内积定义”的扩展方式是核方法能在 SVM 之外广泛用于 PCA、岭回归等算法的重要原因。4.3 软间隔允许误分类的目标函数修正线性不可分还有另一种情况即便映射到高维空间数据里仍然存在噪声或 outliers强行找超平面会把边界扭曲得不成样子。这时引入软间隔soft margin的概念允许少量样本违反间隔约束同时在目标函数里对违反行为施加惩罚。课件标题里的“软间隔优化”对应的是在目标函数中引入松弛变量 (\xi_i \ge 0) 和惩罚参数 (C)[ \min_{w,b,\xi} \frac{1}{2}|w|^2 C\sum_{i1}^{m}\xi_i ][ \text{s.t.} \quad y_i(w^Tx_i b) \ge 1 - \xi_i, \quad \xi_i \ge 0 ]约束条件从原来的 (y_i(w^Tx_i b) \ge 1) 放宽到 (\ge 1 - \xi_i)。(\xi_i) 的取值含义是(0 \le \xi_i \le 1) 表示样本落在间隔边界和超平面之间仍然分类正确(\xi_i 1) 表示样本被误分类。目标函数里的 (C\sum\xi_i) 是对这些违规行为的惩罚。参数 (C) 的作用非常关键(C) 越大目标函数里后面一项的权重越高模型越不愿意容忍误分类间隔边界收窄过拟合风险上升(C) 越小误分类的代价越低间隔边界变宽欠拟合风险上升。在 scikit-learn 的 SVC 里C 默认值是 1.0实际调参时通常按 0.01、0.1、1、10、100 的对数尺度搜索。软间隔的对偶推导和硬间隔类似唯一的区别是拉格朗日乘子 (\alpha_i) 多了上界约束(0 \le \alpha_i \le C)。这个上界是软间隔带来的关键变化——它限制了单个样本对解的影响力避免某个 outlier 因为 (\alpha_i) 无限增大而主导整个超平面。KKT 条件也因此多了几种情况(\alpha_i 0) 对应远离边界的正确分类样本(0 \alpha_i C) 对应恰好落在间隔边界上的支持向量(\alpha_i C) 对应间隔内的样本或误分类样本。4.4 核函数与软间隔的组合效果把核技巧和软间隔放在一起就得到了实际项目里最常用的 SVM 形态使用 RBF 核的软间隔 SVM。这个模型有三个核心超参数(C)误分类惩罚、(\gamma)RBF 核的带宽、以及核函数本身的参数如多项式核的 degree 和 coef0。它们之间的交互是调参时的重点(C) 和 (\gamma) 同时很大模型自由度极高几乎完美拟合训练集但泛化能力差(C) 和 (\gamma) 同时很小模型过于简单决策边界接近线性欠拟合(C) 大但 (\gamma) 小边界平滑但几乎不允许误分类对线性可分数据效果好(C) 小但 (\gamma) 大允许大量误分类且边界复杂结果往往很差。这个组合的决策边界形态远超线性分类器的表达能力。RBF 核把每个训练样本都变成高斯函数的中心最终决策边界是高斯基函数的叠加理论上可以逼近任意形状的分类边界。5. 用 scikit-learn 复现 SVM参数含义与 Grid Search 实战5.1 最小可用代码RBF 核 SVM 的完整流程前面四章把 SVM 的原理拆完了现在落到代码。原版课件只讲数学推导不讲实现但“支持向量机 python 代码”是检索频率最高的需求。这里给出一个最小可用的完整示例覆盖训练、评估、决策边界可视化三个环节import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import make_moons from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC from sklearn.metrics import classification_report, accuracy_score # 生成非线性二分类数据 X, y make_moons(n_samples300, noise0.25, random_state42) # 划分训练集与测试集 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, stratifyy, random_state42 ) # 特征标准化SVM 对特征尺度敏感 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 使用 RBF 核的软间隔 SVM model SVC(kernelrbf, C1.0, gammascale, random_state42) model.fit(X_train_scaled, y_train) # 评估 y_pred model.predict(X_test_scaled) print(Test accuracy: {:.4f}.format(accuracy_score(y_test, y_pred))) print(classification_report(y_test, y_pred)) # 输出支持向量信息 print(Number of support vectors:, len(model.support_vectors_))这段代码有几个细节值得说明。StandardScaler这一步不是可选的RBF 核计算的是样本间的欧氏距离如果某个特征的量纲远大于其他特征距离计算会被它主导(\gamma) 的语义也会失衡。gammascale是 scikit-learn 的默认值等于 (1 / (\text{n_features} \times \text{X.var()}))它会根据输入数据的方差自动调整比自己硬编码一个值更稳。model.support_vectors_返回支持向量的坐标它的数量可以用来判断模型是否过拟合——如果支持向量的数量接近训练样本总数比如超过 80%说明决策边界被挤压得很厉害通常意味着 (\gamma) 过大或 (C) 过大。5.2 参数网格搜索找到 C 和 gamma 的合理组合RBF 核 SVM 的核心超参就两个C和gamma。我用GridSearchCV做一次简单的参数扫描这样可以看到不同的参数组合在验证集上的表现差异from sklearn.model_selection import GridSearchCV param_grid { C: [0.1, 1, 10, 100], gamma: [0.01, 0.1, 1, 10], } grid GridSearchCV( SVC(kernelrbf, random_state42), param_grid, cv5, scoringaccuracy, n_jobs-1, ) grid.fit(X_train_scaled, y_train) print(Best params:, grid.best_params_) print(Best CV score: {:.4f}.format(grid.best_score_)) # 用最优参数重新评估 best_model grid.best_estimator_ y_pred_best best_model.predict(X_test_scaled) print(Test accuracy with best params: {:.4f}.format(accuracy_score(y_test, y_pred_best)))GridSearchCV会穷举 (4 \times 4 16) 组参数组合每组都做 5 折交叉验证最终选出平均验证分数最高的一组。需要注意best_score_是交叉验证的平均分数它和测试集上的分数之间可能有一定差距——如果差距超过 2 到 3 个百分点说明模型对数据划分敏感需要检查数据是否存在泄漏或样本不均衡问题。5.3 代码对应的数学原理回顾现在把代码和前面的推导对应起来。model.fit()内部做的事情是求解第 4.3 节的对偶二次规划问题即最大化 (\sum_i\alpha_i - \frac{1}{2}\sum_{i,j}\alpha_i\alpha_j y_i y_j K(x_i, x_j))约束是 (0 \le \alpha_i \le C) 和 (\sum_i\alpha_i y_i 0)。求解器用的是 LIBSVM 的 SMO 算法通过每次优化两个 (\alpha_i) 来逼近全局最优解。decision_function方法输出的是 (\sum_{i}\alpha_i y_i K(x_i, x) b) 的值predict再对它取符号。model.support_属性记录的就是那些 (\alpha_i 0) 的样本索引它们在训练时已经通过 KKT 条件的互补松弛性质被识别出来了。如果训练完成后打印model.dual_coef_可以看到每个支持向量对应的 (\alpha_i y_i) 值——这个值是非零的而且直接参与预测时的加权求和。本文还有配套的精品资源点击获取
返回列表