ARTICLE DETAIL

资讯详情

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

一条直线分不开,就往高维“扔“——支持向量机与核技巧

一条直线分不开,就往高维“扔“——支持向量机与核技巧 给你一堆点红的一半、蓝的一半混在一起。你的任务画一条线把红蓝分开。如果点摆得规整一条直线就能搞定。可现实里点往往是你中有我、我中有你——比如月亮形状红点围成一圈蓝点挤在中间任何一条直线都分不开。这时候怎么办支持向量机Support Vector MachineSVM给出了一个漂亮到不行的答案既然二维里分不开那就把数据扔到三维、四维……甚至无穷维的空间里在那里它们可能就分得开了。这一篇就把 SVM 和它最惊艳的核技巧讲透。第一性原理分类就是找一条最宽的隔离带先处理最简单的情况数据线性可分。画一条直线能把红蓝分开这样的直线其实有无数条——有的贴着红点有的贴着蓝点有的在正中间。该选哪条SVM 的答案是选间隔margin最大的那条。什么叫间隔就是这条直线到两边最近的几个点的距离之和。SVM 要的是让这条隔离带尽可能宽宽到红蓝两边最近的几个点离这条线都尽量远。为什么要追求最宽直觉特别好理解离数据越远的线越稳。贴着红点画一条线来一个新的、位置稍微偏一点的红点可能就落到线另一边了分类就错了而一条居中、留足了余量的线对新数据有更大的容错空间。这条最宽的隔离带在数学上叫最大间隔超平面。而那些撑起这条隔离带边界的、离超平面最近的几个点就是大名鼎鼎的支持向量Support Vector——SVM 这个名字就是靠支持向量撑起来的机器。超平面方程是w ⋅ x b 0 w \cdot x b 0w⋅xb0SVM 要最大化的间隔是2 ∥ w ∥ \frac{2}{\lVert w \rVert}∥w∥2​w ww越小间隔越宽。所以问题变成在所有点都分对的约束下让∥ w ∥ \lVert w \rVert∥w∥最小。现实没有完美软间隔允许犯点小错上面是理想情况——数据干净利落地线性可分。但现实的数据总有那么几个捣乱的点要么混进对方阵营要么骑在边界上。如果死磕一个都不能错硬间隔Hard Margin就会为了迁就那一两个点把隔离带压得极窄反而过拟合了。SVM 的解法是软间隔Soft Margin允许分类时犯点小错但每个错都要付出代价。数学上就是引入松弛变量ξ \xiξ让约束变成大部分点分对、少数点允许越界并在目标里加上对这些越界的惩罚min ⁡ w , b 1 2 ∥ w ∥ 2 C ∑ i ξ i \min_{w, b} \ \frac{1}{2}\lVert w \rVert^2 C\sum_i \xi_iw,bmin​21​∥w∥2Ci∑​ξi​那个参数C CC就是惩罚力度的旋钮C CC大 → 容错低、隔离带窄、倾向过拟合C CC小 → 容错高、隔离带宽、倾向欠拟合。C CC就是 SVM 里最重要的一个超参数调它就是在分得准和不钻牛角尖之间找平衡。真正的杀手锏核技巧Kernel Trick回到开头的月亮形数据——二维里画不出直线。软间隔也救不了它因为它根本不是有噪点的线性可分而是线性不可分。朴素的思路是造一个新函数把二维的点映射到更高维。比如( x 1 , x 2 ) → ( x 1 , x 2 , x 1 2 x 2 2 ) (x_1, x_2) \to (x_1, x_2, x_1^2 x_2^2)(x1​,x2​)→(x1​,x2​,x12​x22​)加上到原点的距离平方这第三个维度。神奇的是很多低维里纠缠不清的数据升到高维后一个平面就切开了。但这里有个致命的工程问题显式地升维计算量爆炸。映射到一万维就要算一万维的点积映射到无穷维直接算不了。SVM 的天才之处就藏在它的数学形式里。经过推导拉格朗日对偶SVM 的求解只依赖样本两两之间的点积x i ⋅ x j x_i \cdot x_jxi​⋅xj​从不需要单独算出每个样本在高维里的坐标。这意味着我根本不用显式地把x xx映射成ϕ ( x ) \phi(x)ϕ(x)我只需要一个函数K ( x i , x j ) ϕ ( x i ) ⋅ ϕ ( x j ) K(x_i, x_j) \phi(x_i) \cdot \phi(x_j)K(xi​,xj​)ϕ(xi​)⋅ϕ(xj​)直接算出映射后两个点的点积就行。这个函数K KK就叫核函数Kernel这整个不显式映射、只算点积的花招就叫核技巧Kernel Trick。它的威力有多大看几个常用核线性核K ( x i , x j ) x i ⋅ x j K(x_i, x_j) x_i \cdot x_jK(xi​,xj​)xi​⋅xj​等价于不升维用于线性可分数据多项式核K ( x i , x j ) ( x i ⋅ x j c ) d K(x_i, x_j) (x_i \cdot x_j c)^dK(xi​,xj​)(xi​⋅xj​c)d映射到有限高维RBF 核高斯核K ( x i , x j ) exp ⁡ ( − γ ∥ x i − x j ∥ 2 ) K(x_i, x_j) \exp(-\gamma \lVert x_i - x_j \rVert^2)K(xi​,xj​)exp(−γ∥xi​−xj​∥2)隐式地映射到无穷维空间——你没看错无穷维。但有了核技巧你连一维都不需要真的算出来一个exp ⁡ \expexp就搞定了。这就是核技巧最迷人的地方它让你在无穷维空间里做事却只花低维空间的计算量。把月亮形的数据用 RBF 核一扔无穷维里它线性可分了而你的计算成本还是二维的。一句话串起整个 SVM把上面几层叠起来SVM 的全貌就清楚了SVM 找最大间隔的分界线稳 软间隔容错现实 核技巧升维处理线性不可分。它特别适合什么场景中小规模、高维度、样本量不太大的分类问题。比如文本分类词向量维度高、样本相对少、生物信息、小样本图像分类等。在深度学习兴起之前SVM 一度是分类问题的王者。这里也顺便呼应一下之前聊过的词向量核技巧的本质是把数据映射到另一个空间让原本纠缠的关系在新的空间里变得简单——词向量干的其实也是空间映射这一件事国王 − 男人 女人 王后计算机凭什么算出这层意思——词向量一次讲透。一个是把语义映射到向量空间一个是把低维映射到高维思想是相通的。亲手感受一下核的威力光说不练假把式。下面这段代码用 sklearn 演示线性不可分的数据换一个核就分开了importnumpyasnpfromsklearn.svmimportSVC# 造一个月亮形数据红点围一圈蓝点在中间线性不可分rngnp.random.RandomState(0)n100# 红点外圈theta_rrng.uniform(0,2*np.pi,n)X_rnp.c_[1.5*np.cos(theta_r),1.5*np.sin(theta_r)]rng.normal(0,0.1,(n,2))# 蓝点内圈theta_brng.uniform(0,2*np.pi,n)X_bnp.c_[0.6*np.cos(theta_b),0.6*np.sin(theta_b)]rng.normal(0,0.1,(n,2))Xnp.vstack([X_r,X_b])ynp.hstack([np.ones(n),np.zeros(n)])# 红1蓝0# 线性核二维里画不出直线效果差linSVC(kernellinear).fit(X,y)# RBF 核隐式升到无穷维轻松分开rbfSVC(kernelrbf,gamma2).fit(X,y)print(f线性核 训练准确率:{lin.score(X,y):.2f})print(fRBF 核 训练准确率:{rbf.score(X,y):.2f})print(f线性核 支持向量数:{lin.n_support_.sum()}| RBF 核 支持向量数:{rbf.n_support_.sum()})跑出来你会发现线性核在这个数据上准确率可怜因为本质上分不开而 RBF 核几乎 100%。同样的数据、同样的算法只换了一个核结果天差地别。这就是往高维扔的威力。结语换个空间看问题难题可能迎刃而解SVM 教给我的远不止一个分类算法。它最深的启示是那句朴素的话有些问题在原来的维度里无解换个空间可能就迎刃而解。二维里纠缠不清的点扔到高维就分开了眼前解决不了的矛盾换个角度看可能就有路了。而核技巧则提醒我们聪明的做法不是硬算而是找到那个不必显式计算、却能享受其好处的捷径。无穷维很吓人但一个exp ⁡ \expexp就绕过去了。真正的高手永远在找这样的四两拨千斤。想把 SVM 里的间隔、对偶、核函数、正则化这些彻底吃透线代和微积分是绕不开的底子。推荐 B站【408实验室】的《机器学习数学基础》把向量空间、内积、优化这些基础补牢——核技巧为什么能白嫖高维的好处你会在数学里找到答案。
返回列表