sklearn中SVM与AdaBoost对手写体数字进行识别
来源:互联网 发布:java中的注解怎么用 编辑:程序博客网 时间:2024/06/16 05:40
最近比较忙,自从写了第一篇博客之后,好久没写博客。最近自己捣鼓了一下基于SVM与AdaBoost的手写体数字识别,和大家分享一下这个过程吧。
首先,数据集的准备,选用的是比较有名的MINIST数据集(数据集可以在这个地方下载点击打开链接,其实,在学习过程中,要用到的大部分数据集在这个地方都可以下载到的)。
然后,要做的第一件事就是将要用到的包导入:
import numpy as npimport pandas as pdfrom sklearn import svmimport matplotlib.colorsimport matplotlib.pyplot as pltfrom sklearn.metrics import accuracy_scorefrom sklearn.model_selection import GridSearchCVfrom time import timefrom sklearn.ensemble import AdaBoostClassifierfrom sklearn.linear_model import LogisticRegressionfrom sklearn.tree import DecisionTreeClassifier接下来,我们将准备好的数据集导入,并对训练集和测试集的输入输出进行划分,这个地方我分别采用了pandas.read_csv和numpy.loadtxt这两种方法来导入数据集:
data = pd.read_csv('optdigits.tra', header=None)#使用pandas载入训练样本 x, y = data[range(64)].values, data[64].values#划分训练集的输入与输出 images_tra = x.reshape(-1, 8, 8)#其实每一个8x8的小矩阵表示一个数字,为下面将错误样本画出做准备 y_tra = y.ravel().astype(np.int)#将数组变为1维数组 #load test dataset datatest = np.loadtxt('optdigits.tes',dtype=np.float, delimiter=',')#其实这个地方也可以采用pandas读入数据 x_test, y_test = np.split(datatest, (-1,), axis=1)#划分测试样本集的输入与输出 print y_test.shape images_tes = x_test.reshape(-1, 8, 8)#同上 y_test = y_test.ravel().astype(np.int) print images_tes.shape在接下来,我们先用svm算法来对手写体数字进行识别:
model = svm.SVC(C=10.0, kernel='rbf', gamma=0.001)#设置模型参数tt1 = time() model.fit(x, y_tra)#训练模型 tt2 = time() delta_tt = tt2 - tt1 print 'SVMxun训练模型耗时:%d分%.3f秒' % ((int)(delta_tt / 60), delta_tt - 60*((int)(delta_tt/60))) y_hat = model.predict(x_test)#做预测 print 'SVC训练集准确率:', accuracy_score(y_tra, model.predict(x)) print 'SVC测试集准确率:', accuracy_score(y_test, y_hat) print y_test print y_hat num = [] tmp = [] for index in range(len(y_test)): if (y_test[index] != y_hat[index]):#打印出模型分类的测试样本对应的真实值与模型预测的实际值,以及对应的index print y_test[index], y_hat[index], index tmp.append(index)#将错误的index记录下来 num.append(y_test[index])#将这些错误预测结果对应的正确数字保存下来 print '*************************' # print tmp # print num
在识别的过程中,我将测试集中,识别错误的样本下标以及它所对应的正确数字值分别用num数组和tmp数组进行了保存进行了保存。在svm模型参数的设置上,我主要考虑了C,kernel和gamma这三个参数。C:C-SVC的惩罚参数C,默认值是1.0。C越大,相当于惩罚松弛变量,希望松弛变量接近0,即对误分类的惩罚增大,趋向于对训练集全分对的情
况,这样对训练集测试时准确率很高,但泛化能力弱。C值小,对误分类的惩罚减小,允许容错,将他们当成噪声点,泛化能力较强。
kernel :核函数,默认是rbf,可以是‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’
0 – 线性:u'v
1 – 多项式:(gamma*u'*v + coef0)^degree
2 – RBF函数:exp(-gamma|u-v|^2)
3 –sigmoid:tanh(gamma*u'*v + coef0)
我这里就选用了'rbf'核函数,其他的核函数可以自己尝试一下。
gamma : ‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’,则会选择1/n_features
之后,我又采用了AdaBoost算法进行了训练和识别。AdaBoost是一种迭代算法,它有两种形式分别为AdaBoostClassifier和AdaBoostRegressor。
它的核心思想是针对一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。
在实际的模型参数设置过程中,我们要设置的参数包括:
base_estimator:AdaBoostClassifier和AdaBoostRegressor都有,即我们的弱分类学习器或者弱回归学习器。理论上可以选择任何一个分类
或者回归学习器,不过需要支持样本权重。我们常用的一般是CART决策树或者神经网络MLP。默认是决策树,即AdaBoostClassifier默认使用CART分
类树DecisionTreeClassifier,而AdaBoostRegressor默认使用CART回归树DecisionTreeRegressor。另外有一个要注意的点是,如果我们选择的
AdaBoostClassifier算法是SAMME.R,则我们的弱分类学习器还需要支持概率预测,也就是在scikit-learn中弱分类学习器对应的预测方法除了predict
还需要有predict_proba。
algorithm:这个参数只有AdaBoostClassifier有。主要原因是scikit-learn实现了两种Adaboost分类算法,SAMME和SAMME.R。两者的主要
区别是弱学习器权重的度量,SAMME使用了和我们的原理篇里二元分类Adaboost算法的扩展,即用对样本集分类效果作为弱学习器权重,而SAMME.R
使用了对样本集分类的预测概率大小来作为弱学习器权重。由于SAMME.R使用了概率度量的连续值,迭代一般比SAMME快,因此AdaBoostClassifier
的默认算法algorithm的值也是SAMME.R。我们一般使用默认的SAMME.R就够了,但是要注意的是使用了SAMME.R, 则弱分类学习器参数
base_estimator必须限制使用支持概率预测的分类器。SAMME算法则没有这个限制。
loss:这个参数只有AdaBoostRegressor有,Adaboost.R2算法需要用到。有线性‘linear’, 平方‘square’和指数 ‘exponential’三种选择, 默认
是线性,一般使用线性就足够了,除非你怀疑这个参数导致拟合程度不好。
n_estimators: AdaBoostClassifier和AdaBoostRegressor都有,就是我们的弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般
来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。默认是50。在实际调参的过程中,我们常常将
n_estimators和下面介绍的参数learning_rate一起考虑。
learning_rate: AdaBoostClassifier和AdaBoostRegressor都有,即每个弱学习器的权重缩减系数
ν ν,在原理篇的正则化章节我们也讲到了,加上了正则化项,我们的强学习器的迭代公式为
fk(x)=fk−1(x)+ναkGk(x) fk(x)=fk−1(x)+ναkGk(x)。ν ν的取值范围为
0<ν≤1 0<ν≤1。对于同样的训练集拟合效果,较小的ν ν意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。所以这两个参数n_estimators和learning_rate要一起调参。一般来说,可以从一个小一点的
ν ν开始调参,默认是1。在训练过程中,对于AdaBoost中的弱分类器,我这里分别选择了DT和LR。首先来看一下选择DT的情况:
clf = AdaBoostClassifier(DecisionTreeClassifier(max_depth=5, min_samples_split=5, min_samples_leaf=5), n_estimators=200, learning_rate=0.05, algorithm='SAMME.R') t1 = time() clf.fit(x, y_tra) t2 = time() t = t2 - t1 print 'AdaBoost-DT训练模型耗时:%d分%.3f秒' % ((int)(t/60), t-60*(int)(t/60)) y_hat1 = clf.predict(x_test) print 'AdaBoost-DT训练集准确率:', accuracy_score(y_tra, clf.predict(x)) print 'AdaBoost-DT测试集准确率:', accuracy_score(y_test, y_hat1) print '*************************'在决策树参数的选择上,决策树最大深度max_depth我选取5,内部节点再划分所需最小样本数min_samples_split我选取5,叶子节点最少样本数min_samples_leaf我选在5,其他参数我采用默认值。对于这些参数,我个人觉得,如果给的太大,那么必然会产生过拟合的情况,如果给的太小,
那么就会产生欠你和的情况。
再来看一下选用逻辑回归的情况:
clf1 = AdaBoostClassifier(LogisticRegression(penalty='l2'), n_estimators=200, learning_rate=0.05, algorithm='SAMME', random_state=None) t2 = time() clf1.fit(x, y_tra) t3 = time() delta_t = t3 - t2 y_hat2 = clf1.predict(x_test) print 'AdaBoost-LR训练集准确率:', accuracy_score(y_tra, clf1.predict(x)) print 'AdaBoost-LR测试集准确率:', accuracy_score(y_test, y_hat2) print 'AdaBoost-LR训练模型耗时:%d分%.3f秒' % ((int)(delta_t/60), delta_t-60*(int)(delta_t/60))这里,在LR参数的选择上,我主要就改了penalty这个参数,具体为啥改成这个参数,我也没有具体的理论依据,只是自己尝试着玩一下的。。。最后,我们来看一下模型的识别效果:
从模型的表现上来看,SVM有着更好的表现。
代码和数据集我已经上传,可以在这个地方进行下载点击打开链接
大家一起学习,欢迎批评指正。
- sklearn中SVM与AdaBoost对手写体数字进行识别
- (二)用 svm 识别手写体数字图片
- 【机器学习 sklearn】手写数字识别 SVM
- TensorFlow学习笔记(1):使用softmax对手写体数字(MNIST数据集)进行识别
- OpenCV实现手写体数字训练与识别
- 手写体数字识别例子
- KNN识别手写体数字
- SVM对sklearn自带手写数字数据集进行分类
- svm+hog的手写体识别
- 【SVM理论到实践4】基于OpenCv中的SVM的手写体数字识别
- 使用支持向量机(分类)对手写体数字图像进行识别
- 基于OpenCV实现手写体数字训练与识别
- 简单手写体数字识别系统
- 简单手写体数字识别系统
- 初识Kaggle:手写体数字识别
- python利用SVM做手写体识别
- (链接) AdaBoost中利用Haar特征进行人脸识别算法分析与总结
- AdaBoost中利用Haar特征进行人脸识别算法分析与总结(转载)
- Android如何使用Https
- Spark---JVM调优之调节executor离堆内存与连接等待时长
- Javascript——脚本基础
- Spark开发-WordCount详细讲解
- 基于keras的深度学习基本概念讲解
- sklearn中SVM与AdaBoost对手写体数字进行识别
- 51 nod 1503 猪和回文(双线程DP)
- JAVA关键字
- 什么样的音视频SDK才算是真正的音视频开发
- 每周一本书之《深度学习算法实践》:让你一站式了解深度学习算法
- 前端学习,问题汇总
- 网页 视频作为背景(解决google浏览器无法访问本地资源的问题)
- Android三级目录、ListView单选/GridView单选、ListView多选/GridView多选
- android studio导入eclipse项目报错 Error: Some file crunching failed, see logs for details