ARTICLE DETAIL

资讯详情

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

从SVM到核方法:核函数的本质、原理与工程实践指南

从SVM到核方法:核函数的本质、原理与工程实践指南 很多人第一次接触机器学习里的“核函数”这个词是在看SVM支持向量机资料的时候。当时我也一样看着“低维线性不可分映射到高维就线性可分了”这句话觉得道理好像懂了但真要问一句“核函数到底是什么”又说不清楚。后来自己手推公式、手写代码、调参踩坑才慢慢摸清楚这套东西的底细。这篇博文就从一个比较本质的角度把核函数的原理从头到尾拆一遍不绕弯子尽量把“为什么”讲透同时把实际使用中容易被忽视的坑也一并点出来。1. 低维空间里的无解困局为什么非要往高维走1.1 从一条直线搞不定的分类问题说起先抛一个最经典的例子二维平面里有两类点一类分布在圆心附近一类分布在外圈环带上就像射箭的靶子内环和外环。你手里只有一条直线也就是一个线性分类器任凭你怎么旋转、平移这条线都不可能把内环和外环完整分开因为这两类点在原始二维空间里本身就是“非线性可分”的。这个例子很多人书上见过但没细想过它背后的几何含义。线性分类器的决策边界是超平面在二维空间里就是一条直线它的表达能力极其有限只能切出“半边”区域。而真实数据里的类别分布往往是嵌套的、月牙形的、螺旋形的这些都是单条直线搞不定的形状。那怎么办一个很自然的想法是既然二维空间里的直线不够用那就把数据搬到三维、四维甚至更高维的空间里在高维空间里找一个超平面来切。为什么高维空间里就有办法了因为维度越高几何自由度越大原本纠缠在一起的数据在高维视角下可能就“撑开”了。还是拿靶心数据举例如果把每个点的坐标从(x1, x2)变成(x1², x2²)内环和外环在(x1², x2²)这个新空间里拉开的距离就很明显这时候一条直线就能分开它们。1.2 高维映射直观做法与致命代价沿着上面的思路最朴素的做法是先定义一个显式的映射函数φ(x)把每个原始样本点都变换成高维空间里的新向量然后在高维空间里套用线性算法。理论上这是可行的但代价极其高昂甚至往往是不可接受的。举个具体的数字感受一下。假设原始特征是100维你想把特征扩充到包含所有的二阶交叉项也就是xi·xj这种组合。二阶交叉项的个数是多少是C(1002-1, 2)约等于5050个维度。如果原始特征1000维二阶交叉项就约有50万个维度。这还没算三阶、四阶交叉项。每一个样本点都要做一次这样庞大的显式映射不仅内存装不下计算量也是天文数字。更致命的问题在于内积。很多线性算法比如SVM、线性回归、PCA在求解过程中真正需要的数据并不总是原始特征本身而是样本两两之间的内积xi, xj。如果先做高维映射再算内积那得先把两个样本都映射成巨大的高维向量再做一个超大向量的点积运算计算成本和存储成本直接爆炸。也就是说“先映射再内积”这条路理论上成立实操上走不通。核函数之所以能成为经典就是因为它把这条路彻底打通了不映射也能算高维空间里的内积。2. 核技巧的本质不映射也能算内积2.1 替换的关键一步核函数的形式定义非常简单k(x, y) φ(x), φ(y)。这个式子说的是核函数接受两个低维原始空间的样本点返回值直接等于它们各自经过某个映射φ之后在高维空间里的内积。关键在于这个返回值可以直接在低维空间里算出来根本不需要真把φ(x)和φ(y)求出来。我拿一个最常用的例子来演示大家就明白了。定义一个映射φ把二维向量x (x1, x2)映射成三维φ(x) (x1², x2², √2·x1·x2)。注意中间带根号2的第三维这不是随手写的是为了让后面的展开“恰好对得上”。现在任取两个点a (a1, a2)和b (b1, b2)在三维空间做内积φ(a), φ(b) a1²b1² a2²b2² 2a1a2b1b2眼尖的读者已经发现了这个式子完全等于(a1b1 a2b2)²也就是a, b²。换句话说直接对原始二维向量的内积做个平方就能得到三维映射空间里的内积结果。而(a1b1 a2b2)²这个计算只需要4次乘法和几次加法比先展开三维向量再做点积要省得多。如果原始维度再高一些这个差距是指数级的。这就是核技巧的精髓把“映射”变成“运算法则”用低维空间里一个便宜的计算等价地替换掉高维空间里一个昂贵的内积操作。你不需要知道φ长什么样只需要知道“存在一个和这个核函数对应的映射空间”就可以在低维空间里安全地使用高维空间的几何性质。2.2 什么样的函数才算合法核函数不是随便拿一个二元函数k(x, y)就能当核函数用。既然核函数的本质是“高维空间里的内积”那它必须保证任何有限个样本点构成的核矩阵都是半正定的。核矩阵的定义是K其中Kij k(xi, xj)。半正定是什么意思简单说就是对于任意非零实向量c都有cᵀKc ≥ 0。这个条件对应到Mercer定理一个连续对称函数k(x, y)能写成内积形式φ(x), φ(y)的充要条件就是它对任意有限样本集生成的核矩阵半正定。这个定理给了我们一把尺子用来检验某个函数能否合法当核函数用。可能有人会问半正定这个条件到底在实际中有什么影响我举一个反例。有人可能灵机一动想用k(x, y) tanh(a·x, y b)这种Sigmoid形式觉得神经网络也是这么干的应该没问题。但Sigmoid核并不是对所有参数组合都半正定只有当参数取到特定区间时才合法而那个区间常常很窄。如果你没检查正定性就直接套进SVM里求解器可能会出现不收敛、结果震荡等怪异现象。后面讲常见核函数选型时我会再提到这一点。另一个容易犯的错是把所有长得像“距离度量”的函数都当成核函数。比如k(x, y) 1 - ||x - y||²直觉上它有点像相似度但这么一写大距离样本的核值反而变成负数对应的核矩阵大概率不半正定这种函数就不能用。2.3 核矩阵核方法一切操作的中枢讲到核矩阵多说几句。很多初学朋友会把注意力全放在核函数表达式上却忽略了核矩阵才是所有核方法真正操作的对象。核矩阵是一个n×n的对称矩阵n是样本数。Kij表示第i个样本和第j个样本在高维空间里的内积它其实编码了整个数据集在高维空间中的几何结构信息。为什么核方法能够把各种线性算法都“核化”关键就在于很多线性算法的目标函数里样本都是以内积形式出现的。把内积替换成核函数算法就自动在隐含的高维空间里运行了。比如线性回归的解里包含XᵀX和Xᵀy全部替换成核矩阵及相关项就得到了核岭回归PCA的特征分解里包含协方差矩阵替换成核矩阵就得到了核PCA。这个过程在图论里也有个很漂亮的类比核矩阵就像是数据集的“路网信息表”矩阵元素是两点之间的“亲和度”或“相似度”而算法则是在这张表上“导航”。你根本不需要真的驾车上路显式映射只需要查表核矩阵就能知道任意两点的远近关系足以完成分类、回归、聚类等任务。理解到这层后面看任何核方法论文都会轻松很多因为你已经知道这类工作本质上都是“选定一个线性算法 定义一个合法核函数 完成核矩阵替换”。3. 常用核函数的“性格”差异与选型依据3.1 线性核不是最炫但永远值得首选线性核k(x, y) x, y说白了就是不做任何映射直接在原始特征空间里计算内积。很多初学者觉得线性核“不算核函数”这是误解。它不仅是合法的核函数而且往往是应该最先尝试的选项。为什么因为线性核对应一个线性决策边界泛化能力往往更强训练速度最快模型的可解释性也最好。你不仅知道分类结果还能直接拿到每个特征的权重系数知道哪些特征在起主要作用。我自己的经验是先用线性核跑一遍基线如果测试集准确率已经能上90%那你可能需要好好掂量一下是不是真要上高斯核。核方法虽然强大但过度复杂的核函数容易带来过拟合尤其是在样本量不大的时候。线性核作为首选项意义是帮你校准对任务难度的预期。工业界里有个朴素的现实特征工程做得好很多非线性模式都能被线性模型捕捉。像文本分类里TF-IDF之后的高维稀疏特征线性核SVM往往表现一点也不差而且训练速度、内存占用都远优于非线性核。3.2 多项式核显式刻画特征交互多项式核k(x, y) (x, y c)^d其中d是多项式次数c是偏置系数。这个核对应的是包含原始特征以及直到d阶所有交叉项的映射空间。前面的平方核例子就是d2、c0的特殊情况。多项式核的“性格”比较直白次数d直接控制模型复杂度。d1时退化为线性核d2能捕捉两两特征交互d越大能刻画的交互越复杂但参数量和过拟合风险也急剧上升。在图像分类里如果直接用原始的像素值向量用二次多项式核往往就能得到还不错的基线效果因为像素之间的二阶组合确实能捕捉到一些局部结构与纹理信息。多项式核有个不太舒服的地方数值稳定性。当d比较大、x, y的绝对值大于1时(·)^d会迅速爆炸反之若内积小于1又可能迅速衰减到0。所以使用多项式核之前特征缩放是强制性的我建议一定要做标准化或归一化。另外d超过4以后训练过程基本都会变得不稳定一般不推荐往更高的次数走。3.3 高斯RBF核最通用的默认选项高斯径向基核也就是RBF核公式是k(x, y) exp(-γ·||x - y||²)。它对应的映射空间是无限维的因为它的泰勒展开包罗了所有阶次的多项式特征。这也是它表达能力特别强的原因总能在高维空间里找到能把数据“撑开”的方式。RBF核还有一个绝妙的直觉解释它衡量的是两个样本在原始空间里的距离的指数衰减函数距离越近核值越接近1距离越远核值趋向0。这意味着它天然是一个“相似度度量”把样本映射到一个“以自身为中心的放射性函数”构成的特征空间里。一个人可以不懂内积、不懂映射但只要能理解“距离越近越相似”就能大致把握RBF核的行为模式。参数γgamma是RBF核唯一的超参数控制高斯函数的“腰围”。γ小的时候高斯峰宽每个样本的影响范围大决策边界平滑γ大的时候高斯峰窄每个样本只影响很小一块局部区域决策边界扭曲、尖锐很容易把训练集每个点都包进来造成过拟合。实际使用时γ和SVM的惩罚参数C必须联合调不能在真空中单独调某一个。我常用指数网格搜索γ取2的幂次方序列比如2^-15到2^3C类似地从2^-5到2^15。为什么用指数网格因为这两个参数的变化对模型影响是指数级的线性等距网格会漏掉关键值效率太低。交叉验证之后再看热力图往往能看到一条明显的“好参数脊线”也就是C和γ同时等比增大或减小时模型都表现不错因为两者之间存在配合关系。3.4 自定义核函数的正定性陷阱除了常见核很多人会遇到需要自定义核的场景特别是做结构化数据、图数据或者特定的领域相似度的时候。这是一个很深的坑我在这里先提个醒。我见过不止一个朋友自己设计了一个相似度函数看两个样本的匹配程度、重叠率写出来很有道理但丢进SVM里效果就是一坨屎怎么调都不行。排查下来核矩阵特征值出现负数也就是说这函数根本不半正定不满足Mercer定理算法的最优解理论保证都没了怎么可能正常工作。如果一定要自定义核函数我有一个建议设计完函数之后先用一小批样本比如几百个算出核矩阵用数值方法检查特征值是否全部非负。如果不满足可以尝试两种修复思路。一种是往对角线加一个小的正数ε也就是K εI相当于给每个样本施加一个小的自相似度惩罚这在一些正则化框架下能把特征值“抬”成正的。另一种是直接改用经过验证的核组合比如直接用RBF核作用在你自己提取的特征上这个往往比设计一个“花哨但不合法”的相似度函数省心很多。4. 从SVM到整个核方法家族核函数的真正用武之地4.1 核岭回归和SVR回归任务同样受益很多人把核函数和SVM绑在一起以为核函数只用于分类。实际上核技巧是通用的任何能写成内积形式的线性算法都能“核化”回归就是其中一大类。核岭回归Kernel Ridge Regression, KRR是其中最简单的例子。线性岭回归的解是w (XᵀX λI)⁻¹Xᵀy这里面XᵀX是一个内积矩阵Xᵀy也是样本与标签的内积。一旦把这些内积替换为核矩阵K以及核函数与标签的对应项就得到了核岭回归。它的好处是既有非线性拟合能力又保留岭回归的解析解不需要迭代优化稳定可靠。在实操中我经常拿核岭回归当SVM的高效替代品来用。当训练样本量在几万以内时KRR的训练速度往往比SVM快不少因为SVM需要解一个二次规划问题而KRR只需要解一个线性方程组。当然KRR的缺点是解是稠密的每个训练样本都是“支持向量”预测时要把测试样本和所有训练样本的核值都算一遍推理成本比稀疏的SVM高。如果你的在线服务对推理延迟非常敏感这一点必须提前想清楚。SVR支持向量回归则是SVM思路在回归上的延伸通过引入ε不敏感损失只让落在误差带之外的样本成为支持向量从而保持解的稀疏性。在选择KRR还是SVR时我的经验是样本量不大、追求稳定可靠选KRR样本量中等、对推理速度有要求选SVR样本量很大则要考虑下一节讲的计算优化方案。4.2 高斯过程与核PCA当核函数成为概率和降维的工具高斯过程回归Gaussian Process, GP是另一个核方法的代表性应用。GP的基本假设是函数值服从一个联合高斯分布而核函数在这里扮演的是协方差函数的角色描述任意两个输入点对应的函数值之间的相关性。你完全可以把GP理解成“用数据不断更新对函数分布认知”的贝叶斯方法先验由核函数定义观测数据更新后验预测时给出均值与方差。GP拥有一个SVM没有的“隐藏福利”它不仅输出预测值还输出不确定性。这在自动超参数调优、贝叶斯优化中特别实用比如在你想要决定下一步探索哪个参数组合的时候GP的不确定性估计会告诉你哪里“信息量最大”。代价是训练复杂度为O(n³)样本量一旦上万就很吃力需要用稀疏近似方法。再看核PCAKernel PCA。普通PCA是找原始空间中方差最大的方向核PCA则是在核函数隐含的高维特征空间里找主成分方向。说人话就是它能捕捉到原始空间里的非线性结构流形把人脸光照变化、手写数字的旋转变化等在低维线性PCA下处理不好的模式用少数几个核主成分就描述出来。常见做法是先算核矩阵K然后中心化K减去行均值、列均值和总体均值再对中心化后的核矩阵做特征分解。核PCA有个坑因为核矩阵的维度是样本数不是特征数所以它学到的“主成分”维度最多是样本数而且新样本投影需要依赖所有训练样本做核值计算。这也导致核PCA在大样本场景下并不像mini-batch版本的PCA那样可以增量式训练部署时得存下全部训练数据这是不少项目上线时才发现的麻烦事。4.3 核方法在领域适配与其他任务里的打开方式核函数还有一个让我觉得特别有意思的应用方向是迁移学习和领域适配。经典方法MMDMaximum Mean Discrepancy最大均值差异就是基于核函数的。它的核心思想是如果两个分布P和Q足够相似那么对于任意核函数k分布P下的样本核均值与分布Q下的样本核均值之差应该很小。MMD的计算公式里全是核值不需要任何显式密度估计直接拿样本就能算所以特别受实践者欢迎。用一个具体场景来理解MMD你有大量带标签的“源域”数据比如模拟环境渲染出来的车辆图片和少量不带标签的“目标域”数据真实道路摄像头图片。模拟图和真实图风格差异很大直接把源域模型用在目标域上效果崩。用MMD度量两个域的分布差训练时让网络不仅分类准确还要让两个域在某个特征空间里的MMD尽量小这个“协同训练”的过程就能把模型从模拟域“拉”向真实域效果往往立竿见影。核方法在聚类里也有应用比如核K-Means在高维特征空间做聚类中心更新能处理在原始空间中“缠成一团”的聚类结构。此外核Fisher判别分析KFDA则是把LDA线性判别分析核化用于监督降维。可以说几乎所有经典的线性算法都有一个对应的核版本。明白了这一点你的工具箱就从“几个散装算法”升级成了“一整面可自由组合的工具墙”。5. 实战中的坑与调参经验汇总5.1 特征缩放决定成败很多人用SVM高斯核结果发现模型完全学不动或者训练过程中出现NaN第一个应该检查的就是特征尺度。高斯核的输入是欧氏距离||x - y||²。如果特征A的量纲在0到1之间特征B的量纲在一万到十万之间那么距离几乎完全由特征B主导特征A在高维空间里等于不存在。此时哪怕特征A才是分类的关键模型也完全看不见。我处理这类问题的流程很简单先做标准化StandardScaler或MinMax归一化再考虑用什么核。标准化对带有异常值的特征更稳因为它用的是均值和方差不受极值边界挤占MinMax归一化对稀疏特征比较友好文本TF-IDF特征我一般不做标准化因为稀疏性一破坏内积计算就变慢了。你可以根据特征分布情况做选择但无论如何跳过特征缩放直接上高斯核是一个非常危险的做法。5.2 gamma和C的联动调参逻辑前面提过γ和C必须联合调这里把它们的交互逻辑说得再透一点。C控制的是“对错分的容忍度”C越大模型越不愿意让训练样本犯错决策边界越复杂C越小模型越宽容边界越平滑。γ控制的是单个样本的影响半径γ越大影响半径越小边界越容易绕每个样本走。这两个参数如果同时取大模型会疯狂过拟合把训练集每个噪声点都包进来如果同时取小模型会过于平滑变成近似线性欠拟合。实际调参时我发现一个比较省心的策略先用一个较粗的网格把γ放在一个很大的范围里比如2^-15到2^3C同样大范围做一次5折交叉验证画出准确率热力图大致锁定“脊线”位置然后再在脊线附近做细网格搜索。还有一个被不少人忽略的小技巧如果训练慢可以先在小规模子集上做粗调锁定一个大致的参数区间再放大全量数据上精调。直接用全量数据做几十组网格搜索在数据量稍大的时候会等得你怀疑人生。5.3 大规模样本时的计算瓶颈与解决方案核矩阵是n×n的10万样本就是100亿个元素光存储就要几十GB别说训练了构建核矩阵这步就过不去。这就是核方法最著名的痛点。针对这个问题经验上有几条路可以走。一是引入近似核方法。代表性做法是随机傅里叶特征Random Fourier Features它通过对高斯核的傅里叶变换做蒙特卡洛采样把核函数近似成一个显式的低维随机特征映射之后就能直接用线性模型训练把O(n²)的复杂度降成O(n·d)。另一个方法是Nyström近似从全部样本中采样m个地标点用这块子矩阵的近似来计算整个核矩阵的低秩逼近。二是在算法层面改走SGD路线。比如用随机梯度下降来训练非线性模型不显式构建完整核矩阵每个batch只计算batch内样本的核值。虽然这不再是“纯核方法”但在深度网络时代很多“带核技巧的神经网络”就是这么做的把核函数嵌入到网络的一层里照样可以反向传播。三是如果样本量真的特别大不如退一步认真考虑是否真的需要非线性核。我看到过不少项目费了大力气上RBF核结果和线性模型在测试集上只差零点几个百分点。真实业务中特征量够多的时候线性模型优秀特征工程往往就是“性价比之王”。5.4 核矩阵数值检查与故障排查清单最后给一份我自己排查核方法问题时常用的清单希望能帮你节省一些调试时间核函数没有做特征缩放先标准化或归一化重跑基线。自定义核函数先检查核矩阵特征值是否非负不合法就换RBF或实施正则化修正。多项式核次数过高降次数或检查特征缩放后的数值范围。训练结果NaN检查核值是否溢出高斯核一般不会多项式核和Sigmoid核概率较大。训练集准确率100%、测试集一塌糊涂γ或C调太小了往平滑方向调同时适量增加正则化。样本量超过5万认真考虑Nyström、随机傅里叶特征或直接转线性模型。分类概率输出SVM的Platt缩放可能不稳定换成带内置概率校准的模型或直接用KRR配合sigmoid校准。我自己的一个切身体会是核函数选型其实有点像选菜刀不是刀越大越好而是适合手上的活儿才最好。线性核是日常万能刀RBF是剁骨刀多项式核是雕刻刀都有了做菜才能从容。这套东西从理论到实践我前前后后折腾了不少时间每次以为自己懂了总会在某个边角料上再跌一跤。但也正是因为这些坑才把“核函数”这三个字从公式里真正活成了手底下的工具。如果你也是刚开始碰核方法建议别急着抄代码先把核矩阵是什么、为什么内积替换可行这两件事想清楚后面的路就顺多了。
返回列表