机器学习A-Z~支持向量机

本文将介绍机器学习中一个非常重要的算法,叫做SVM,中文翻译支持向量机。首先看一组例子来解释这个算法。

基本概念

有一组数据如图所示,有红色的点和蓝色的点,代表了两种分类的数据,现在我们要做的是如何将这两种数据准确的分隔开来。看图像其实很简单,可以横着画一条直线或者竖着画或者斜着画都能将其分隔开来。那么svm要做的就是找到最佳的一条直线。

那么这条直线要满足的特点是它和红组和绿组有最大的间隔。所谓最大间隔就是红组中离直线最近的点的距离和绿组中离直线最近的距离最大。这两个点就叫做Support Vector。这里解释下为什么叫支持向量,首先“支持”的意思,就是说这些数据点中除了两个点之外的任何一个点都不会影响到这个算法的决策边界,即这条直线实际上是又这两个点支持的,然后“向量”,在二维空间中的点实际上都可以用向量表示,但在高维中没办法用几何方式表示出来,它其实都是向量。

对于这条直线,我们称作Maximum Margin Hyperplane/Classifier,即最大间隔超平面。所谓超平面就是比数据空间少一维的空间,比如这里二维的那么对应的就是一维的即一条直线。

其中和这条直线平行的这两天直线,一个叫做正向超平面,一个叫负向超平面,这个正负这里只是跟法向量有关,是数学上的概念,不用太在意正负。

接下来看看这个SVM算法为什么这么特别。这里假设我们需要训练一个算法来识别苹果和橘子,比如通过水果的颜色和水分来判断。那么大部分的苹果都是青色或者红色,而橘子一般是黄色。那么在图像中可以当作这个横轴代表颜色,x1越往右的就是颜色偏黄色的,那么这部分数据显然都是橘子。

这些正常的水果都在边界的两侧,并且这部分的数据距离边界都相对较远。那么SVM最特别的地方就是它可以学习到最特殊最特别的东西,比如说这个时候出现了一个黄色的苹果,很像橘子。那么这样的苹果就是SVM中的支持向量,同样如果这时有个绿色的橘子也是支持向量。因此SVM其实是由数据中比较极端的个例所实现的。这点和其他的算法有根本的不同。

python实现基础的SVM

对于如何在python中实现SVM算法其实很简单,之前的课程中已经讲述了一个分类问题的Logistic Regression算法,我们要做的只是将其中的分类器由LogisticRegression改成SVM算法即可。这里只粘贴那一部分的代码:

from sklearn.svm import SVC
classifier = SVC(kernel='linear', random_state=0)
classifier.fit(X_train, y_train)

这里的kernel指的是SVM算法的核,后文会详细解释,这里用的是linear即线性。最终得到的结果我们会发现和之前的分类方式相比优化程度并不是很高,这个和核的选择是有很大关系的。

核函数支持向量机

上面讲的都是线性分类问题,那么非线性的问题就暂时还无法结局,因此我们需要改良SVM算法,这就是接下来要将的Kernel SVM。

高维投射

看下面这组数据,显然不是一个线性问题,我们无法用线性的方法将其分类。

首先,我们先将线性不可分的数据从低维投射到高维,使得其在高维上线性可分,接下来再将分隔好的数据投射到原先低维的空间。这里先举一个一维的问题。这里有一条直线上,有红色和绿色的点,这条直线上是否存在一个点将红点和旅店分开。显然是无法做到的,那么需要将其投射到二维空间上。

这里假设有个点在红绿之间x=5,那么将所有的点左移5个单位,然后画出一条曲线y=(x-5)^2,这样就可以将点都投射到这条曲线上。此时就可以找到一条直线将红绿两组数据分隔开来了。

那么再回过头看看上面的二维的问题,我们需要再添加一条坐标轴将其投射到三维空间中,此时可以找到一条超平面来分隔开红绿两组数据。

找到这个平面后我们还需要将其投射回二维平面上,得到的就是如图一样的圈,这样就将数据成功分隔开来。

但由于高维到低维然后低维到高维对于计算机而言计算量很大,那么我们就需要引入核函数来解决非线性问题,可以绕过这里的繁琐的计算过程,却依然能解决问题。

核函数技巧

首先讲讲非线性SVM中最常用的核函数,The Gaussian RGF Kernel。

这里先假设l已经确定,那么这个函数就是关于向量x的方程。将其在图像上表示出来,这里假设l就是(0,0,0)点。

从方程上来看,如果x与l距离很大,那么指数就会大,由于是负数,那么整个方程的结果就会趋向于0.如果x与l距离很接近,那么指数就会趋向于0,加个符号依然趋向于0,那么这个函数就趋向于1.这里从图像也能看出来。

那么接下来看看如何利用这个函数来寻找数据的分类边界。函数中的l我们可以当作基准点,在上述的数据中如图假设是绿色点的中心,那么很显然,所有的绿色点距离这个点的距离一定是小于某个常数,而红色的点距离它的距离一定大于这个常数。

在三维空间中我们可以画个圈如图所示,这个圈的纵坐标并不是就是0,只是很接近于0。那么绿色点就是坐落于圈的里面这个高上上面,而红色的点就在这个圈外面。此时就可以将这个圈投影到二维平面上,即这组数据的分类边界。

接下来再讲讲这个\sigma是做什么的,它实际上是控制这个圆的半径。当其升高的时候,要达到同样的函数值,分母也要变大,那么圆圈的半径就会越大,反之其越小的时候半径也会越小。这个\sigma的值取决于数据本身,如果这个绿色的数据本身就蜷缩在一起,那么它就会很小,反之很大。

再看一个稍微复杂点的数据如下所示:

那么它的边界就类似两个圆拼接在一起,核函数就是两个不同的核函数的和,实际情况可能会乘上一个系数。那么绿色的点距离这两个核的距离和较小,红色的距离它们的和距离较大。

那么分类边界怎样界定。如图,这里的K(x,l1)K(x,l2)其实都是关于x1,x2的函数。关于x1,x2的函数等于0在二维空间可以得到一条曲线。假设此时有个新的点,那么计算这个和如果大于等于0,那么就分到绿色组,如果小于等于0则分到红色组。其实完整的版本的函数应该在这两个函数前都分别要加上一个系数,最后加上一个常数。但这里为了方便理解只写出了简化版本。

除去高斯核函数还有一些其他常用的核函数如下所示:

不同的核函数

但其实还有很多其他的核函数,这里给出一个网址,里面有很多核函数的介绍,感兴趣的朋友可以自行查看。

最后的python代码实现其实就是将上面线性的核换成高斯核,如下所示:

classifier = SVC(kernel='rbf', random_state=0)

最终得到的结果可以自行查看,会发现这个分类器的效果比之前的是有明显提升的。

点赞

发表评论

%d 博主赞过: