我们常说的SVM是什么

我们常说的SVM是什么

前言
SVM,即“支持向量机”,是有监督的学习模型。在机器学习中应用十分广泛。我们可以利用SVM做文本分类、图像分类以及序列分析等等。那么,接下来我们就介绍这个SVM究竟是什么?
一天,老师和我说,桌上有两种颜色的球,要我用一条线去分开它们。
在这里插入图片描述
所以,我就画了一根线在这里。
那么,问题来了。当球的数量变得越来越多的时候,我就好像不能够单单用一根线就完全分开这些球,是吧?
为了解决这种问题,SVM就横空出世了。 SVM实际上就是找到一个最佳分隔线、分隔面这样的一个界限,使得两边的样本都离这个界面足够远。当距离足够远的情况下,就可以进行分类了:假设位于界限左侧的为A类,那么位于另一侧的则为B类。可以很好地区分开来。
在这里插入图片描述
那么,如果是这样的摆放位置呢?我们似乎就无法画一条直线来区分开来。取而代之的是利用一根曲线来分隔。
同理,当球的数量越多,并且摆放位置越来越没有规律时,应该怎么解决呢?
后来,老师就用力地拍了一下桌子,这些球就腾飞到空中。如果足够厉害,就可以发现在垂直方向,也有一个平面可以将这些球完美地切分开。

那么,简单的SVM介绍就到这里了。下面就仔细介绍SVM的原理与实现。

SVM原理

支持向量机的定义在于为在特征空间上做一个间隔最大的线性分类器,使不同类别之间的间隔最大化。
如果用x表示样本数据,y表示数据的类别,那么这个线性分类器就可以在n维的数据空间中找到一个超平面。这个超平面可以用这个方程表示:
在这里插入图片描述
这个超平面可以用f(x)表示,当f(x) 等于0的时候,x便是位于超平面上的点,而f(x)大于0的点对应 y=1 的数据点,f(x)小于0的点对应y=-1的点。
在这里插入图片描述

SVM中的间隔距离

当我们确定超平面的时候,|wx+b|能够表示点x到距离超平面的远近,并且可以通过观察这个表达式的符号与y标记的是否一致(因为我们一般用作二分类问题,所以y要么为1,要么为0)。

函数间隔

在SVM中,我们引入了一个概念,函数间隔:(y(w*x+b))。其中 x 是函数变量;w 是法向量。法向量这里指的是垂直于平面的直线所表示的向量,它决定了超平面的方向。
即,我们用这个正负性来判定分类正确与否。但是这样定义的函数间隔有问题,即如果成比例的改变w和b(如将它们改成2w和2b),则函数间隔的值f(x)却变成了原来的2倍(虽然此时超平面没有改变),所以只有函数间隔还远远不够。

几何间隔

在实际应用中,我们会对法向量w作一定的约束,从而得出真正的从点到超平面的距离----几何间隔。
假定对于一个点 x ,令其垂直投影到超平面上的对应点为 x0 ,w 是垂直于超平面的一个向量, γ \gamma γ为样本x到超平面的距离,
在这里插入图片描述
所谓的几何间隔也叫欧式距离,通过求解这个欧式距离来获得最小值,也就是数据到超平面的最短距离。
在这里插入图片描述

最大间隔分类器

我们知道,当进行分类时,当置信度越高,分类就越准确。因此,当超平面离数据点的间隔越大时,分类结果的置信度也就越高。因此,为了获得更高的置信度,我们也要让这个超平面最大化这个间隔。

**通过由上面的分析可知:人为定义的函数间隔不适合用来最大化间隔值,因为在超平面固定以后,可以等比例地缩放w的长度和b的值,这样可以使得函数间隔在超平面保持不变的情况下被取得任意大。但几何间隔因为除上了w,使得在缩放w和b的时候几何间隔的值是不会改变的,它只随着超平面的变动而变动,因此,这是更加合适的一个间隔。换言之,这里要找的最大间隔分类超平面中的“间隔”指的是几何间隔。

在这里插入图片描述
如上图,那么哪一条直线是比较好的分类器呢?很显然,图线B比较靠近蓝色球,但是如果球的数量增多,蓝色的球可能会出现在B的右侧,被判断为红色球。同理A在真实环境下也有可能发生误识别。因此直线C算是一个比较好的划分。
在高维空间中,我们假定C为一个决策面,也就是我们上面说的分类间隔。我们可以移动C,使之产生一个极限的距离,在这个距离上,可以很好地判断两个类别。但是如果越过了这个位置,就会产生错误。也就是说,在这个距离上的决策面C是一个最优解,也是我们上述所说的最大分类间隔。

损失函数

在机器学习中,我们一般需要最小化损失函数,根据损失函数来衡量模型的好坏。一般的来说,需要最小化损失函数,以获得最优解。SVM采用的是Hinge Loss来求得最大间隔,即最优解。SVM 求解使通过建立二次规划原始问题,引入拉格朗日乘子法,然后转换成对偶的形式去求解,通过求解与问题等价的对偶问题,再获得原来问题的最优解,这是一种理论非常充实的解法。

那么解释一下什么是对偶?在凸优化中,任何一个求极大化的线性规划问题都有一个求极小化的线性规划问题与之对应,这就是对偶问题。

核函数

一般来说,线性分类器,计算复杂度度低,解释性好,但是线性分类器的缺电在于它的拟合程度弱。
而非线性分类器拟合程度更强,泛化能力更好,但是又容易出现过拟合的现象,除此之外,计算的复杂度也是个问题。
在实际的问题中,大部分问题都不是线性可分的,也就是说满足指定条件的超平面根本不存在。那么,对于非线性的情况,SVM又是怎么处理的呢?
SVM是通过一个核函数,通过这么一个核函数将数据映射到高维空间,来解决在原始空间中的线性不可分问题。**核函数的优点在于即使将数据变换到了高维空间,可是它的计算是发生在低维空间中的。也就是说,避免了高维空间中的复杂计算,而只是将分类的结果映射到了高维的空间。**我们经常提到的核函数有多项式核函数(参数较多,计算量大)、高斯核函数(参数数量比多项式核函数少,但是性能不错)、线性核函数(计算量少,但不能处理线性不可分问题)。

核函数的选择

那么应该如何选择核函数呢?
1.如果特征数量小,并且样本的数量正常,我们就可以使用高斯核函数;
2.如果特征数量大,和样本数量差不多,即差不多是一比一的关系。那么就是用线性核函数;
3.如果特征数量小,而样本数量比特征数大很多,我们就需要手动添加若干特征,使之变成上述情况。
4.SVM中默认的核函数是高斯核函数,rbf。

核函数的本质是两个函数的內积,通过核函数将其隐射到高维空间,在高维空间非线性问题转化为线性问题, SVM得到超平面是高维空间的线性分类平面。其分类结果也视为低维空间的非线性分类结果, 因而带核的SVM就能分类非线性问题。

松弛变量

在SVM中,我们难免会遇到与预测相差很大的结果,这时就用到松弛变量了。运用这个松弛变量可以看做是“包容地接受”这么一个噪点。使这一个离群点不会使超平面发生移动、间隔缩小。通过改变松弛变量也就是对模型敏感性地调整。
在这里,我们又引入了硬间隔和软间隔的概念
硬间隔指的就是完全分类准确,不能存在分类错误的情况。软间隔,就是允许一定量的样本分类错误。
1.在完全线性可分的情况下,我们可以使用硬间隔,因为可以获得一个理想的分类器,但是实际中往往做不到。
2.在大部分的线性可分条件下,我们可以引入软间隔,允许出现一定的样本分类错误。
3.到了线性不可分的情况下,我们就要引入核函数。将原本的样本空间通过核函数映射到高维空间中,以获得一个最优解,从而实现线性可分。

惩罚系数

与松弛变量相对应的是惩罚系数C。惩罚系数是指对分类错误的惩罚程度,当C越大时,分类器效果越好,但是容易出现过拟合,泛化能力变差。相反,当C越小时,泛化能力会增强但是准确性就会稍微降低。

实战

from sklearn import svm
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
import numpy as np


def plot_hyperplane(clf, X, y, 
                    h=0.02, 
                    draw_sv=True, 
                    title='hyperplan'):
    # create a mesh to plot in
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))

    plt.title(title)
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.xticks(())
    plt.yticks(())

    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    # Put the result into a color plot
    Z = Z.reshape(xx.shape)
    plt.contourf(xx, yy, Z, cmap='hot', alpha=0.5)

    markers = ['o', 's', '^']
    colors = ['b', 'r', 'c']
    labels = np.unique(y)
    for label in labels:
        plt.scatter(X[y==label][:, 0], 
                    X[y==label][:, 1], 
                    c=colors[label], 
                    marker=markers[label])
    if draw_sv:
        sv = clf.support_vectors_
        plt.scatter(sv[:, 0], sv[:, 1], c='y', marker='x')




X, y = make_blobs(n_samples=100, centers=3, 
                  random_state=0, cluster_std=0.8)
clf_linear = svm.SVC(C=1.0, kernel='linear')
clf_poly = svm.SVC(C=1.0, kernel='poly', degree=3)
clf_rbf = svm.SVC(C=1.0, kernel='rbf', gamma=0.5)
clf_rbf2 = svm.SVC(C=1.0, kernel='rbf', gamma=0.1)


plt.figure(figsize=(10, 10), dpi=144)


clfs = [clf_linear, clf_poly, clf_rbf, clf_rbf2]
titles = ['Linear Kernel', 
          'Polynomial Kernel with Degree=3', 
          'Gaussian Kernel with $\gamma=0.5$', 
          'Gaussian Kernel with $\gamma=0.1$']

for clf, i in zip(clfs, range(len(clfs))):
    clf.fit(X, y)
    plt.subplot(2, 2, i+1)
    plot_hyperplane(clf, X, y, title=titles[i])
    

最后的结果:
在这里插入图片描述

SVM 多分类器是集成算法么?

SVM 算法最初是为二分类问题设计的,如果我们想要把 SVM 分类器用于多分类问题,常用的有一对一方法和一对多方法。集成学习的概念你这样理解:通过构造和使用多个分类器完成分类任务,也就是我们所说的博取众长。以上是 SVM 多分类器和集成算法的概念,关于 SVM 多分类器是否属于集成算法,我认为你需要这样理解。在 SVM 的多分类问题中,不论是采用一对一,还是一对多的方法,都会构造多个分类器,从这个角度来看确实在用集成学习的思想,通过这些分类器完成最后的学习任务。不过我们一般所说的集成学习,需要有两个基本条件:每个分类器的准确率要比随机分类的好,即准确率大于 50%;每个分类器应该尽量相互独立,这样才能博采众长,否则多个分类器一起工作,和单个分类器工作相差不大。所以你能看出,在集成学习中,虽然每个弱分类器性能不强,但都可以独立工作,完成整个分类任务。

而在 SVM 多分类问题中,不论是一对一,还是一对多的方法,每次都在做一个二分类问题,并不能直接给出多分类的结果。此外,当我们谈集成学习的时候,通常会基于单个分类器之间是否存在依赖关系,进而分成 Boosting 或者 Bagging 方法。如果单个分类器存在较强的依赖关系,需要串行使用,也就是我们所说的 Boosting 方法。如果单个分类器之间不存在强依赖关系,可以并行工作,就是我们所说的 Bagging 或者随机森林方法(Bagging 的升级版)。所以,一个二分类器构造成多分类器是采用了集成学习的思路,不过在我们谈论集成学习的时候,通常指的是 Boosing 或者 Bagging 方法,因为需要每个分类器(弱分类器)都有分类的能力。

以上内容如有错误,欢迎指出。谢谢!

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值