尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
手写SMO详解SVM:拉格朗日对偶、KKT与核函数
学支持向量机的时候很多人卡在“拉格朗日对偶法”这一关。我知道那种感觉——公式推导看得懂但总觉得缺一个“为什么”为什么要转成对偶问题KKT条件到底是来干嘛的为什么推导完突然就蹦出一个核函数说实话我当时第一次看教材从头到尾抄了一遍推导抄完了还是懵。直到后来自己动手从零实现了一遍SVM那些公式才真正连成一条线。这篇内容我就按一条我自己“终于懂了”的路径来写从SVM怎么变成一个带约束的优化问题到拉格朗日对偶法怎么给这个约束问题松绑再到KKT条件怎么把两个问题焊接起来最后落到手写一个简化版SMO算法在二维数据上真正看到支持向量长什么样。如果你是刚学SVM的入门者这篇能帮你把整条推导链打通如果你已经会用工具包这篇可以帮你把底层的数学直觉补齐。1. SVM的优化问题从“找一条线”到“解一个凸二次规划”1.1 最大间隔与函数间隔、几何间隔的关系SVM做的事情一句话说就是在两类样本之间找一条分割线高维里是超平面让这条线离两边最近的点都尽量远。这个“离最近的点尽量远”的距离就是间隔。间隔越大分类器对新样本的泛化能力通常越好这个说法不是经验玄学而是在结构风险最小化框架下有理论支撑的结论。这里有两个容易混的概念函数间隔和几何间隔。函数间隔对于样本((x_i,y_i))函数间隔定义为(\hat{\gamma}_i y_i(w^T x_i b))。注意这里(y_i)取(1)或(-1)所以只要分类正确且离边界越远值就越大。几何间隔是函数间隔除以(|w|)即(\gamma_i \frac{y_i(w^T x_i b)}{|w|})它的几何含义是样本点到超平面的真实距离。为什么要用几何间隔来做优化目标因为函数间隔有个致命问题你把(w)和(b)同时放大2倍超平面本身没变但函数间隔变成了原来的2倍。这是个虚的膨胀。几何间隔因为除以(|w|)把这个尺度伸缩抵消掉了只反映真实的几何距离。所以我们的目标是最大化几何间隔(\frac{1}{|w|} \min_i y_i(w^T x_i b))。这一步的关键在于最优化问题对尺度不敏感所以我们可以做一个非常聪明的归一化直接规定距离超平面最近的那些样本满足(y_i(w^T x_i b) 1)。为什么可以这么规定因为(w)和(b)同时缩放多少倍超平面都不变我们完全可以选定一个尺度让最近样本的函数间隔恰好为1。做完这个归一化最大化最小几何间隔(\frac{1}{|w|})就等价于最小化(\frac{1}{2}|w|^2)。于是SVM的原始问题变成一个标准的带约束优化问题[ \min_{w,b} \frac{1}{2}|w|^2 ][ \text{s.t.} \quad y_i(w^T x_i b) \ge 1, \quad i 1, ..., n ]这个形式非常重要。它说明SVM不是凭空冒出来的它的本质是一个带有不等式约束的凸二次规划。1.2 为什么这个优化问题是“凸”的凸有什么好处目标函数(\frac{1}{2}|w|^2)是关于(w)的二次函数而且Hessian矩阵是正定的就是单位矩阵的倍数所以它是严格凸函数。约束(y_i(w^T x_i b) \ge 1)是线性不等式线性不等式定义的可行域是凸集。凸优化最大的好处就是局部最优解就是全局最优解而且对偶间隙为零后面会讲到这意味着什么。在SVM之前你如果学过感知机你会发现感知机只要求找一个能把数据分开的超平面找到哪个算哪个解不唯一。而SVM因为有了“最大间隔”这个目标解是唯一的、稳定的这正是由凸性保证的。我当时学到这里有个小心得机器学习里凡是能写成凸优化的问题基本都是“有标准答案”的问题求解靠谱、理论完备。研究出SVM的人高明之处就是先把这个几何直观问题精准地描述成凸二次规划剩下的事情就可以交给最优化理论这个成熟工具箱了。1.3 为什么要转到对偶问题而非直接求原始问题到这里你可能会问这个原始问题直接用现成的二次规划求解器不就行了吗行小数据量时确实可以。但转到对偶问题有它不可替代的价值对偶问题的变量个数等于样本数(n)而不等于特征维度(d)。当特征维度很高的时候原始问题在高维空间里求优化不方便对偶形式反而更舒服。对偶问题暴露了“样本内积”这个结构核函数由此自然登场这是SVM最有杀伤力的武器。对偶形式里大部分(\alpha_i)会优化为0只有支持向量对应的(\alpha_i)非零。这个稀疏性既是计算上的优势也是SVM解释性的来源。所以接下来的主题就是这个看似抽象的数学工具——拉格朗日对偶法。2. 带约束极值拉格朗日乘子法是拉格朗日对偶法的地基2.1 先说最简单的等式约束下的拉格朗日乘子法再深入对偶之前先退一步看一个老朋友在等式约束下求极值。假设你要在曲线(g(x,y)0)上找(f(x,y))的最小值。教科书里的方法是构造[ L(x,y,\lambda) f(x,y) \lambda g(x,y) ]然后对(x)、(y)、(\lambda)分别求偏导等于0联立求解。怎么理解这件事的几何直觉在极值点目标函数的等高线和约束曲线必然相切也就是说目标函数的梯度(\nabla f)和约束函数的梯度(\nabla g)方向平行。(\lambda)就是那个把它们联系起来的比例系数。对(\lambda)求偏导等于0等价于把约束(g(x,y)0)给“请”了回来。这个视角很重要。拉格朗日乘子法不是某个天才凭空发明的公式它的本质就一句话在约束曲面上梯度方向被分解极值处目标梯度与约束梯度平行。2.2 不等式约束下的拉格朗日函数一个容易坑人的符号约定SVM的约束是不等式(y_i(w^T x_i b) - 1 \ge 0)不是等式。这种约束怎么处理思路是给每个不等式配一个拉格朗日乘子(\alpha_i \ge 0)把不等式“吸收”进目标函数。这里有一个决定后面所有推导方向的约定问题。我的写法采用国内教材里最常见的一种[ L(w,b,\alpha) \frac{1}{2}|w|^2 - \sum_{i1}^n \alpha_i \left( y_i(w^T x_i b) - 1 \right) ]其中要求(\alpha_i \ge 0)。这个减号怎么来的可以这样想在可行域内(y_i(w^T x_i b) - 1 \ge 0)恒成立。如果某个(\alpha_i)是负数那么(-\alpha_i(\cdots))这一项反而可能把目标函数往下拉导致优化走偏。所以约束(\alpha_i \ge 0)是我们构造拉格朗日函数时主动加的目的是让对偶问题给出一个有意义的、不越过可行域的优化。如果你去看其他资料会发现有人写成加法形式[ L(w,b,\alpha) \frac{1}{2}|w|^2 \sum_{i1}^n \alpha_i \left( 1 - y_i(w^T x_i b) \right) ]这两种写法本质一样只是(\alpha_i)的取值范围和后面推导的“对齐方向”不同。我自己学的时候在符号上栽过跟头看A教材推导到一半去查B教材发现求偏导的符号对不上整个推导就乱套了。所以我的建议是从头到尾选定一种约定跟到底不要混着看。2.3 min-max与max-min原始问题和对偶问题的关系有了拉格朗日函数下一步的操作是整个对偶法的核心结构。考虑这样一个量(\max_{\alpha \ge 0} L(w,b,\alpha))。对固定的(w,b)如果某个样本违反了约束即(y_i(w^T x_i b) 1)那么当(\alpha_i \to \infty)时(-\alpha_i(\cdots))会趋向(\infty)整个最大值就爆炸了。反过来如果所有样本都满足约束那么最大时应该让所有(\alpha_i)都取0。所以[ \max_{\alpha \ge 0} L(w,b,\alpha) \begin{cases} \frac{1}{2}|w|^2, \text{若所有约束都满足} \ \infty, \text{若有任一约束被违反} \end{cases} ]接下来再对(w,b)求最小就得到了原始问题的等价形式[ \min_{w,b} \max_{\alpha \ge 0} L(w,b,\alpha) ]这个形式表面上没什么用但它揭示了一个结构我们先是“拉格朗日化”把约束放进目标再通过(\max)把违反约束的情况用无穷大惩罚掉。现在把min和max交换一下顺序得到对偶问题[ \max_{\alpha \ge 0} \min_{w,b} L(w,b,\alpha) ]这个交换不是白换的。内层(\min_{w,b} L)没有约束可以直接求偏导解出闭式解代入后得到一个只关于(\alpha)的函数这就是对偶函数。为什么要费这个劲因为对偶问题往往更好解而且能带出支持向量和核函数。这里必须理清一个关键概念原始问题和对偶问题不是总相等的。我们解对偶问题本质上是解一个“原始问题的下界”。对偶问题的最优值一定小于等于原始问题的最优值这叫弱对偶。两者相等的情况叫强对偶。SVM恰好属于强对偶成立的场景这也是为什么我们敢放心去解对偶问题。3. 强对偶与KKT条件原始问题和对偶问题何时握手3.1 弱对偶恒成立强对偶需要Slater条件为什么说对偶问题的最优值(d^)永远不超过原始问题的最优值(p^)因为对任意(w,b)和(\alpha \ge 0)有[ \min_{w,b} L(w,b,\alpha) \le L(w,b,\alpha) ]对任意的(\alpha)取最大后依然满足[ \max_{\alpha \ge 0} \min_{w,b} L(w,b,\alpha) \le \min_{w,b} \max_{\alpha \ge 0} L(w,b,\alpha) ]这是一个恒成立的不等式关系不需要任何额外条件。真正的问题是什么时候等号成立对凸优化问题有一个很方便的充分条件叫Slater条件如果存在一个严格可行的点也就是说存在某个((w,b))让所有不等式约束都严格成立不是贴着边界那么强对偶成立。3.2 SVM为什么天然满足强对偶条件回到SVM的约束(y_i(w^T x_i b) \ge 1)。只要数据是严格线性可分的不存在恰好落在分界线上或重叠的点你总能稍微放大一下间隔找到一个让所有约束都严格大于1的超平面。这个“严格大于”就满足了Slater条件因此SVM的原始问题和对偶问题有相同的解。这就是为什么SVM的教科书推导都在解对偶问题却没有花大篇幅解释“为什么可以这样交换顺序”——因为对满足Slater条件的凸问题这个交换是合法的。理解了这一点你再回看那些跳过强对偶条件直接交换min-max的推导就知道作者默认了什么前提。其实完整地说即使数据不是严格线性可分的加了松弛变量后只要处理得当强对偶依然能成立。严谨性在真正的推导中当然重要但初学阶段你首先要建立“SVM能安全转对偶”的直觉。3.3 KKT四个条件逐一拆解当强对偶成立时原始问题的最优解和对偶问题的最优解必须满足KKT条件。KKT条件本质上是“极值点梯度为零约束可行性互补松弛”的组合。对SVM来说具体是四条梯度为零(\frac{\partial L}{\partial w} 0)(\frac{\partial L}{\partial b} 0)。这是无约束最优化的必要条件拉格朗日函数里的极值点必须满足。原始可行性(y_i(w^T x_i b) - 1 \ge 0)。这是SVM本身的约束不能丢。对偶可行性(\alpha_i \ge 0)。这是我们构造对偶问题时要求(\alpha_i)非负带来的条件。互补松弛(\alpha_i (y_i(w^T x_i b) - 1) 0)。这是最意味深长的一条。互补松弛说的是如果一个样本对应的(\alpha_i 0)那么它必须刚好在约束边界上也就是(y_i(w^T x_i b) 1)。反过来如果一个样本离边界有距离(y_i(w^T x_i b) 1)那它的(\alpha_i 0)。想想这是什么意思只有那些距离超平面最近、恰好挂在线上的样本才会在优化里留下非零的(\alpha_i)其他样本的(\alpha_i)全部归零。这些“恰好在线上的点”就是支持向量。所以KKT条件不只是一堆公式它是SVM“稀疏性”的理论来源——到最后模型只需要支持向量就能完全描述。我第一次真正被这个公式打动就是在自己写代码时打印出每个(\alpha_i)发现除了少数支持向量对应的(\alpha)非零其他全是数值上接近于0的小数。那个瞬间书上的互补松弛公式才在我脑子里立起来。4. 对偶形式推导w是怎么“消失”的核函数入口是怎么出现的4.1 对w和b求偏导等于0代入消元强对偶成立我们就可以放心求对偶问题。先把拉格朗日函数对(w)和(b)求偏导[ \frac{\partial L}{\partial w} w - \sum_{i1}^n \alpha_i y_i x_i 0 \quad \Rightarrow \quad w \sum_{i1}^n \alpha_i y_i x_i ][ \frac{\partial L}{\partial b} -\sum_{i1}^n \alpha_i y_i 0 \quad \Rightarrow \quad \sum_{i1}^n \alpha_i y_i 0 ]第一个式子揭示了最优(w)的形态它是所有样本的加权线性组合权重是(\alpha_i y_i)。这本身就是一个极简的观点——分隔超平面的法向量完全由训练数据张成。第二个式子则是一个藏在约束里的等式所有(\alpha_i y_i)加起来必须为0。这个约束在对偶问题中会一直跟着后面SMO算法每次更新都绕不开它。把这两个式子代回拉格朗日函数就能消掉(w)和(b)。我在推导时习惯一步步展开先看(\frac{1}{2}|w|^2)这一项代入(w \sum \alpha_i y_i x_i)后变成[ \frac{1}{2}\sum_{i1}^n \sum_{j1}^n \alpha_i \alpha_j y_i y_j (x_i^T x_j) ]再看(\sum_i \alpha_i y_i (w^T x_i b) - \sum_i \alpha_i)这一整块其中(\sum_i \alpha_i y_i w^T x_i \sum_i \sum_j \alpha_i \alpha_j y_i y_j (x_i^T x_j))而(\sum_i \alpha_i y_i b b \sum_i \alpha_i y_i 0)。所有的二次项合并后对偶目标函数变成[ \max_{\alpha} \sum_{i1}^n \alpha_i - \frac{1}{2}\sum_{i1}^n \sum_{j1}^n \alpha_i \alpha_j y_i y_j (x_i^T x_j) ]约束就两条[ \alpha_i \ge 0, \quad \sum_{i1}^n \alpha_i y_i 0 ]整个过程里(w)和(b)这两个原始变量完全消失了取而代之的是每个样本一个的(\alpha_i)。这就是拉格朗日对偶法在SVM里最直观的功劳。4.2 对偶问题的最终形态与KKT联立解释把这个对偶问题用矩阵形式写出来会更清楚一点。令(Q_{ij} y_i y_j x_i^T x_j)那么对偶问题变成[ \max_{\alpha} \quad \mathbf{1}^T \alpha - \frac{1}{2} \alpha^T Q \alpha ][ \text{s.t.} \quad \alpha \ge 0, \quad y^T \alpha 0 ]QF矩阵(Q)是半正定的因为可以写成(y * X)的外积形式所以这也是一个凸二次规划不过是关于(\alpha)的。用SMO算法可以高效求解。求解完(\alpha)之后原始问题的参数通过下面两个式子恢复[ w \sum_{i} \alpha_i y_i x_i ][ b y_j - w^T x_j \quad \text{对某个} \alpha_j 0 \text{的支持向量} ]结合KKT的互补松弛条件这里的一切都圆上了(\alpha_i 0)的样本就是支持向量它们挂在边界上给出(w)的表达式同时提供计算(b)所需的信息(\alpha_i 0)的样本对模型完全没贡献。4.3 内积一出现核函数的入口就打开了上面的推导出现了一个极其关键的形态目标函数里所有数据都以内积(x_i^T x_j)的形式出现决策函数也是。这意味着什么意味着我们根本不关心单个样本的长相只关心样本两两之间的内积。如果原始特征空间里样本不是线性可分的我们可以先把样本映射到一个更高维的空间(\phi(x))然后在高维空间里做线性SVM。这个操作放到对偶问题里唯一的改动就是把所有内积(x_i^T x_j)替换成高维内积(\phi(x_i)^T \phi(x_j))。核函数(K(x_i, x_j))正是用来规避“显式写高维映射”的只要这个函数能等价于某个高维空间中的内积我们就不需要真的去算(\phi(x))计算量还停留在低维。这就是著名的核技巧。对偶形式里内积作为唯一的数据交互形式是核技巧能成立的前提。如果你直接解原始问题特征映射写都写不出来更谈不上什么核技巧。所以核函数的出现不是SVM的发明而是对偶形式“自我暴露”出来的红利。学到这一层你才算真正明白为什么教材要坚持走拉格朗日对偶这条路。5. 训练完的模型参数怎么恢复从α到w和b5.1 w是支持向量的加权组合对偶问题解出来后模型参数(w)很简单[ w \sum_{i1}^n \alpha_i y_i x_i ]因为大多数(\alpha_i 0)本质求和只剩支持向量。所以(w)是支持向量的加权线性组合权重由(\alpha_i y_i)给出。这个式子我在实现的时候直接用了numpy的一行代码w np.sum(alpha * y * X, axis0)其中alpha、y、X都是numpy数组。注意这里必须用alpha乘y逐元素相乘得到一个与样本同维的权重向量列表再按样本维度求和。这个操作在数值上很稳定但要注意alpha里那些理论上应该是0的点实际会有极小的非零值比如(10^{-12})求和时不会造成明显误差但这给了我们一个判断支持向量的标准设一个小阈值比如alpha 1e-5的样本才算有效支持向量。5.2 b的求法一个容易出错的细节(b)的求法没有(w)那么直观很多初学者在这里踩坑。根据KKT互补松弛条件对于任意(\alpha_i 0)的支持向量有[ y_i(w^T x_i b) 1 ]两边乘(y_i)注意(y_i^2 1)得到[ b y_i - w^T x_i ]理论上用任意一个支持向量代入都能得到相同的(b)。但数值计算中有浮点误差实践中更稳的做法是取所有支持向量计算的平均值support_vectors np.where(alpha 1e-5)[0] b np.mean(y[support_vectors] - X[support_vectors].dot(w))我当时自己实现的时候第一版只用了一个支持向量求(b)结果每次运行结果在小数点后第三位有波动。改成所有支持向量平均之后稳定性立刻好了。这里我想强调一个容易被忽略的点取平均本身不是一个数学要求而是一个数值稳定性措施——KKT条件在数学上保证了每个支持向量给出的(b)相同但浮点运算下平均值更可靠。5.3 软间隔扩展对偶形式只多了一个C上界现实数据几乎都不是严格线性可分的允许部分样本犯错是常态。硬间隔SVM对噪声极其敏感一个离群点就能把整个决策边界拉偏。解决办法是引入松弛变量(\xi_i)允许第(i)个样本突破边界一段距离同时在目标函数里加惩罚项。原始问题变成[ \min_{w,b,\xi} \frac{1}{2}|w|^2 C \sum_{i1}^n \xi_i ][ \text{s.t.} \quad y_i(w^T x_i b) \ge 1 - \xi_i, \quad \xi_i \ge 0 ](C)是惩罚系数越大代表越不能容忍违反约束。神奇的事情来了重新走一遍拉格朗日对偶的推导最终的对偶问题几乎不变唯一的变化是约束从(\alpha_i \ge 0)变成了[ 0 \le \alpha_i \le C ]也就是说(C)给拉格朗日乘子加了一个上限。这个变化在SMO算法里就是一行裁剪逻辑但它带来的影响是本质的支持向量的权重不再像硬间隔那样无上限异常点不会获得过大的影响力模型的鲁棒性因此大大提升。我第一次实现的时候先用硬间隔跑了一个带噪声的数据集决策边界被一个孤立点拽得面目全非。然后把代码改成软间隔加了个裁剪操作边界立刻恢复了直觉上合理的位置那一刻我才真正理解(C)这个参数为什么是SVM最重要的旋钮之一。6. 手写一个简化版SMO从零实现线性与RBF支持向量机6.1 SMO的核心直觉为什么一次必须改两个α对偶问题有等式约束(\sum_i \alpha_i y_i 0)。如果每次只改一个(\alpha_i)这个约束很容易被打破。比如你改了(\alpha_1)剩下所有(\alpha)的和就必须反向变化才能维持等式成立但你又不能一次动“剩下所有”——这就很麻烦。SMO的思路是每次固定其他所有(\alpha)只优化两个(\alpha_i)和(\alpha_j)。因为只有两个变量时等式约束变成一个线性关系老(\alpha_i)和新(\alpha_j)之间存在线性替换关系可以把问题化成一元二次优化直接有闭式解。这就是SMO“每次选一对”的根本原因。所以SMO表面上的技巧是“坐标下降”里子其实是等式约束逼出来的“成对更新”。理解了这个动机你再看Platt那篇论文里的各种启发式选点规则才不觉得那是一个黑盒。6.2 α更新的核心式子和裁剪逻辑对于一对(\alpha_i, \alpha_j)更新公式可以写得很紧凑。定义误差[ E_i u_i - y_i ]其中(u_i \sum_j \alpha_j y_j K(x_j, x_i) b)是当前模型对样本(i)的预测值。再定义学习步长的分母[ \eta K(x_i, x_i) K(x_j, x_j) - 2K(x_i, x_j) ]则(\alpha_j)未经裁剪的更新值为[ \alpha_j^{new, unc} \alpha_j^{old} \frac{y_j (E_i - E_j)}{\eta} ]然后根据(y_i)和(y_j)是否相同以及(\alpha_i \alpha_j s)这个线性关系把(\alpha_j)裁剪到([L, H])区间内。简单起见我实现的版本里直接统一用(C)作为上下界[ \alpha_j^{new} \min(\max(\alpha_j^{new, unc}, 0), C) ]最后用等式约束反推(\alpha_i)[ \alpha_i^{new} \alpha_i^{old} y_i y_j (\alpha_j^{old} - \alpha_j^{new}) ]这一步是SMO里最容易写错的地方我当时调试了半天才发现是自己忘了乘(y_i y_j)。等式的推导细节是由(\sum \alpha_k y_k 0)改动前后(\alpha_i^{old} y_i \alpha_j^{old} y_j \alpha_i^{new} y_i \alpha_j^{new} y_j)解出来就是这个式子。更新完(\alpha)后还要更新(b)。标准的做法是根据更新后的(\alpha_i)和(\alpha_j)分别计算两个候选(b_1, b_2)如果(\alpha_i)在((0, C))内则取(b_1)如果(\alpha_j)在((0, C))内则取(b_2)否则取两者平均。这个逻辑同样源于KKT条件只有(0 \alpha C)的点才严格在边界上才有资格决定(b)。6.3 核心代码核函数、误差缓存、b更新我写的这个简化版SMO不追求工程效率主要为了把对偶形式跑通。核函数我实现了线性和RBF两种代码结构上把核矩阵预计算好这样SMO迭代时只查表不用反复算内积代码更清晰。import numpy as np def linear_kernel(X1, X2): return X1.dot(X2.T) def rbf_kernel(X1, X2, gamma0.5): sq1 np.sum(X1**2, axis1).reshape(-1, 1) sq2 np.sum(X2**2, axis1).reshape(1, -1) dist2 sq1 - 2 * X1.dot(X2.T) sq2 return np.exp(-gamma * dist2) def simple_smo(X, y, C1.0, kernellinear, max_iter100, tol1e-3): n X.shape[0] K linear_kernel(X, X) if kernel linear else rbf_kernel(X, X) alpha np.zeros(n) b 0.0 for it in range(max_iter): changed 0 for i in range(n): Ei (alpha * y).dot(K[i]) b - y[i] if (y[i] * Ei -tol and alpha[i] C) or (y[i] * Ei tol and alpha[i] 0): # 选一个j这里简化处理随机挑 j np.random.choice([k for k in range(n) if k ! i]) Ej (alpha * y).dot(K[j]) b - y[j] alpha_i_old, alpha_j_old alpha[i], alpha[j] eta K[i, i] K[j, j] - 2 * K[i, j] if eta 0: continue alpha[j] y[j] * (Ei - Ej) / eta # 裁剪 alpha[j] min(max(alpha[j], 0), C) alpha[i] y[i] * y[j] * (alpha_j_old - alpha[j]) # 更新b b1 b - Ei - y[i] * (alpha[i] - alpha_i_old) * K[i, i] - y[j] * (alpha[j] - alpha_j_old) * K[i, j] b2 b - Ej - y[i] * (alpha[i] - alpha_i_old) * K[i, j] - y[j] * (alpha[j] - alpha_j_old) * K[j, j] b (b1 b2) / 2 changed 1 if changed 0: break return alpha, b这段代码我建议初学者一行行对照公式看。有两个地方和完整SMO差别很大一是j的选取完全随机没有走启发式二是没有维护误差缓存E的全局副本每次现算。这两点都会让收敛变慢但逻辑简单、不容易写错适合用来理解原理。等跑通这个版本再看Platt原文里的选点策略就是锦上添花的事了。6.4 二维实验效果观察支持向量我用这个简化版SMO跑了一个二维模拟数据实验程序生成两类高斯分布的点每个类50个样本先跑线性核再跑RBF核然后把决策边界和支持向量画出来。关键的观察点有两个。第一线性核时决策边界就是一条直线落在边界线上的点恰好是那些(\alpha)大于阈值的支持向量数量远少于全部训练样本。第二换成RBF核之后决策边界变成一条弯曲的曲线原本线性不可分的数据被完整分开而且边界附近的支持向量依然清晰可见。从(\alpha)的数值分布看大量样本的(\alpha)都是0只有一小撮非零。这个实验让我彻底明白了一件事SVM的模型容量不是由样本总量决定的而是由支持向量决定的。这也是它在小样本、高维场景下特别能打的原因。7. 学习这条路的几个抗坑心得7.1 符号约定混乱是我见过最多的问题拉格朗日函数到底写成加法还是减法不同资料、不同课程习惯不同。这本身不是错误但它会连锁影响你对偶推导中的每个正负号。我的建议是选定一种约定把从拉格朗日函数到最终对偶形式的推导从头到尾完整写一遍中途不换教材。等你把一套推顺了再看其他写法就只是符号层面的转换而已。7.2 数值上与理论上的α千万不要拿微小值硬套理论上(\alpha_i)应该精确等于0的样本在数值计算中得到的往往是(10^{-12})这种极小值。如果你用alpha 0去筛支持向量会把几乎所有样本都筛进来决策边界就乱了。实践里设一个阈值比如1e-5小于阈值的直接按0处理。同样的道理也适用于判断KKT条件是否满足不要用严格等于要用容忍度。7.3 别急着上现成求解器先手推一遍再动手实现现在用现成的向量机工具包一行代码就能完成训练核函数随便换参数自动调。但我仍然强烈建议你至少手写一次SMO哪怕是最简化的版本。因为你在推导中踩过的每一个正负号错误、每一个裁剪边界问题都会让你对SVM的认知深一层。我自己的经验是手写完一个简化SMO之后再回头看书里的拉格朗日对偶推导公式之间突然就有了手感——它们不是一堆需要背的符号而是一条有来龙去脉的推理链。最后再分享一个小技巧。如果你在学对偶问题时感到抽象可以像我一样把整个推导拆成“原始问题→拉格朗日函数→对偶函数→KKT条件→SMO算法→参数恢复”六步每步用代码验证一个中间结果。数学公式的意义往往不是看出来的是跑出来的。等你亲眼看自己的程序正确分出了两类点那些公式才算真正长在了你的脑子里。
RELATED

相关推荐

宠物医院预约小程序课设源码:Java后端调用链路全解析

宠物医院预约小程序课设源码:Java后端调用链路全解析

简介:基于Java开发的宠物医院预约微信小程序完整源码与数据库文件,面向计算机相关专业的在校学生和教师。资源围绕宠物医院预约业务场景,包含完整代码与数据表脚本,适合作为课程设计、期末大作业或毕业设计的基础方案,…

📅 2026/10/22 19:50:15
基于规则与大模型混合的Issue智能分诊助手设计与实现

基于规则与大模型混合的Issue智能分诊助手设计与实现

1. 为什么需要给 Issue 做分诊 维护过开源项目的人都有一个共同感受:真正消耗精力的往往不是写代码,而是处理源源不断涌进来的 Issue。一个新 Issue 提交上来,里面可能混杂着 Bug 报告、功能请求、使用咨询、重复提问、甚至完全跑题的灌水内容…

📅 2026/10/22 19:50:15
LiteLLM投毒事件分析与应急防护:从排查到加固

LiteLLM投毒事件分析与应急防护:从排查到加固

1. 这起投毒事件到底是怎么回事先给还没搞清楚状况的朋友补个背景。LiteLLM 是现在做 AI 网关最常用的开源项目之一,很多团队拿它做统一入口,对接 OpenAI、Anthropic、各种国产模型以及自建的本地模型服务,转发请求、管 Token 配额、做预算控…

📅 2026/10/22 19:45:14
MORE NEWS

更多资讯

📰

C++抽卡模拟器

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

VideoChat-Flash-Qwen2_5-7B_InternVideo2-1B_rai_1.8.0_npu_16K部署FAQ:已知限制、MIT/TPN许可说明与从1.8.0升级的完整路线图

【免费下载链接】VideoChat-Flash-Qwen2_5-7B_InternVideo2-1B_rai_1.8.0_npu_16K 项目地址: https://ai.gitcode.com/hf_mirrors/amd/VideoChat-Flash-Qwen2_5-7B_InternVideo2-1B_rai_1.8.0_npu_16K 点击查看 免费下载 VideoChat-Flash-Qwen2_5-7B_InternVideo2-…

📰

Office 下载安装超详细保姆级教程(附安装包)【2026最新】

文章目录第一部分:了解Office 2021第二部分:Office 2021安装步骤详解第三部分:总结大家好!本文将分步骤介绍Office 2021的安装方法,这是一份详细的指南,旨在帮助大家顺利完成安装。Office是常用的办公软件&…

📰

c# web发布与IIS搭建合集教程(Win11):

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

【2025】RobotStudio 2024安装教程保姆级一键安装教程(附安装包)

文章目录RobotStudio下载RobotStudio 2024详细安装步骤安装前准备与解压启动RobotStudio安装程序安装向导操作自定义安装位置首次运行与许可设置RobotStudio常见问题与解决方案本教程为您带来RobotStudio 2024的保姆级一键安装指南。RobotStudio是瑞士ABB公司推出的机器人编程软…

📰

本地高精度测温与远程多区采集:嵌入式HVAC温度监测方案解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬