写点什么

支持向量机 - 非线性 SVM 与核函数

  • 2022-11-24
    山东
  • 本文字数:2488 字

    阅读完需:约 8 分钟

这一节是核函数的过度


如果把数据推广到非线性数据,比如说环形数据上


from sklearn.datasets import make_circlesX,y = make_circles(100, factor=0.1,noise=0.1)
X.shape---(100, 2)
y.shape---(100,)
plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap="rainbow")
复制代码



clf = SVC(kernel='linear').fit(X,y)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap='rainbow')plot_svc_decision_function(clf)
复制代码



明显,现在线性 SVM 已经不适合于我们的状况了,我们无法找出一条直线来划分我们的数据集,让直线的两边分别是两种类别。这个时候,如果我们能够在原本的 X 和 y 的基础上,添加一个维度 r,变成三维,我们可视化这个数据,来看看添加维度让我们的数据如何变化。


r = np.exp(-(X**2).sum(1))# sum(1)每行求和# np.exp表示e的x次方,x为输入的数字
r.shape---(100,)
from mpl_toolkits import mplot3d
def plot_3D(elev=30,azim=30,X=X,y=y): ax = plt.subplot(projection="3d") ax.scatter3D(X[:,0],X[:,1],r,c=y,s=50,cmap="rainbow") # 多了一个维度r ax.view_init(elev=elev,azim=azim) # 旋转视图的角度,elev上下旋转的角度,azim左右旋转的角度 ax.set_xlabel("x") ax.set_ylabel("y") ax.set_zlabel("z") plt.show() plot_3D()
复制代码



可以看见,此时此刻我们的数据明显是线性可分的了:我们可以使用一个平面来将数据完全分开,并使平面的上方的所有数据点为一类,平面下方的所有数据点为另一类。


from ipywidgets import interact,fixedinteract(plot_3D,elev=[0,30],azip=(-180,180),X=fixed(X),y=fixed(y))# 用到啥说啥# elev和azip后面传入元组,就是一个可平滑调节的按钮,传入列表,就是一个下拉菜单,只能选择菜单中的角度
复制代码



此时我们的数据在三维空间中,我们的超平面就是一个二维平面。我们刚才做的,计算 r,并将 r 作为数据的第三维度来将数据升维的过程,被称为“核变换”,即是将数据投影到高维空间中,以寻找能够将数据完美分割的超平面,即是说寻找能够让数据线性可分的高维空间。

SVC 在非线性数据上的推广

为了能够找出去非线性数据的线性决策边界,我们需要将数据从原始的空间投射到新空间中。是一个映射函数,它代表了某种非线性的变换,如同我们之前所做过的使用 r 来升维一样。使用这种变换,线性 SVM 的原理可以被很容易推广到非线性情况下,其推导过程和逻辑都与线性 SVM 一模一样,只不过在定义决策边界之前,我们必须先对数据进行升维度,即将原始的转换成如此,非线性 SVM 的损失函数的初始形态为


\left{\begin{aligned}&\mathop{\text{min }}\limits_{\omega,b}\frac{||\omega||^{2}}{2}\&y_{i}(\omega \cdot \Phi (x_{i})+b)\geq 1,i=1,2,\cdots,N\end{aligned}\right.


同理,非线性 SVM 的拉格朗日函数和拉格朗日对偶函数也可得



使用同样的推导方式,让拉格朗日函数满足 KKT 条件并在拉格朗日函数上对每个参数求导,经过和线性 SVM 相同的变换后,就可以得到拉格朗日对偶函数。同样使用梯度下降或 SMO 等方式对进行求解,最后可以求得决策边界,并得到最终的决策函数


重要参数 kernel

这种变换非常巧妙,但也带有一些实现问题。 首先,我们可能不清楚应该什么样的数据应该使用什么类型的映射函数来确保可以在变换空间中找出线性决策边界。极端情况下,数据可能会被映射到无限维度的空间中,这种高维空间可能不是那么友好,维度越多,推导和计算的难度都会随之暴增。其次,即使已知适当的映射函数,我们想要计算类似于这样的点积,计算量可能会无比巨大,要找出超平面所付出的代价是非常昂贵的。而解决这些问题的数学方式,叫做“核技巧”(Kernel Trick),是一种能够使用数据原始空间中的向量计算来表示升维后的空间中的点积结果的数学方式。具体表现为,**。而这个原始空间中的点积函数,就被叫做“核函数”(Kernel Function)**。


这里超出个人能力范围了,只能跑一下代码,以后再研究吧


核函数能够帮助我们解决三个问题:


  1. 有了核函数之后,我们无需去担心究竟应该是什么样,因为非线性 SVM 中的核函数都是正定核函数(positive definite kernel functions),他们都满足美世定律(Mercer's theorem),确保了高维空间中任意两个向量的点积一定可以被低维空间中的这两个向量的某种计算来表示(多数时候是点积的某种变换)。

  2. 使用核函数计算低维度中的向量关系比计算原本的要简单太多了

  3. 因为计算是在原始空间中进行,所以避免了维度诅咒的问题。


选用不同的核函数,就可以解决不同数据分布下的寻找超平面问题。在 SVC 中,这个功能由参数“kernel”和一系列与核函数相关的参数来进行控制。参数“kernel"在 sklearn 中可选以下几种选项:



可以看出,除了选项"linear"之外,其他核函数都可以处理非线性问题。多项式核函数有次数 d,当 d 为 1 的时候它就是再处理线性问题,当 d 为更高次项的时候它就是在处理非线性问题。


我们之前画图时使用的是选项“linear",自然不能处理环形数据这样非线性的状况。而刚才我们使用的计算 r 的方法,其实是高斯径向基核函数所对应的功能,在参数”kernel“中输入”rbf“就可以使用这种核函数。我们来看看模型找出的决策边界时什么样:


clf = SVC(kernel="rbf").fit(X,y)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap="rainbow")plot_svc_decision_function(clf)
复制代码



可以看到,决策边界被完美地找了出来


视频作者:菜菜TsaiTsai链接:【技术干货】菜菜的机器学习sklearn【全85集】Python进阶_哔哩哔哩_bilibili


发布于: 刚刚阅读数: 4
用户头像

跃入人海 2022-09-14 加入

还未添加个人简介

评论

发布
暂无评论
支持向量机-非线性SVM与核函数_Python_烧灯续昼2002_InfoQ写作社区