ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

SMO算法解析:两变量闭式解推导与高效实现

SMO算法解析:两变量闭式解推导与高效实现 1. 从“暴力求解”到“分而治之”SMO算法为何而生如果你曾经亲手实现过支持向量机SVM尤其是在处理非线性可分问题、引入核函数之后大概率会在求解那个二次规划Quadratic Programming, QP问题时感到头疼。标准的SVM对偶问题其目标函数是求解一组拉格朗日乘子α它看起来很美但求解起来却很“重”。当你的训练样本数从几百上升到几千、几万时传统的通用QP求解器会变得异常缓慢甚至因为内存消耗过大而无法运行。这就像你要组装一个由数万个零件构成的精密仪器却要求你必须同时调整所有零件的位置才能找到最佳组合——这几乎是一个不可能完成的任务。SMOSequential Minimal Optimization序列最小最优化算法的提出正是为了解决这个“不可能”。它的核心思想极其巧妙既然同时优化所有变量太难那我就每次只优化两个变量把一个大问题分解成一系列极小的、可以解析求解的子问题。你可以把它想象成修理一块巨大的、复杂的电路板。你不需要也无法一次性地检测和修复所有故障点。相反你每次只聚焦于两个最可能出问题的焊点用万用表解析计算快速诊断并修复它们然后基于修复后的结果再寻找下一对需要处理的焊点。如此循环整个系统最终会收敛到稳定、最优的状态。SMO算法之所以高效其基石就在于这个“每次优化两个变量”的子问题存在闭式解解析解。这意味着我们不需要在子问题内部再进行耗时的迭代优化比如梯度下降而是可以直接通过一套公式计算出最优的更新值。这就像是解一个二元一次方程组只要系数确定解就能直接写出来。这个“闭式解”的存在性证明是整个SMO算法理论正确性和实用性的关键。没有它SMO就退化成了一个低效的坐标下降法每次迭代仍然需要调用一个小的优化器其速度优势将荡然无存。本文将深入这个最核心的“黑匣子”为你一步步拆解SMO算法中关于两变量优化子问题的解析求解过程及其证明。我们不会停留在“公式长这样照着用就行”的层面而是会像解开一个数学谜题一样探究为什么偏偏选两个变量为什么两个变量就能有解析解这个解是怎么推导出来的边界情况如何处理理解了这个证明你不仅能更自信地使用SVM库更能深刻理解这种“分而治之”的优化思想并将其应用到其他大规模优化问题中。2. 问题重述将SVM对偶问题“切片”要理解解析解我们必须先看清我们切下来的这片“切片”到底是什么。首先回顾一下软间隔SVM的标准对偶形式$$ \begin{aligned} \max_{\alpha} \quad W(\alpha) \sum_{i1}^{m} \alpha_i - \frac{1}{2} \sum_{i1}^{m}\sum_{j1}^{m} \alpha_i \alpha_j y_i y_j K(\mathbf{x}_i, \mathbf{x}j) \ \text{s.t.} \quad \sum{i1}^{m} \alpha_i y_i 0 \ 0 \le \alpha_i \le C, \quad i 1, \dots, m \end{aligned} $$其中( m ) 是样本数( \alpha_i ) 是拉格朗日乘子( y_i \in {-1, 1} ) 是样本标签( K(\mathbf{x}_i, \mathbf{x}_j) ) 是核函数( C ) 是惩罚参数。SMO算法每次选择两个乘子 ( \alpha_1 ) 和 ( \alpha_2 ) 进行优化固定其他所有 ( \alpha_i (i3,\dots,m) ) 不变。为什么是两个因为如果只选一个由于存在线性等式约束 ( \sum \alpha_i y_i 0 )当你改变一个 ( \alpha_i ) 时为了满足约束必须至少调整另一个 ( \alpha_j ) 来进行补偿。所以最小的优化集合就是两个变量。现在我们把目光聚焦在这两个变量上。假设我们选中的是 ( \alpha_1 ) 和 ( \alpha_2 )其他所有 ( \alpha_i ) 固定为常数。我们将对偶目标函数 ( W(\alpha) ) 中与 ( \alpha_1, \alpha_2 ) 相关的部分剥离出来。为了简化推导我们定义核函数值 ( K_{ij} K(\mathbf{x}_i, \mathbf{x}_j) )。将目标函数展开并分离出与 ( \alpha_1, \alpha_2 ) 相关的项 $$ W(\alpha) \alpha_1 \alpha_2 \sum_{i3}^{m} \alpha_i - \frac{1}{2} \Bigg[ \alpha_1^2 y_1^2 K_{11} \alpha_2^2 y_2^2 K_{22} 2\alpha_1\alpha_2 y_1 y_2 K_{12} 2\alpha_1 y_1 \sum_{i3}^{m} \alpha_i y_i K_{1i} 2\alpha_2 y_2 \sum_{i3}^{m} \alpha_i y_i K_{2i} \Bigg] \text{Constant} $$ 由于 ( y_i^2 1 )并且我们将与 ( \alpha_3, \dots, \alpha_m ) 自身相关的二次项和交叉项不涉及 ( \alpha_1, \alpha_2 )合并到常数项中得到 $$ W(\alpha_1, \alpha_2) \alpha_1 \alpha_2 - \frac{1}{2} \alpha_1^2 K_{11} - \frac{1}{2} \alpha_2^2 K_{22} - y_1 y_2 \alpha_1 \alpha_2 K_{12} - y_1 \alpha_1 v_1 - y_2 \alpha_2 v_2 \text{Constant} $$ 其中我们引入了两个关键的“常数”项因为对于当前子问题其他 ( \alpha_i ) 固定 $$ v_1 \sum_{i3}^{m} \alpha_i y_i K_{1i}, \quad v_2 \sum_{i3}^{m} \alpha_i y_i K_{2i} $$同时等式约束变为 $$ \alpha_1 y_1 \alpha_2 y_2 -\sum_{i3}^{m} \alpha_i y_i \triangleq \zeta $$ 这里 ( \zeta ) 是一个在当前子问题中固定的常数。此外还有边界约束 $$ 0 \le \alpha_1 \le C, \quad 0 \le \alpha_2 \le C $$于是原始的巨型QP问题被完美地“切片”成了一个仅关于 ( \alpha_1 ) 和 ( \alpha_2 ) 的、带有一个线性等式约束和边界约束的二元二次规划问题。我们的任务就是在这个“小盒子”里快速找到最优的 ( (\alpha_1^{\text{new}}, \alpha_2^{\text{new}}) )。注意这里的推导假设了 ( y_i^2 1 )并且忽略了与 ( \alpha_1, \alpha_2 ) 无关的常数项因为它们不影响优化结果。这个简化形式是后续解析推导的基础。3. 消元与化简将二元问题化为一元问题现在我们手握一个二元函数 ( W(\alpha_1, \alpha_2) ) 和一个线性等式约束 ( \alpha_1 y_1 \alpha_2 y_2 \zeta )。求解带约束优化问题的经典方法之一就是利用约束消元将问题转化为无约束的单变量优化问题。我们根据 ( y_1 ) 和 ( y_2 ) 的符号是否相同分两种情况讨论。这两种情况在几何上对应于约束直线不同的斜率但代数处理本质相同。情况一( y_1 \ne y_2 )此时 ( y_1 y_2 -1 )。由约束 ( \alpha_1 y_1 \alpha_2 y_2 \zeta ) 可得 $$ \alpha_1 y_1 \zeta - \alpha_2 y_2 \Rightarrow \alpha_1 y_1 (\zeta - \alpha_2 y_2) y_1 \zeta - \alpha_2 y_1 y_2 $$ 因为 ( y_1 y_2 -1 )所以 ( -y_1 y_2 1 )代入上式 $$ \alpha_1 y_1 \zeta \alpha_2 $$ 我们令 ( s y_1 y_2 -1 )并定义 ( k y_1 \zeta )则上式可写为 ( \alpha_1 \alpha_2 k )。由于 ( \alpha_1 ) 和 ( \alpha_2 ) 都被框在 ([0, C]) 的区间内这个关系意味着 ( \alpha_2 ) 的变化会导致 ( \alpha_1 ) 等量变化斜率为1。情况二( y_1 y_2 )此时 ( y_1 y_2 1 )。由约束 ( \alpha_1 y_1 \alpha_2 y_2 \zeta ) 可得因为 ( y_1 y_2 )不妨记为 ( y ) $$ y(\alpha_1 \alpha_2) \zeta \Rightarrow \alpha_1 \alpha_2 \zeta y \triangleq \gamma $$ 这里 ( \gamma ) 是一个常数。所以 ( \alpha_1 \gamma - \alpha_2 )。这意味着 ( \alpha_1 ) 和 ( \alpha_2 ) 的变化方向相反斜率为-1。我们可以用一个统一的表达式来概括。设 ( s y_1 y_2 )那么约束条件可以改写为 $$ \alpha_1 s \alpha_2 \text{constant} $$ 更精确地从 ( \alpha_1 y_1 \alpha_2 y_2 \zeta ) 出发两边乘以 ( y_1 ) $$ \alpha_1 (y_1 y_2) \alpha_2 \zeta y_1 $$ 即 $$ \alpha_1 s \alpha_2 \zeta y_1 \triangleq \gamma $$ 这里我们重新定义了常数 ( \gamma \zeta y_1 )。于是我们得到了一个简洁的线性关系 $$ \alpha_1 \gamma - s \alpha_2 $$将目标函数转化为关于 ( \alpha_2 ) 的一元二次函数接下来我们将 ( \alpha_1 \gamma - s \alpha_2 ) 代入到目标函数 ( W(\alpha_1, \alpha_2) ) 中。注意我们的目标是最大化 ( W )但为了求导方便我们通常考虑最小化其负值 ( -W )。由于最大化一个二次函数等价于最小化其负的二次函数开口方向改变而求极值点只关心导数零点所以我们可以直接对 ( W(\alpha_2) ) 求导。为了清晰我们展开代入过程。首先写出关于 ( \alpha_2 ) 的函数 $$ W(\alpha_2) (\gamma - s \alpha_2) \alpha_2 - \frac{1}{2} K_{11} (\gamma - s \alpha_2)^2 - \frac{1}{2} K_{22} \alpha_2^2 - s K_{12} (\gamma - s \alpha_2) \alpha_2 - y_1 v_1 (\gamma - s \alpha_2) - y_2 v_2 \alpha_2 \text{Constant} $$合并一次项( (\gamma - s \alpha_2) \alpha_2 \gamma (1 - s) \alpha_2 )。 展开二次项和交叉项( -\frac{1}{2} K_{11} (\gamma^2 - 2s\gamma \alpha_2 \alpha_2^2) ) 因为 ( s^2 1 )( - s K_{12} (\gamma \alpha_2 - s \alpha_2^2) -s\gamma K_{12} \alpha_2 K_{12} \alpha_2^2 ) 因为 ( -s \times -s 1 )将所有项按 ( \alpha_2 ) 的幂次重新整理常数项与 ( \alpha_2 ) 无关( \gamma - \frac{1}{2} K_{11} \gamma^2 - y_1 v_1 \gamma \text{Constant} )一次项( \alpha_2 ) 的系数 $$ (1-s) (K_{11} s \gamma) - (s \gamma K_{12}) - y_2 v_2 (s y_1 v_1) $$二次项( \alpha_2^2 ) 的系数 $$ -\frac{1}{2} K_{11} - \frac{1}{2} K_{22} K_{12} $$我们记二次项系数为 ( \eta ) $$ \eta K_{11} K_{22} - 2 K_{12} $$ 注意我们这里定义的是 ( -\frac{1}{2} \eta )因为整理后二次项是 ( -\frac{1}{2}(K_{11} K_{22} - 2K_{12}) \alpha_2^2 -\frac{1}{2} \eta \alpha_2^2 )。所以( W(\alpha_2) ) 是一个关于 ( \alpha_2 ) 的二次函数( W(\alpha_2) -\frac{1}{2} \eta \alpha_2^2 (\text{一次项系数}) \alpha_2 \text{常数} )。4. 求导与最优解解析解的诞生现在我们有了一个关于 ( \alpha_2 ) 的一元二次函数。为了找到其最大值因为原始目标是最大化 ( W )我们对其求导并令导数为零。由于二次项系数是 ( -\frac{1}{2} \eta )要使函数有最大值开口向下我们需要 ( \eta 0 )。幸运的是对于常用的核函数如线性核、多项式核、RBF核只要两个样本点不同( \eta ) 通常大于0。这源于核函数矩阵的正定性或半正定性。如果 ( \eta \le 0 \说明目标函数非凸此时需要特殊处理通常采取边界更新策略。我们首先讨论 ( \eta 0 ) 的正常情况。令导数 ( dW/d\alpha_2 0 ) $$ -\eta \alpha_2 (\text{一次项系数}) 0 $$为了得到清晰的最优解表达式我们引入SVM预测中的“误差”概念。定义第 ( i ) 个样本的预测值与真实值的误差为 $$ E_i f(\mathbf{x}i) - y_i \left( \sum{j1}^{m} \alpha_j y_j K(\mathbf{x}_i, \mathbf{x}_j) b \right) - y_i $$ 其中 ( f(\mathbf{x}_i) ) 是当前模型对样本 ( i ) 的预测值( b ) 是当前的偏置项。经过一系列繁琐但直接的代数运算将一次项系数用 ( E_i )、( y_i ) 和核函数值表示我们可以得到未经剪辑的、最优的 ( \alpha_2 ) 解析解 $$ \alpha_2^{\text{new, unc}} \alpha_2^{\text{old}} \frac{y_2 (E_1 - E_2)}{\eta} $$这个公式是SMO算法的心脏它极其直观地告诉了我们更新方向分子 ( y_2 (E_1 - E_2) )驱动更新的“力量”。( E_1 - E_2 ) 衡量了两个样本当前预测误差的差异。如果 ( E_1 ) 很大预测很错而 ( E_2 ) 很小预测很对那么 ( \alpha_2 ) 就需要一个大的调整来修正模型对样本1的预测。乘上 ( y_2 ) 确保了更新的符号正确。分母 ( \eta )可以理解为更新的“步长阻尼系数”。( \eta K_{11} K_{22} - 2K_{12} )在RBF核下它大致与两个样本点的距离平方成正比。样本越相似( K_{12} ) 越大( \eta ) 越小更新步长越大因为两者强相关调整一个对另一个影响大需要更大的步子样本差异越大( \eta ) 越大更新步长越小。实操心得在代码实现中计算 ( \eta ) 时需要注意数值稳定性。当两个样本完全相同时( \eta ) 可能接近零导致除零错误。因此通常需要判断if eta 0如果eta非正则放弃解析更新直接采用边界值更新策略。5. 剪辑到边界将理论解装入可行域的“盒子”上一步我们得到了无约束的最优解 ( \alpha_2^{\text{new, unc}} )。但它可能飞出了我们规定的“盒子”——即不满足边界约束 ( 0 \le \alpha_2 \le C ) 以及由等式约束衍生出的 ( \alpha_1 ) 的边界。因此我们必须将这个“自由解”剪辑Clip到其可行的区间内。可行区间由边界约束和线性等式约束共同决定。我们之前有 ( \alpha_1 \gamma - s \alpha_2 )且 ( 0 \le \alpha_1 \le C )( 0 \le \alpha_2 \le C )。这定义了一个二维空间中的平行四边形或线段可行域。我们需要找到 ( \alpha_2 ) 的可行上下界 ( L ) 和 ( H )。同样分两种情况情况一( y_1 \ne y_2 ) 即 ( s -1 )此时( \alpha_1 - \alpha_2 \gamma )。约束为( 0 \le \alpha_2 \le C )( 0 \le \alpha_1 \alpha_2 \gamma \le C \Rightarrow -\gamma \le \alpha_2 \le C - \gamma )综合这两个条件下界 ( L \max(0, -\gamma) )上界 ( H \min(C, C - \gamma) )。情况二( y_1 y_2 ) 即 ( s 1 )此时( \alpha_1 \alpha_2 \gamma )。约束为( 0 \le \alpha_2 \le C )( 0 \le \alpha_1 \gamma - \alpha_2 \le C \Rightarrow \gamma - C \le \alpha_2 \le \gamma )综合这两个条件下界 ( L \max(0, \gamma - C) )上界 ( H \min(C, \gamma) )。注意这里的 ( \gamma \alpha_1^{\text{old}} s \alpha_2^{\text{old}} )是一个已知的常数。得到 ( L ) 和 ( H ) 后剪辑操作就很简单了 $$ \alpha_2^{\text{new}} \begin{cases} H \text{if } \alpha_2^{\text{new, unc}} H \ \alpha_2^{\text{new, unc}} \text{if } L \le \alpha_2^{\text{new, unc}} \le H \ L \text{if } \alpha_2^{\text{new, unc}} L \end{cases} $$然后根据等式约束更新 ( \alpha_1 ) $$ \alpha_1^{\text{new}} \alpha_1^{\text{old}} s (\alpha_2^{\text{old}} - \alpha_2^{\text{new}}) $$ 这个公式直接来源于关系式 ( \alpha_1 s\alpha_2 \gamma \alpha_1^{\text{old}} s\alpha_2^{\text{old}} ) 的变形。6. 更新偏置与误差完成一次迭代的闭环更新完 ( \alpha_1 ) 和 ( \alpha_2 ) 后模型的决策函数 ( f(\mathbf{x}) \sum_i \alpha_i y_i K(\mathbf{x}_i, \mathbf{x}) b ) 发生了变化因此偏置项 ( b ) 和所有样本的误差 ( E_i ) 也需要更新以便为下一轮变量选择提供准确信息。更新偏置项 ( b )偏置 ( b ) 的更新需要利用KKT条件特别是那些位于支持向量边界( 0 \alpha_i C )的样本其预测值恰好等于标签函数间隔为1。我们通常根据新更新的 ( \alpha_1 ) 和 ( \alpha_2 ) 来计算新的 ( b )。如果 ( 0 \alpha_1^{\text{new}} C )说明 ( \mathbf{x}1 ) 是自由支持向量满足 ( y_1 f(\mathbf{x}1) 1 )。由此可解出 $$ b_1^{\text{new}} y_1 - \sum{i3}^{m} \alpha_i y_i K{1i} - \alpha_1^{\text{new}} y_1 K_{11} - \alpha_2^{\text{new}} y_2 K_{12} $$ 利用旧的误差 ( E_1 \sum_{j} \alpha_j^{\text{old}} y_j K_{1j} b^{\text{old}} - y_1 )上式可以简化为 $$ b_1^{\text{new}} b^{\text{old}} - E_1 - y_1 (\alpha_1^{\text{new}} - \alpha_1^{\text{old}})K_{11} - y_2 (\alpha_2^{\text{new}} - \alpha_2^{\text{old}})K_{12} $$如果 ( 0 \alpha_2^{\text{new}} C )同理利用 ( \mathbf{x}2 ) 可得 $$ b_2^{\text{new}} b^{\text{old}} - E_2 - y_1 (\alpha_1^{\text{new}} - \alpha_1^{\text{old}})K{12} - y_2 (\alpha_2^{\text{new}} - \alpha_2^{\text{old}})K_{22} $$如果两者都满足条件理论上 ( b_1^{\text{new}} ) 和 ( b_2^{\text{new}} ) 应该相等。但由于数值计算误差通常取它们的平均值。如果两者都不在 ( (0, C) ) 区间内即都在边界上那么 ( \alpha_1 ) 和 ( \alpha_2 ) 对应的样本都不再是严格的支持向量此时可行区间内所有的 ( b ) 都满足KKT条件。一个稳健的做法是取 ( b_1^{\text{new}} ) 和 ( b_2^{\text{new}} ) 的中点 $$ b^{\text{new}} \frac{b_1^{\text{new}} b_2^{\text{new}}}{2} $$更新误差 ( E_i )所有样本的误差 ( E_i ) 也需要更新以反映 ( \alpha_1, \alpha_2, b ) 的变化。最直接的方法是全部重新计算一遍但这在样本量大时开销巨大。一个高效的增量更新方法是 $$ E_i^{\text{new}} E_i^{\text{old}} (\alpha_1^{\text{new}} - \alpha_1^{\text{old}}) y_1 K_{1i} (\alpha_2^{\text{new}} - \alpha_2^{\text{old}}) y_2 K_{2i} (b^{\text{new}} - b^{\text{old}}) $$ 对于所有 ( i 1, \dots, m ) 都适用。这样我们只需要 ( O(m) ) 的复杂度主要是计算核函数值 ( K_{1i} ) 和 ( K_{2i} ) 的乘积而不是重新计算所有预测值所需的 ( O(m^2) ) 复杂度。踩坑实录在实现误差增量更新时一个常见的错误是忘记更新偏置项 ( b ) 带来的影响即漏加 ( (b^{\text{new}} - b^{\text{old}}) ) 这一项。这会导致误差累积最终影响变量选择的准确性甚至导致算法不收敛。务必确保更新公式的完整性。7. 变量选择策略与算法收敛性解析求解只是SMO迭代中的一步。另一个关键问题是下一次迭代我该选哪两个变量 ( \alpha_i ) 和 ( \alpha_j ) 选择的好坏直接决定了算法收敛的速度。第一变量外层循环的选择通常选择违反KKT条件最严重的样本对应的 ( \alpha_i )。KKT条件是SVM最优解的充要条件对于软间隔SVM其互补松弛条件可以转化为对每个样本 ( i ) 的检验如果 ( \alpha_i 0 )则要求 ( y_i f(\mathbf{x}_i) \ge 1 )。如果 ( 0 \alpha_i C )则要求 ( y_i f(\mathbf{x}_i) 1 )。如果 ( \alpha_i C )则要求 ( y_i f(\mathbf{x}_i) \le 1 )。由于数值精度我们通常设置一个容忍度 ( \tau )如 ( 10^{-3} )。违反上述条件的程度可以用 ( |y_i f(\mathbf{x}_i) - 1| ) 或更精确的度量来衡量。优先优化这些违反KKT条件的变量能最有效地向最优解推进。第二变量内层循环的选择目标是使目标函数值有最大的增长。从解析解公式 ( \alpha_2^{\text{new}} \alpha_2^{\text{old}} \frac{y_2 (E_1 - E_2)}{\eta} ) 可以看出我们希望 ( |E_1 - E_2| ) 尽可能大因为这样更新步长会更大。因此一个高效的启发式策略是选择那个使得 ( |E_1 - E_2| ) 最大的 ( \alpha_2 )。在实践中通常会维护一个全局的误差缓存 ( E_i )并在选择第二变量时遍历所有非边界( 0 \alpha_i C )的样本找到能使 ( |E_1 - E_j| ) 最大的 ( j )。如果这样选择不能带来足够的下降则扩大搜索范围到整个样本集。算法收敛性SMO算法可以看作一种特殊的坐标上升法。每次迭代都精确求解一个二维子问题的最优解并保证目标函数值严格增加除非已到达全局最优。由于目标函数有上界且每次迭代都带来确定的改进因此算法保证收敛。在实际中当所有变量都满足KKT条件在某个容忍度之内或者目标函数值的变化非常小时算法即可终止。8. 从理论到实现关键细节与性能调优理解了核心证明最终要落地到代码。这里有几个实现层面的关键细节直接关系到算法的正确性和效率。1. 核函数矩阵的缓存Kernel Cache计算 ( \eta K_{11} K_{22} - 2K_{12} ) 和更新误差 ( E_i ) 时需要频繁访问核函数值 ( K_{ij} )。核函数计算尤其是RBF核是SMO中最耗时的操作。一个标准的优化是维护一个核函数值的缓存。由于每次只更新两个变量受影响的误差项 ( E_i ) 的更新只依赖于 ( K_{1i} ) 和 ( K_{2i} )。因此可以预先计算并缓存所有样本与当前工作集比如违反KKT条件最严重的那些样本的核函数行。缓存策略如LRU能极大提升速度。2. 数值精度与特殊情况处理( \eta ) 非正如前所述如果 ( \eta \le 0 )目标函数在约束线段上非凸。此时不应使用解析解。常见的处理是直接计算目标函数在线段两个端点 ( L ) 和 ( H ) 处的值选择使目标函数更大的那个端点作为 ( \alpha_2^{\text{new}} )。更新量过小如果计算出的 ( \alpha_2^{\text{new}} ) 与 ( \alpha_2^{\text{old}} ) 的差异小于一个阈值如 ( 10^{-8} )可以跳过此次更新避免无意义的计算和误差更新。偏置 ( b ) 的更新当 ( \alpha_1^{\text{new}} ) 和 ( \alpha_2^{\text{new}} ) 都在边界时取 ( b_1 ) 和 ( b_2 ) 的平均值是一个稳定策略。有些实现会维护一个所有满足 ( 0 \alpha_i C ) 的支持向量计算出的 ( b ) 的平均值作为最终的偏置。3. 迭代终止条件除了KKT条件违反度另一个常用的终止条件是目标函数值的相对变化或对偶间隙Duality Gap。对偶间隙是原始问题目标函数值与对偶问题目标函数值之差当它足够小时可以认为接近最优解。但在SMO中精确计算对偶间隙成本较高更常用的是最大违反KKT条件的值。4. 与通用QP求解器的对比在实操中对于中小规模数据集样本数10k像libsvm、sklearn.svm.SVC中实现的SMO及其变种如使用二阶启发式选择工作集的速度远超通用QP求解器如cvxopt。其根本原因就在于SMO将计算复杂度从 ( O(m^3) ) 量级降到了近似 ( O(m^2) )并且通过缓存和启发式选择将常数因子降得很低。对于更大规模的数据则常采用基于梯度下降的算法如Pegasos或随机双坐标上升SDCA。我个人在实现和调优SMO时的体会是证明过程的严谨性保证了算法的正确性框架而实现细节上的优化缓存、启发式选择、数值处理则决定了算法在实际中的性能和鲁棒性。吃透解析解的推导能让你在调试代码时清楚地知道每一步计算的意义当出现异常结果比如不收敛、精度差时能快速定位到是变量选择、剪辑逻辑还是误差更新环节出了问题。这远比单纯调用一个svm.SVC().fit()的黑盒更能让你建立起对SVM模型深刻的、直觉性的理解。
返回列表