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

  • 感知机
  • 支持向量机理论
    • 线性可分支持向量机
    • 线性支持向量机
    • 非线性支持向量机
      • 常见核函数
      • SMO算法
  • 支持向量机的应用手写识别系统
    • 应用背景
    • 工具选择
    • 转换样本数据
      • 将txt文本转换为arff文件
      • 算法执行
      • 使用测试数据测试模型好坏
      • 与KNN算法实验结果对比
  • 参考资料

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

感知机

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

给定一个训练数据集
         T={(x1,y1),(x2,y2),...,(xN,yN)}
其中 xi 是输入空间, yi 是类别。求参数 w,b ,使得损失函数极小化问题的求解
       minw,bL(w,b)=xiM(wxi+b)
其中M是误分类点的集合。

具体采用随机梯度下降算法求解(不适用批量下降算法的原因是:批量下降算法会慢,虽然其选取的梯度都是最“抖”的那个,但是真正要效率更好的话,还是随机下降更高)。
感知机问题的最后求解,会得到一个分离超平面,会将两类分成两部分。这样的分离超平面是有无穷多个的。但是哪个分离超平面更好?如何找到一个更好的分离超平面?这就是支持向量机的问题了。

支持向量机理论

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

线性可分支持向量机

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

minw,b12||w||2
s.t yi(wxi+b)10,i=1,2,...,N

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

线性支持向量机

实际情况中,训练数据集往往并不是线性可分的,因为存在着噪声以及特异点。当然,我们可以先去除掉噪声数据再进行线性可分的操作,但是如何判断噪声数据实际上是很麻烦的事。那么就推广到了更一般的情况—-线性支持向量机。
上面线性可分支持向量机的间隔是硬间隔最大化,现在这种情况下,应当是软间隔最大化。
为了解决这个问题需要引入松弛变量的概念(在线性规划问题中,单纯形算法也引入了松弛变量,其实道理是类似的)。
多的不叙述了,很多参考书上有具体的证明过程,给出问题。

minw,b12||w||2+CNi=1ε
s.t yi(wxi+b)1+ε0,i=1,2,...,N
其中 ε 是松弛变量。

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

非线性支持向量机

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

常见核函数

(1)多项式核函数

K(x,z)=(xz+1)p

(2)高斯核函数

K(x,z)=exp(||xz||22σ2)

当然可以自定义核函数,但是需要满足下面条件:
自定义的核函数应该是正定的。其充要条件:

K:χ×χR 是对称函数,则 K(x,z) 为正定核函数的充要条件是对任意 xiχ,i=1,2,...,m , K(x,z) 对应的Gram矩阵 K=[K(xi,xj)]m×n 是半正定矩阵。 ———–李航《统计学习方法》

SMO算法

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

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

应用背景

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

工具选择

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

转换样本数据

将txt文本转换为arff文件

所有的文件(包括转换后的数据可下载,点击可下载)
原来的txt数据截图如下。
[机器学习]支持向量机及其应用---手写识别系统(SMO算法)_第1张图片
将其WEKA可以处理的格式,这个数据是32×32的数据,一共1024个数据。我将其转换成了1024个属性。并且是数字型。一共有2000多个训练样本,编写JAVA程序处理得到arff格式文件。JAVA代码参考如下。

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即可)。
运行,得到结果如下。

=== 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 %。

=== 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开发手册

你可能感兴趣的:(算法,机器学习,SVM,smo,手写数字)