您的位置:首页 > 其它

[机器学习]支持向量机及其应用---手写识别系统(SMO算法)

2015-12-22 21:43 573 查看
感知机

支持向量机理论
线性可分支持向量机

线性支持向量机

非线性支持向量机
常见核函数

SMO算法

支持向量机的应用手写识别系统
应用背景

工具选择

转换样本数据
将txt文本转换为arff文件

算法执行

使用测试数据测试模型好坏

与KNN算法实验结果对比

参考资料

本博文将介绍支持向量机的一些理论并使用WEKA来得到一个分类器。在介绍支持向量机之前,先介绍感知机的一些知识。

感知机

感知机是二类分类的线性分类模型,其输入为实例的特征向量,输出为实例类别。感知机对应于输入空间中的实例划分为正负两类的分离超平面,属于判别模型。感知机的描述如下:

给定一个训练数据集

        T={(x1,y1),(x2,y2),...,(xN,yN)}T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}

其中xix_i是输入空间,yiy_i是类别。求参数w,bw,b,使得损失函数极小化问题的求解

      minw,bL(w,b)=−∑xi∈M(wxi+b)min_{w,b}L(w,b)=-\sum_{x_i \in M}{(wx_i+b)}

其中M是误分类点的集合。

具体采用随机梯度下降算法求解(不适用批量下降算法的原因是:批量下降算法会慢,虽然其选取的梯度都是最“抖”的那个,但是真正要效率更好的话,还是随机下降更高)。

感知机问题的最后求解,会得到一个分离超平面,会将两类分成两部分。这样的分离超平面是有无穷多个的。但是哪个分离超平面更好?如何找到一个更好的分离超平面?这就是支持向量机的问题了。

支持向量机理论

支持向量机的间隔最大化和核技巧,使它即可以处理线性分类问题,也可以处理非线性问题。

线性可分支持向量机

上面介绍完感知机问题后,其实线性可分支持向量机,就是求解感知机问题的一个最大间隔超平面。首先这个最大间隔超平面是存在的,且唯一的,存在唯一性可以通过数学证明(反证法可以证明得到唯一性)。

先给出线性可分支持向量机的原始问题的描述:

minw,b12||w||2min_{w,b} \frac{1}{2}||w||^2

s.t yi(w⋅xi+b)−1≥0,i=1,2,...,Ny_i(w\cdot x_i+b)-1 \geq 0, i=1,2,...,N

为了求解线性可分支持向量机的原始问题,可以应用拉格朗日对偶性来得到原始问题的最优解。具体的过程这里不再叙述。可以参见李航《统计学习方法》。

线性支持向量机

实际情况中,训练数据集往往并不是线性可分的,因为存在着噪声以及特异点。当然,我们可以先去除掉噪声数据再进行线性可分的操作,但是如何判断噪声数据实际上是很麻烦的事。那么就推广到了更一般的情况—-线性支持向量机。

上面线性可分支持向量机的间隔是硬间隔最大化,现在这种情况下,应当是软间隔最大化。

为了解决这个问题需要引入松弛变量的概念(在线性规划问题中,单纯形算法也引入了松弛变量,其实道理是类似的)。

多的不叙述了,很多参考书上有具体的证明过程,给出问题。

minw,b12||w||2+C∑Ni=1εmin_{w,b} \frac{1}{2}||w||^2 +C\sum_{i=1}^N\varepsilon

s.t yi(w⋅xi+b)−1+ε≥0,i=1,2,...,Ny_i(w\cdot x_i+b)-1+\varepsilon \geq 0, i=1,2,...,N

其中ε\varepsilon 是松弛变量。

同样可以通过对偶的方式求解出解。

非线性支持向量机

非线性分类其实是最常见的了,求解这类问题需要引入核技巧。对于数学系的笔者来说,核函数的理解还是很难啊(应该是没学过泛函分析的结果)。简单点说,通过核技巧,可以将非线性问题转换成线性问题。这样就可以通过线性可分支持向量问题来求解了。

常见核函数

(1)多项式核函数

K(x,z)=(x⋅z+1)pK(x,z)=(x \cdot z+1)^p

(2)高斯核函数

K(x,z)=exp(−||x−z||22σ2)K(x,z)=exp(-\frac{||x-z||^2}{2 \sigma^2 })

当然可以自定义核函数,但是需要满足下面条件:

自定义的核函数应该是正定的。其充要条件:

设K:χ×χ→RK:\chi \times \chi \rightarrow R是对称函数,则K(x,z)K(x,z)为正定核函数的充要条件是对任意xi∈χ,i=1,2,...,mx_{i} \in \chi,i=1,2,...,m,K(x,z)K(x,z) 对应的Gram矩阵K=[K(xi,xj)]m×nK=[K(x_i,x_j)]_{m \times n}是半正定矩阵。 ———–李航《统计学习方法》

SMO算法

SMO算法是一种启发式算法。其基本思路是:所有变量的解都满足KKT条件时,已经得到最优解。否则,选择2个变量(其中有一个变量必须是不满足KKT条件的),固定其它所有的变量,进行求解。不断的迭代计算,最终得到最优解。当然这里的2个变量的选择是很有讲究的。分为2层循环的选择,具体就不再叙述了。可以参考其它资料。

支持向量机的应用—手写识别系统

应用背景

在《机器学习实战》书第二章给了一个手写识别系统的例子(主要是由于他提供了数据),在官网下载到数据。有2000个训练样本,900个测试样本。可下载。

工具选择

和上一篇一样,我们使用weka工具。在数据转换过程中,笔者遇到了些许问题,这里需要强调一点,weka对于数据格式的要求还是比较严格的。

转换样本数据

将txt文本转换为arff文件

所有的文件(包括转换后的数据可下载,点击可下载

原来的txt数据截图如下。




将其WEKA可以处理的格式,这个数据是32×32的数据,一共1024个数据。我将其转换成了1024个属性。并且是数字型。一共有2000多个训练样本,编写J***A程序处理得到arff格式文件。J***A代码参考如下。

[code]import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;

public class transToArff {
    @SuppressWarnings("resource")
    public static void main(String[] args) throws IOException {
        File dir = new File(
                "/Users/arthur/Desktop/机器学习与数据挖掘/machinelearninginaction/Ch02/digits/trainingDigits");
        File[] file = dir.listFiles();
        FileOutputStream out = null;   
        out= new FileOutputStream(new File("/Users/arthur/Desktop/numbertrain.arff"));   
        out.write("@relation testKNN_predicted_predicted\n".getBytes());
        for(int i=1;i<1025;i++){
            out.write(("@attribute"+" "+i+" numeric\n").getBytes());
        }
        out.write("@attribute leixing {0,1,2,3,4,5,6,7,8,9}\n".getBytes());
        out.write("@data\n".getBytes());
        for (File f : file) {
            if (f.isFile()&&!f.isHidden()) {
                String res="";
                BufferedReader reader = new BufferedReader(new FileReader(f));
                String str = reader.readLine();
                for (int k= 0; k < 32; k++) {
                    for (int i= 0; i < 32; i++) {
                        res+=str.charAt(i)+",";
                    }
                    str = reader.readLine();
                }
                res+=f.getName().charAt(0)+"\n";
                out.write(res.getBytes());
            }
        }
    }
}


算法执行

打开WEKA,将训练数据导入,并在Classify选择Function选择 SMO算法。选择交叉验证(Flods按照默认的为10即可)。

运行,得到结果如下。

[code]=== Stratified cross-validation ===
=== Summary ===

Correctly Classified Instances        1890               97.7249 %
Incorrectly Classified Instances        44                2.2751 %
Kappa statistic                          0.9747
Mean absolute error                      0.1602
Root mean squared error                  0.2721
Relative absolute error                 88.9941 %
Root relative squared error             90.7025 %
Coverage of cases (0.95 level)         100      %
Mean rel. region size (0.95 level)      80.3619 %
Total Number of Instances             1934     

=== Detailed Accuracy By Class ===

                 TP Rate  FP Rate  Precision  Recall   F-Measure  MCC      ROC Area  PRC Area  Class
                 0.989    0.000    1.000      0.989    0.995      0.994    0.999     0.994     0
                 0.980    0.008    0.933      0.980    0.956      0.951    0.990     0.936     1
                 0.990    0.001    0.995      0.990    0.992      0.991    1.000     0.998     2
                 0.990    0.002    0.985      0.990    0.987      0.986    0.997     0.978     3
                 0.978    0.003    0.968      0.978    0.973      0.970    0.998     0.970     4
                 0.968    0.002    0.978      0.968    0.973      0.970    0.997     0.972     5
                 0.990    0.001    0.990      0.990    0.990      0.989    0.999     0.985     6
                 0.985    0.003    0.975      0.985    0.980      0.978    0.999     0.983     7
                 0.950    0.002    0.977      0.950    0.963      0.960    0.992     0.941     8
                 0.951    0.003    0.975      0.951    0.963      0.959    0.990     0.942     9
Weighted Avg.    0.977    0.003    0.978      0.977    0.977      0.975    0.996     0.970     

=== Confusion Matrix ===

   a   b   c   d   e   f   g   h   i   j   <-- classified as
 187   0   0   0   1   0   1   0   0   0 |   a = 0
   0 194   0   0   0   0   0   1   2   1 |   b = 1
   0   1 193   0   0   0   0   0   1   0 |   c = 2
   0   0   0 197   0   1   0   1   0   0 |   d = 3
   0   2   0   0 182   0   1   0   0   1 |   e = 4
   0   1   1   1   1 181   0   0   1   1 |   f = 5
   0   2   0   0   0   0 193   0   0   0 |   g = 6
   0   0   0   0   1   0   0 198   0   2 |   h = 7
   0   6   0   0   1   2   0   0 171   0 |   i = 8
   0   2   0   2   2   1   0   3   0 194 |   j = 9


使用测试数据测试模型好坏

(1)核函数选择为多项式核函数

用我们的测试数据再进行下测试。通过交叉验证得到的模型测试数据表明正确率为 98.5201 %。

[code]=== Re-evaluation on test set ===

User supplied test set
Relation:     testKNN_predicted_predicted
Instances:     unknown (yet). Reading incrementally
Attributes:   1025

=== Summary ===

Correctly Classified Instances         932               98.5201 %
Incorrectly Classified Instances        14                1.4799 %
Kappa statistic                          0.9835
Mean absolute error                      0.1601
Root mean squared error                  0.272 
Coverage of cases (0.95 level)         100      %
Total Number of Instances              946


(2)核函数选择RBF函数(高斯核函数)

相对上一个,这个函数执行时间更久。但结果好了1%左右达到 98.9429 %。

与KNN算法实验结果对比

交叉验证得到的结果正确率为97.4147 %,用测试数据测试正确率98.6258 %,结果与SMO算法差不多。但是用SMO预测效果更好,因为KNN算法得不到模型,但SMO算法可以。

参考资料

李航,《统计学习方法》,清华大学出版社

Peter,《机器学习实战》

WEKA开发手册
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: