- 转载请注明作者和出处:http://blog.csdn.net/u011475210
- 代码地址:https://github.com/WordZzzz/ML/tree/master/Ch06
- 操作系统:WINDOWS 10
- 软件版本:python-3.6.2-amd64
- 编 者:WordZzzz
前言:
前面三篇讲的都是SVM线性分类器,如果数据集非线性可分(如下图所示),那就需要做些修改了。
显而易见,在该数据中存在某种可以识别的模式。接下来,我们就需要使用一种称为核函数(kernel)的工具将数据转换成易于分类器理解的形式。在本篇博文中,我们先对核函数进行简单的了解,然后重点研究径向基函数(radial basis function,最流行的核函数)及其实现,最后在我们之前的手写数字识别问题上进行实践。
核函数简介
再看本文章开头的图片,我们似乎可以用一个圆来吧数据划分开来,但是对于线性分类器来说,这好像很难实现。我们或许可以对数据进行某种形式的转换,从而得到某些新的变量来表示数据。在这个例子中,我们将数据从一个特征空间转换到另一个特征空间,在新空间下,我们可以很容易利用已有的工具对数据进行处理。这个过程,学过数学的都知道,即从一个特征空间到另一个特征空间的映射。通常情况下,核函数实现的是低维到高维的映射,以后其他算法涉及到的PCA等,则是高维到低微的映射。经过空间转换之后,我们可以在高维空间解决线性问题,这也就等价于在低维空间中解决非线性问题。
SVM优化中一个特别好的地方就是,所有的运算都可以写成内积(inner product,也叫点积)的形式。向量的内积指的是两个向量相乘,之后得到单个标量或者数值。我们可以把内积运算替换成核函数,而不必做简化处理。将内积替换成核函数的方式被称为核技巧(kernel trick)或者核“变电”(kernel substation)。
当然,核函数并不仅仅应用于SVM中,很多其他的机器学习算法也都用到核函数。接下来,我们就来介绍一个流行的核函数,那就是径向基函数。
径向基函数
径向基函数是一个采用向量作为自变量的函数,能够基于向量距离运算输出一个标量。这个距离可以使从<0,0>向量或者其他向量开始计算的距离。我们用到的径向基函数的高斯版本公式为:0,0>
$$
k(x,y) = exp(\frac{ {-\begin{Vmatrix} x-y \end{Vmatrix} }^2}{2 \sigma^2})
$$
其中,σ是用户定义的用于确定到达率(reach)或者说是函数值跌落到0的速度参数。
上述高斯核函数将数据从其特征空间映射到跟高维的空间,具体来说这里是映射到一个无穷维的空间。在该数据集上,使用高斯核函数得到一个很好的结果,当然,该函数也可以用于许多其他的数据集,并且也能够得到低错误率的结果。
核函数实现
如果在svmMLiA.py文件中添加一个函数并稍作修改,那么我们就能在已有代码中使用核函数了(所有与核函数实现相关的函数,函数名末尾都是K)。其中主要区分代码在innerLK()和calcEk()中,我已经重点标记出。
新添加的核转换函数,主要用于填充结构体和后续的计算:
1 | def kernelTrans(X, A, kTup): |
其他函数:
1 | class optStructK: |
接下来我们写测试函数。整个代码中最重要的是for循环开始的那两行,他们给出了如何利用核函数进行分类。首先利用结构初始化方法中使用过的kernelTrans()函数,得到转换后的数据。然后,再用其与前面的alpha及类别标签值求积。特别需要注意观察的是,我们是如何做到只需要支持向量数据就可以进行分类的。
1 | def testRbf(k1 = 1.3): |
上述代码分别在训练集和测试集上进行性能测试,打印输出如下:
1 | reload(svmMLiA) |
当然,大家也可以尝试更换不同的k1参数以观察测试错误率、训练错误率、支持向量个数随k1的变化情况。下面个两张图是书上的举例。
我们会发现,支持向量的数目存在一个最优值。SVM的优点在于它能对数据进行高效分类。如果支持向量太少,就可能会得到一个很差的决策边界;如果支持向量太多,也就是相当于每次都利用整个数据集进行分类,这种分类方法成为kNN(多么熟悉)。
手写识别问题回顾
SVM对kNN的优点在于,SVM只需要保留支持向量就可以获得可比的效果,占用内存大大减小。下面,我们就用SVM来对手写数字进行分类识别(不加修改的SVM只能用于二分类问题,在这里,我们规定,如果是数字9,则为-1,否则为+1)。
1 | def img2vector(filename): |
上面的大部分代码我们都已经很熟悉了,这里就不再赘述,直接进行测试。
1 | reload(svmMLiA) |
尝试不同的σ,并尝试了线性核函数,总结得到如图结果:
Kernel,settings | Training error (%) | Test error (%) | # Support vectors |
---|---|---|---|
RBF,0.1 | 0 | 52 | 402 |
RBF,5 | 0 | 3.2 | 402 |
RBF,10 | 0 | 0.5 | 99 |
RBF,50 | 0.2 | 2.2 | 41 |
RBF,100 | 1.5 | 4.3 | 26 |
Linear | 2.7 | 2.2 | 28 |
结果表明,当径向基函数的参数σ取10左右时,就可以得到最小的测试错误率。同时,最小的训练错误率,并不对应于最小的支持向量数目。另外,线性核函数的效果并不是特别糟糕,可以以牺牲线性核函数的错误率来换取分类速度的提高。
总结
支持向量机是一种分类器。之所以称为“机”是因为它会产生一个二值决策结果,即它是一种决策“机”。支持向量机的泛化错误率较低,具有良好的学习能力,且学到的结果具有很好的推广性。这些优点使得支持向量机十分流行,有些人认为他是监督学习中最好的定式算法。
系列教程持续发布中,欢迎订阅、关注、收藏、评论、点赞哦~~( ̄▽ ̄~)~
完的汪(∪。∪)。。。zzz