哈!,看到这个名字就知道这篇文章不会讲太多原理的了
网上有各种关于大侠拍桌救其爱人的故事解释了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)