svm手写数字识别python_SVM之Mnist手写数字识别

哈!,看到这个名字就知道这篇文章不会讲太多原理的了

网上有各种关于大侠拍桌救其爱人的故事解释了SVM原理,这里我就不过多阐述了

还是给个链接:

两个链接相辅相成

一个解释直观原理(几何图形层面),一个解释抽象原理(数学公式层面)。

数学皆是如此,比如学初学线性代数时,大家都会感叹这都tm是些啥玩意儿?学这东西有啥用呀?为什么会有矩阵这种恶心的东西呀?

当大家慢慢深入了解其几何原理后(直观理解的一种),然后大家就会感叹这tm太神奇的吧,为什么矩阵这么优秀呀?当初为什么不好好学线代呀?

亦如支持向量机(SVM),大家要是一开始就看抽象原理的话,一堆堆数学公式,一堆堆什么高斯核函数什么的,头都能看晕。所以大家先要知道某个东西大概是个什么玩意儿,再去细细为什么是这么个玩意儿。

打住我的胡扯,然后进入下一段胡扯

如何让一个程序识别数字呢:我们可以写一个程序,让程序随机地猜。可想而知,正确率只有10%左右

改进一下,不瞎几把猜,而通过强大无比地数学计算。我们先计算图像的明暗度,然后比较得到它更接近哪个数字的明暗度。这相对随机猜有了很大的改进,但其结果却不尽人意,仅22%左右的准确率。

怎样能达到50%以上的准确率呢?机器学习里面的很多算法就能做到,如SVM

究极版本就是目前最火的什么CNN卷积神经网络,那个神经网络这个神经网络啦

不过今天要说的是SVM——————的调用(理不直气也壮.png)

如果你深刻了解原理之后,难不成还自己造轮子?

人生三大错觉之一——我超越了标准库

当然,SVM也不是什么标准库啦

今天要用的是sklearn下的SVM工具

今天要用的数据也是sklearn下的自带手写数字的数据

首先导包:

import numpy as np

from sklearn import svm

from sklearn.datasets import load_digits

from sklearn.model_selection import train_test_split

导入numpy就不说了,老伙伴了

第二行也不说了,一看就懂...

第三行嘛,运行load_digits函数可以导入今天我们要用到的数据

第四行,train_test_split函数可以随机划分训练集和测试集

好了,接下来导入数据:

mnist = load_digits()

x,test_x,y,test_y = train_test_split(mnist.data,mnist.target,test_size=0.25,random_state=40)

test_size即测试集所占总数据的比例

random_state是随机数的初始种子(不懂这句话意思的可以去补习一下计算机随机数产生等知识)

scikit-learn的SVM中有三种分类器SVC

NuSVC

LinearSVC

SVC和NuSVC的区别不大,区别是它俩对损失的度量方式不同

LinearSVC如其名字,核函数只能时线性核函数

由于三个分类器的参数各不相同,所以我就只讲几个重要的参数了C 惩罚参数,默认1.0。NuSVC没有这个参数项,因为其通过另一个参数nu来控制训练集训练的错误率

kernel核函数默认rbf,当然你也可以把它设置为'linear', 'poly', 'rbf', 'sigmoid', 'precomputed' ,要注意的是,LinearSVC不能设置核函数,其默认是'linear'

gamma'poly', 'rbf', 'sigmoid'核函数的参数。默认会根据数据特征自动选择

degree当核函数为'poly'时生效,即poly函数的维度,默认为3

coef0'poly', 'sigmoid'核函数的常数项

因为这篇是讲使用,那就不考虑什么精度什么的了,什么又快又方便则用哪个,且全部用默认参数

model = svm.LinearSVC()

通过数据训练模型:

model.fit(x, y)

将训练好的模型进行预测并打印下准确度:

z = model.predict(test_x)

print('准确率:',np.sum(z==test_y)/z.size)

最终运行得到此模型的准确度为:93.33%

代码中用到的数据是sklearn自带的手写图片数据,总共1797张8x8的图片

本人用同样的LinearSVC分类器的默认参数训练过mnist的50000张28x28的图片,得到最终的准确度为89%左右

用同样的SVC分类器的默认参数训练mnist的50000张28x28的图片得到94.35%的准确度

已经很不错了,但上面的分类器使用的都是默认参数,也有某些大神好好调整参数,使得精确度达到98.56%!

这种古老算法也能达到如此精度,已经很不错了

给你们看看数据集里面某些人类都识别不出的数据你就懂了

最后还是老话题,模型的保存

这次模型的保存很容易,使用python的pickle类即可,将上面的分类器类进行序列化

import _pickle as pickle

...

with open('./model.pkl','wb') as file:

pickle.dump(model,file)

模型的恢复,亦很容易

import _pickle as pickle

with open('./model.pkl','rb') as file:

model = pickle.load(file)

然后就可以调用model.predict进行预测了

最后附上全部代码:

import numpy as np

from sklearn import svm

from sklearn.datasets import load_digits

from sklearn.model_selection import train_test_split

import _pickle as pickle

if __name__ == '__main__':

mnist = load_digits()

x,test_x,y,test_y = train_test_split(mnist.data,mnist.target,test_size=0.25,random_state=40)

model = svm.LinearSVC()

model.fit(x, y)

z = model.predict(test_x)

print('准确率:',np.sum(z==test_y)/z.size)

with open('./model.pkl','wb') as file:

pickle.dump(model,file)

你可能感兴趣的:(svm手写数字识别python)