SVM 这份面试题,我前前后后被问过三轮,也面过别人。它几乎是算法岗面试里出现率最高的模型之一,但有意思的是,真正能从头到尾把 SVM 讲透的候选人并不多。大部分人能说出“最大化间隔”“核函数”“对偶”这几个词,再往下追问“间隔是怎么推导的”“为什么对偶之后就能用核技巧”“C 取大一点到底会发生什么”,就开始卡壳了。
这篇文章我不打算按教科书顺序把 SVM 的所有知识点罗列一遍,而是站在面试官的角度,把高频问题按一条主线串起来:从线性可分时的硬间隔,到对偶与支持向量,再到软间隔和核函数,最后是工程实现和对比题。每一部分我都会把“面试官为什么这么问”以及“怎么回答才算到位”讲清楚。适合备战算法岗面试的同学,也适合那些想系统梳理 SVM 知识、过去学得比较零散的人。
1. 面试官的第一问:最大化间隔凭什么成立
1.1 从“选哪条分界线”说起
面试官问 SVM,几乎一定从“什么是支持向量机”开始,或者更具体地问:“两类点线性可分,存在无数条分界线,SVM 选了哪一条,为什么?”
这个问题看似基础,其实是整个 SVM 的出发点。拿二维数据举例,两类点中间可以画无数条直线把它们分开,感知机会从其中挑一条可行的,至于哪一条,取决于初始化和样本顺序,并不唯一。SVM 的思路不同,它要在这些可行的直线里,找一条距离两类样本都尽量远的。
这里的“距离”不能随口说,要引出间隔(margin)的准确定义。SVM 定义的间隔,是决策边界到两侧最近样本点的最小距离之和。如果决策边界写成 ( \mathbf{w} \cdot \mathbf{x} + b = 0 ),那么某个样本点到这条线的几何距离是:
[ \frac{ |\mathbf{w} \cdot \mathbf{x}_i + b| }{ |\mathbf{w}| } ]
为什么叫几何间隔?因为 ( \mathbf{w} \cdot \mathbf{x} + b ) 本身可以被等比例缩放而不改变分界面,直接拿它的绝对值当距离是不行的,必须除以 ( |\mathbf{w}| ) 做归一化。这是第一个容易讲混的点:函数间隔和几何间隔的区别。函数间隔是 ( y_i(\mathbf{w} \cdot \mathbf{x}_i + b) ),几何间隔是函数间隔除以 ( |\mathbf{w}| )。
1.2 从约束到优化目标,面试官会怎么追问
为了推导方便,SVM 做了一个约定:对每个样本,约束 ( y_i(\mathbf{w} \cdot \mathbf{x}_i + b) \ge 1 )。为什么右边取 1 而不是别的数?因为同时缩放 ( \mathbf{w} ) 和 ( b ),分界面不变,所以可以固定最小函数间隔为 1,这就确定了 ( \frac{2}{|\mathbf{w}|} ) 作为总间隔。
面试追问到这里,重点就来了。目标是在约束下最大化 ( \frac{2}{|\mathbf{w}|} ),等价于最小化 ( \frac{1}{2} |\mathbf{w}|^2 )。有的人会问“为什么最小化 ( |\mathbf{w}| ) 不行,非要加个平方再乘二分之一”——为了求导方便,平方之后目标函数是光滑凸函数,梯度是一个整齐的 ( \mathbf{w} ),后面拉格朗日对偶求偏导也更干净。这个细节虽然小,但能看出你有没有真正动手推过。
硬间隔 SVM 的完整优化问题长这样:
[ \min_{\mathbf{w}, b} \frac{1}{2} |\mathbf{w}|^2 \quad \text{s.t.} \quad y_i(\mathbf{w} \cdot \mathbf{x}_i + b) \ge 1, \quad i = 1, \dots, n ]
到这里面试官一般还会补一句:“如果数据线性不可分怎么办?”这就是硬间隔的死穴,也是引出软间隔的入口。硬间隔要求所有样本都被正确分类且满足间隔约束,一旦数据有噪声或本身线性不可分,优化问题直接无解。所以后面才会引入松弛变量 ( \xi ),这个下面专门展开。
2. 对偶问题绕一圈,反而打开了核技巧的门
2.1 拉格朗日乘子法在原问题上的操作
面试官问“为什么要转化成对偶问题”的时候,千万别回答“为了求解更方便”。更准确的说法是:原问题本身是凸二次规划,直接解也能解,但对偶形式把优化目标变成了只依赖样本内积的表达式,这为核技巧铺了路。
具体操作不复杂。构造拉格朗日函数:
[ L(\mathbf{w}, b, \boldsymbol{\alpha}) = \frac{1}{2} |\mathbf{w}|^2 - \sum_{i=1}^{n} \alpha_i \left[ y_i(\mathbf{w} \cdot \mathbf{x}_i + b) - 1 \right], \quad \alpha_i \ge 0 ]
对 ( \mathbf{w} ) 和 ( b ) 分别求偏导并令其为零,得到两个关键等式:
[ \mathbf{w} = \sum_{i=1}^{n} \alpha_i y_i \mathbf{x}_i ]
[ \sum_{i=1}^{n} \alpha_i y_i = 0 ]
把这两个结果代回拉格朗日函数,就能消掉 ( \mathbf{w} ) 和 ( b ),得到对偶问题:
[ \max_{\boldsymbol{\alpha}} \sum_{i=1}^{n} \alpha_i - \frac{1}{2} \sum_{i=1}^{n} \sum_{j=1}^{n} \alpha_i \alpha_j y_i y_j (\mathbf{x}_i \cdot \mathbf{x}_j) ]
[\text{s.t.} \quad \alpha_i \ge 0, \quad \sum_{i=1}^{n} \alpha_i y_i = 0 ]
看到没,目标函数里样本只以内积形式出现。如果没有这一步,后面核技巧就没有落点。面试官说“原来如此,那核技巧是干嘛的”,你就可以顺势讲下去。
2.2 KKT 条件与支持向量:稀疏性从哪来
原问题和对偶问题之间有强对偶关系,前提是满足 KKT 条件。面试官喜欢问 KKT,因为这里藏着一个 SVM 最有意思的性质——稀疏性。
互补松弛条件长这样:
[ \alpha_i \left[ 1 - y_i (\mathbf{w} \cdot \mathbf{x}_i + b) \right] = 0 ]
拆开看,两种情况:
- 如果 ( \alpha_i > 0 ),那么必须 ( y_i (\mathbf{w} \cdot \mathbf{x}_i + b) = 1 ),样本落在间隔边界上。
- 如果 ( y_i (\mathbf{w} \cdot \mathbf{x}_i + b) > 1 ),样本在间隔边界内部甚至远离边界,那么 ( \alpha_i = 0 ),它对模型没有任何贡献。
换句话说,训练完成后,绝大部分样本的 ( \alpha_i ) 都是 0,只有落在边界上的少量样本留了下来。因为 ( \mathbf{w} = \sum \alpha_i y_i \mathbf{x}_i ),决策函数只由这些 ( \alpha_i > 0 ) 的样本决定,它们就是支持向量。这也是“支持向量机”名字的由来。
我面试的时候习惯让对方用手比划一下:给两个类别的点,哪些是支持向量,为什么只有它们决定了边界。能对着图说清楚“改变一个非支持向量的位置,分界线完全不动”,说明真的理解了。另外,偏置 ( b ) 的求解也是一个高频细节:取任意一个支持向量,代入 ( y_i(\mathbf{w} \cdot \mathbf{x}_i + b) = 1 ) 就能解出来。稳健一点的做法是对所有支持向量求平均,减少计算误差。
3. 线性不可分怎么办:软间隔与核函数
3.1 软间隔的引入和 C 的两面性
现实数据几乎不可能完美线性可分,强行用硬间隔不是过拟合就是无解。于是 SVM 引入了松弛变量 ( \xi_i ),允许个别样本突破间隔约束,甚至被分类错误。优化目标变成:
[ \min_{\mathbf{w}, b, \boldsymbol{\xi}} ; \frac{1}{2} |\mathbf{w}|^2 + C \sum_{i=1}^{n} \xi_i ]
[\text{s.t.} \quad y_i (\mathbf{w} \cdot \mathbf{x}_i + b) \ge 1 - \xi_i, \quad \xi_i \ge 0 ]
这里面试官必问一个参数:C 是干嘛的,取大和取小各会发生什么。C 是惩罚系数,表示你对误分类的容忍程度。C 越大,模型越不允许多犯错,会把精力放在把所有样本都分类正确上,决策边界会变得很复杂,容易过拟合;C 越小,模型对误分类的容忍度越高,边界更平滑,但可能欠拟合。
我做过一组对比实验,同样一份带噪声的数据,C 从 0.01 调到 100,决策边界从一条大直线变成贴着样本走的复杂曲线。C 没调好,用 RBF 核时尤其明显,边界会出现那种很诡异的“岛状”区域,看着就很不安全。
补充一个让人更容易记住的角度:软间隔可以看成合页损失(hinge loss)加正则项。合页损失 ( \max(0, 1 - y_i(\mathbf{w} \cdot \mathbf{x}_i + b)) ) 和 ( \xi_i ) 是等价的,所以 SVM 的目标也可以写成:
[ \min_{\mathbf{w}} ; \frac{1}{2} |\mathbf{w}|^2 + C \sum_{i=1}^{n} \max \left( 0, 1 - y_i(\mathbf{w} \cdot \mathbf{x}_i + b) \right) ]
这个形式在对比 SVM 和逻辑回归时非常好用,面试官一问“SVM 用的是什么损失函数”,能准确说出“合页损失”是加分项。
3.2 核技巧的本质:不显式映射,却等价于高维映射
回答“为什么引入核函数”这个问题,要分两层。
第一层:线性不可分的数据,换个高维空间可能就线性可分了。比如二维平面上的圆环分布,在二维里怎么画直线都分不开,但映射到三维,用 ( z = x_1^2 + x_2^2 ) 这个特征,就变成了一个点在 z 轴上的高低问题,一个平面就能切开。
第二层:直接做高维映射,计算量爆炸。尤其特征维度本来就不低的时候,显式计算 ( \phi(\mathbf{x}) ) 再算内积,成本太高。而核技巧直接用一个核函数 ( K(\mathbf{x}_i, \mathbf{x}_j) = \phi(\mathbf{x}_i) \cdot \phi(\mathbf{x}_j) ) 跳过显式映射,算出来的内积结果却和映射后一致。
对偶问题里的 ( \mathbf{x}_i \cdot \mathbf{x}_j ) 全部替换成 ( K(\mathbf{x}_i, \mathbf{x}_j) ),这就是核技巧的全部。面试官如果问“为什么对偶形式重要”,核心答案就是这一句:对偶后的目标函数只涉及样本内积,可以被核函数替代,从而实现低计算成本的隐式高维映射。
常用的核函数,我列了一个对比表:
| 核函数 | 表达式 | 特点 | 适用场景 |
|---|---|---|---|
| 线性核 | ( \mathbf{x}_i \cdot \mathbf{x}_j ) | 无超参数,训练快 | 文本分类、高维稀疏数据 |
| 多项式核 | ( (\gamma \mathbf{x}_i \cdot \mathbf{x}_j + r)^d ) | d 控制模型复杂度,容易过拟合 | 图像领域有先验时使用 |
| RBF 高斯核 | ( \exp(-\gamma |\mathbf{x}_i - \mathbf{x}_j|^2) ) | 最常选,能逼近任意非线性边界 | 通用默认选择 |
| Sigmoid 核 | ( \tanh(\gamma \mathbf{x}_i \cdot \mathbf{x}_j + r) ) | 类似神经网络,但需要满足正定条件才收敛 | 实践中较少用 |
RBF 核的两个要点必须掌握:
- 为什么 RBF 是默认选择:它只有一个 ( \gamma ) 参数要调,而且 RBF 的 ( \exp ) 形式对应无穷维的特征映射,表达能力强。
- ( \gamma ) 怎么理解:可以看成高斯分布的 ( \frac{1}{2\sigma^2} )。( \gamma ) 越大,高斯分布越尖,每个样本只影响周围很小一片,决策边界扭来扭去,容易过拟合;( \gamma ) 越小,影响范围越大,边界平滑容易欠拟合。
面试常见追问是“RBF 核的 ( \gamma ) 和 C 怎么配合”。我的经验是先从 ( C=1 )、( \gamma = 1/n ) 或 ( 1/\text{特征数} ) 这种默认值开始,再用交叉验证网格搜索,对数步长扫 C 和 γ。网格搜索的步长一般 ( C ) 取 ( 2^{-5} ) 到 ( 2^{15} ),γ 取 ( 2^{-15} ) 到 ( 2^3 ),覆盖范围尽量大,一轮下来基本能找到不错的组合。
4. 工程细节与面试遇到的坑:从标准化到多分类
4.1 为什么 SVM 对数据预处理那么敏感
SVM 的优化目标是基于距离的,特征之间的尺度差异会直接影响几何间隔的计算。如果一个特征是身高的数值(一两百),另一个特征是某个占比(0 到 1),前者会主导距离计算,导致模型几乎无视后者。所以 SVM 之前必须做标准化或归一化,尤其是用 RBF 核的时候,不标准化相当于给不同特征偷偷加了不同的权重。
面试里我遇到过这样一个问题:“SVM 能不能处理缺失值?”答案是不能。SVM 在计算核矩阵 ( K(\mathbf{x}_i, \mathbf{x}_j) ) 时需要完整的特征向量,缺失值无法参与距离计算。所以预处理阶段就要决定是删除缺失样本、用均值/中位数填充,还是用模型预测填充。这些细节看起来琐碎,但工程里真的很重要。
另一个相关的问题是“SVM 的时间复杂度”。标准二次规划求解是 ( O(n^2) ) 到 ( O(n^3) ) 级别,n 是样本数。所以 SVM 适合中小规模数据,十万级别的样本用默认的 SVC 就很吃力。工程上遇到大数据,要么用线性核配合高效求解器,要么换成逻辑回归或树模型。面试官问这个,看的是你有没有真实跑过大模型的训练,而不只是调过 sklearn 接口。
4.2 多分类:OvO 和 OvR 怎么选
SVM 天生是二分类器,多分类需要包装策略。两个主流方案:
- 一对一(OvO):每两类之间训练一个分类器,共 ( \frac{n(n-1)}{2} ) 个,投票决定最终类别。sklearn 的 SVC 默认用这种。
- 一对多(OvR / OvA):每个类别训练一个“是这个类还是其他所有类”的分类器,共 n 个,输出置信度最大的类别。
OvO 每个分类器只在一小部分数据上训练,单个训练快,但总分类器数量多;OvR 分类器数量少,但每个分类器面对的数据类别不平衡,多个分类器之间还可能存在决策边界重叠问题。实践经验是类别数量不大时 OvO 更稳,这也是 sklearn 选择它作为默认的原因。面试不会要求手推多分类公式,但能说清楚各自利弊就够用了。
4.3 SMO:不用手推,但要能讲清思路
面试官通常不会要求现场手写 SMO 的完整实现,但问“SVM 在大规模数据上是怎样求解的”时,你要知道 SMO(序列最小优化)的基本思想。
SMO 的核心是坐标下降的极端版本:一次只优化两个 ( \alpha ),固定其他所有 ( \alpha_i ),因为约束 ( \sum \alpha_i y_i = 0 ) 让所有 ( \alpha_i ) 不能随意单独变动,至少要同时动两个才能保持等式成立。每轮选两个“最违反 KKT 条件”的 ( \alpha ) 做更新,迭代到收敛。
可以顺着讲一下为什么选两个而不是一个:只更新单个变量会破坏约束,两变量更新时,一个变了,另一个能推导出解析解,不需要调用优化器。这个细节说出来,面试官会觉得你对优化过程是真的有了解。
4.4 概率输出和决策值
标准 SVM 输出的不是概率,是样本到决策边界的距离,也就是决策函数值 ( \mathbf{w} \cdot \mathbf{x} + b )。面试官问“怎么让 SVM 输出概率”,说的是 Platt 缩放:在训练好的 SVM 决策值上,再拟合一个逻辑回归模型,把决策值映射到 [0,1] 区间。sklearn 里probability=True就是干这个的,代价是训练后会额外做一次交叉验证来拟合参数。
需要知道的是,Platt 缩放得到的概率并不一定是校准得很好的概率,不同类别的先验不均匀时尤其不可靠。所以如果业务真的需要置信度排序,通常还是优先考虑逻辑回归这类天然概率模型。
5. 对比题和手撕题:这一关刷掉最多人
5.1 SVM 与逻辑回归的对比
面试到后期,对比题通常是区分“背过面经”和“真正理解模型”的分水岭。我用一个表总结高频对比:
| 对比维度 | SVM | 逻辑回归 |
|---|---|---|
| 损失函数 | 合页损失,关注间隔边界附近的样本 | 对数损失,所有样本都参与梯度更新 |
| 模型形式 | 决策函数是 ( \mathbf{w} \cdot \mathbf{x} + b ) | ( P(y=1 \mid x) ) 用 sigmoid 拟合概率 |
| 支持向量 | 只有支持向量影响模型,天然稀疏 | 所有样本共同决定参数 |
| 核技巧 | 内积替换核函数,隐式非线性 | 需要显式构造特征变换 |
| 输出 | 原始决策值,概率需额外校准 | 天然概率输出 |
| 适用规模 | 中小样本、高维特征效果好 | 大样本、在线学习更方便 |
| 对异常值 | 较鲁棒,只有支持向量敏感 | 异常值对梯度影响明显 |
回答的时候抓住核心思想:SVM 是最小化结构风险,追求间隔最大化;逻辑回归是最大化似然估计,追求对所有样本的整体拟合程度。一个“抓大放小”,一个“平均用力”。如果能把这句话自然地讲出来,整体印象就会很不错。
5.2 SVM 与感知机的对比
这个对比简单,但经常考。感知机是错误驱动的:每次遇到错分样本就更新权重,最终得到一个可行解,但不保证是最优解,而且解不唯一。SVM 在感知机的基础上,要求所有可行解里面间隔最大的那个,所以解是唯一的(线性可分前提下)。另外,感知机没有正则项,SVM 自带 ( |\mathbf{w}|^2 ) 的结构风险最小化。一句话总结:感知机给你一条线,SVM 给你一条“最稳”的线。
5.3 手撕题:两个点的最大间隔分界面
面试手撕 SVM 的经典例题非常固定,我给一个必会的版本。假设正类点 ( x_1 = (1, 1) ),负类点 ( x_2 = (-1, -1) ),求最大间隔分界面 ( \mathbf{w} \cdot \mathbf{x} + b = 0 )。
两个点关于原点对称,因此分界面一定过原点,( b = 0 )。约束是:
[ \mathbf{w} \cdot (1, 1) \ge 1 ]
[
- \left[ \mathbf{w} \cdot (-1, -1) \right] \ge 1 \quad \Rightarrow \quad \mathbf{w} \cdot (1, 1) \ge 1 ]
两个约束合并成一个:( w_1 + w_2 \ge 1 )。最大化间隔等价于最小化 ( w_1^2 + w_2^2 )。最优解在约束取等号时获得,因为如果 ( w_1 + w_2 > 1 ),还能同时缩小 w 的模长,间隔增大。
用拉格朗日法,构造:
[ L = w_1^2 + w_2^2 + \lambda (1 - w_1 - w_2) ]
对 ( w_1 )、( w_2 ) 求偏导:
[ 2w_1 - \lambda = 0, \quad 2w_2 - \lambda = 0 ]
所以 ( w_1 = w_2 ),代入 ( w_1 + w_2 = 1 ),得 ( w_1 = w_2 = 0.5 )。于是 ( \mathbf{w} = (0.5, 0.5) ),( b = 0 )。
最大间隔值:
[ \frac{2}{|\mathbf{w}|} = \frac{2}{\sqrt{0.5^2 + 0.5^2}} = \frac{2}{\sqrt{0.5}} \approx 2.83 ]
这几个数字要能当场算出来,不要犹豫。面试官一般还会接着问“哪些点是支持向量”,答案是两个点都在边界上,都是支持向量,边界直线分别是 ( 0.5x_1 + 0.5x_2 = 1 ) 和 ( 0.5x_1 + 0.5x_2 = -1 )。
5.4 面试问答速查表
把常见的面试追问浓缩成一张速查表,方便临考前过一遍:
| 问题 | 回答要点 |
|---|---|
| 什么是支持向量 | ( \alpha_i > 0 ) 且落在间隔边界上的样本,只靠它们决定模型 |
| 为什么最大化间隔 | 间隔越大,对训练样本的扰动越不敏感,泛化能力更强 |
| 为什么要引入对偶 | 对偶后目标只含内积,为核技巧铺路 |
| 核函数起什么作用 | 隐式完成高维映射,不显式计算 ( \phi(x) ) |
| 为什么 RBF 是默认核 | 表达能力覆盖线性核,只有一个 γ 参数 |
| 为什么必须做标准化 | SVM 基于距离计算,特征量纲不同会主导决策 |
| C 和 γ 怎么调 | 网格搜索 + 交叉验证,对数步长扫参 |
| 训练完成后的模型大小 | 只保留支持向量、对应 ( \alpha ) 和 ( b ) |
| SVM 处理大规模数据 | 求解复杂度高,大数据优先线性核或换模型 |
写在最后,说点面经之外的话
刷完这些题之后,我还想提醒一句:面试考 SVM 的重点不是让你背结论,而是看你有没有独立推导过。我自己的做法是把硬间隔的拉格朗日对偶从头到尾在纸上推了至少三遍,第一遍看公式,第二遍关掉资料自己推,第三遍边推边给自己讲解。真正推过之后,很多点会突然连成线:为什么 ( \mathbf{w} = \sum \alpha_i y_i \mathbf{x}_i )、为什么支持向量稀疏、为什么核技巧能嵌入到对偶问题里,全部是一个逻辑链条上的产物。
如果你准备时间有限,优先保证两件事:一是能完整写出硬间隔的拉格朗日对偶推导,二是能把手撕题那两个点的例子流畅算完。这两件事过了,SVM 这关基本就守住了。后面再往软间隔、核函数、SMO、工程细节这些方向延展,压力会小很多。