实战2-手写数字识别

介绍了用LR,Random Forest,KNN,SVM,神经网络来实现预测,并做了几种方法的比较。

KNN

sklearn.neighbors.
KNeighborsClassifier
(*n_neighbors=5*, *weights='uniform'*, *algorithm='auto'*, *leaf_size=30*, *p=2*, *metric='minkowski'*, *metric_params=None*, *n_jobs=1*, ***kwargs*)

需要选择的参数:

  • n_neighbors (即K)
  • weights (K大的时候可以选distance降低权重)
  • algorithm (只影响预测时间,不影响精度)
  • p (p=2时是欧拉距离,p=1就是曼哈顿距离)

疑问

  • 没有把图像二值化?

完整代码:
KNN_choosePara.py

# -*- coding: UTF-8 -*-

import pandas as pd
import numpy as np
import time
from sklearn.cross_validation import cross_val_score
from sklearn.neighbors import KNeighborsClassifier



#read data
print "reading data"
dataset = pd.read_csv("../train.csv")
X_train = dataset.values[0:, 1:]
y_train = dataset.values[0:, 0]


#for fast evaluation
X_train_small = X_train[:10000, :]
y_train_small = y_train[:10000]


X_test = pd.read_csv("../test.csv").values


#knn
#-----------------------用于小范围测试选择最佳参数-----------------------------#
#begin time
start = time.clock()

#progressing
print "selecting best paramater range"
knn_clf=KNeighborsClassifier(n_neighbors=5, algorithm='kd_tree', weights='distance', p=3)
score = cross_val_score(knn_clf, X_train_small, y_train_small, cv=3)

print( score.mean() )
#end time
elapsed = (time.clock() - start)
print("Time used:",int(elapsed), "s")

#k=3
#0.942300738697
#0.946100822903 weights='distance'
#0.950799888775 p=3
#k=5
#0.939899237556
#0.94259888029
#k=7
#0.935395994386
#0.938997377902
#k=9
#0.933897851978

KNN_predict.py:

# -*- coding: UTF-8 -*-
from KNN.KNN_choosePara import *

clf=KNeighborsClassifier(n_neighbors=5, algorithm='kd_tree', weights='distance', p=3)

start=time.clock()



#read data
print "reading data"
dataset = pd.read_csv("train.csv")
clf.fit(X_train,y_train) #针对整个训练集训练分类器
elapsed = (time.clock() - start)
print("Training Time used:",int(elapsed/60) , "min")



print "predicting"
result=clf.predict(X_test)
result=np.c_[range(1,len(result)+1),result.astype(int)] #转化为int格式生成一列
df_result=pd.DataFrame(result,columns=['ImageID','Label'])

df_result.to_csv('./results.knn.csv',index=False)

#end time
elapsed = (time.clock() - start)
print("Test Time used:",int(elapsed/60) , "min")

# choosing parameters
# 0.947298365455 score
# ('Time used:', 983, 's')
# reading data
# ('Training Time used:', 0, 'min')
# predicting
# ('Test Time used:', 244, 'min')
# 0.97214 final score

</br></br>

LR

sklearn.model_selection.GridSearchCV
(estimator, param_grid, scoring=None, fit_params=None, n_jobs=1, 
iid=True, refit=True, cv=None, verbose=0, pre_dispatch='2*n_jobs', 
error_score='raise', return_train_score=True)

需要选择的参数:

  • estimator : lr_clf
  • param_grid : 参数列表,字典格式
  • n_jobs :并行计算数?

完整代码:
LR_choosePara:

# -*- coding: UTF-8 -*-
from KNN.KNN_choosePara import *
import pandas as pd
import numpy as np
import time
from sklearn.linear_model import  LogisticRegression
from sklearn.grid_search import GridSearchCV

start=time.clock()

lr_clf=LogisticRegression(solver='newton-cg',multi_class='ovr',max_iter=100,C=1)


# 用GridSearchCV寻找最佳参数空间
parameters={'penalty:':['12'],'C':[2e-2, 4e-2,8e-2, 12e-2, 2e-1]} #dict格式的参数列表
gs_clf=GridSearchCV(lr_clf,parameters,n_jobs=1,verbose=True) #estimator, fit_params, n_jobs,
gs_clf.fit(X_train_small.astype('float')/256,y_train_small)


#打印最佳参数空间结果
print()
for params, mean_score, scores in gs_clf.grid_scores_:
    print "%0.3f (+/-%0.03f) for %r"  % (mean_score, scores.std() * 2, params)
print()

elapsed=(time.clock()-start)
print "time used:",elapsed

</br></br>

SVM

SVC和NuSVC的区别:
NuSVC是核支持向量分类,和SVC类似,但不同的是通过一个参数空值支持向量的个数。

SVM_choosePara.py

# -*- coding: UTF-8 -*-
from KNN.KNN_choosePara import *
import pandas as pd
import numpy as np
import time
from sklearn.svm import SVC, NuSVC
from sklearn.grid_search import GridSearchCV

start=time.clock()

#classificator
svm_clf=NuSVC(nu='0.1',kernel='rbf',gamma=0.1,verbose=True)

#choose the parameters
parameters=[{'nu':[0.05,0.02],'gamma':[3e-2, 2e-2, 1e-2]}]
gs_clf=GridSearchCV(svm_clf,parameters,n_jobs=1,verbose=True)
gs_clf.fit(X_train_small.astype('float')/256,y_train_small)

print()
for params,mean_score, scores in gs_clf.grid_scores_:
    print("%0.3f (+/-%0.03f) for %r" % (mean_score, scores.std() * 2, params))
print()

elapsed=time.clock()-start
print("Time used:",elapsed)

SVM_predict.py

# -*- coding: UTF-8 -*-
import time
import numpy as np
import pandas as pd
from sklearn.svm import SVC, NuSVC

svm_clf=NuSVC(nu=0.2,kernel='rbf',gamma=0.2,verbose=True)

start=time.clock()



#read data
print "reading data"
dataset = pd.read_csv("../train.csv")
X_train = dataset.values[0:, 1:]
y_train = dataset.values[0:, 0]
svm_clf.fit(X_train,y_train) #针对整个训练集训练分类器
elapsed = (time.clock() - start)
print("Training Time used:",int(elapsed/60) , "min")



print "predicting"
X_test = pd.read_csv("../test.csv").values
result=svm_clf.predict(X_test)
result=np.c_[range(1,len(result)+1),result.astype(int)] #转化为int格式生成一列
df_result=pd.DataFrame(result,columns=['ImageID','Label'])

df_result.to_csv('./results.svm.csv',index=False)

#end time
elapsed = (time.clock() - start)
print("Test Time used:",int(elapsed/60) , "min")


# optimization finished, #iter = 16982
# C = 49.988524
# obj = 4126.039937, rho = 0.015150
# nSV = 8251, nBSV = 0
#
# Total nSV = 42000
# ('Training Time used:', 175, 'min')
# predicting
# ('Test Time used:', 201, 'min')


#0.11614

不知道为什么,测试选参数的时候得分还是蛮高的,预测就只有0.1,还需要在看看。

</br></br>

Random forest

随机森林,因为之前几个算法跑起来都需要一个小时以上,随机森林选参+测试用了不到十分钟,将信将疑的把结果上传kaggle,得分居然也很高, 先上代码,之后再分析。

RF_choosePara.py

# -*- coding: UTF-8 -*-
from sklearn.ensemble import RandomForestClassifier
import time
import numpy as np
from sklearn.grid_search import GridSearchCV
import pandas as pd



#begin time
start = time.clock()


#reading data
print "reading data"
dataset = pd.read_csv("../train.csv")
X_train = dataset.values[0:, 1:]
y_train = dataset.values[0:, 0]

#for fast evaluation
X_train_small = X_train[:10000, :]
y_train_small = y_train[:10000]

elapsed = (time.clock() - start)


#progressing
parameters = {'criterion':['gini','entropy'] , 'max_features':['auto', 12, 100]}

rf_clf=RandomForestClassifier(n_estimators=400, n_jobs=4, verbose=1)
gs_clf =  GridSearchCV(rf_clf, parameters, n_jobs=1, verbose=True )

gs_clf.fit( X_train_small.astype('int'), y_train_small )

print()
for params, mean_score, scores in gs_clf.grid_scores_:
    print("%0.3f (+/-%0.03f) for %r"  % (mean_score, scores.std() * 2, params))
print()
#end time
elapsed = (time.clock() - start)
print("Time used:",elapsed) #seconds


# 0.946 (+/-0.003) for {'max_features': 'auto', 'criterion': 'gini'}
# 0.947 (+/-0.001) for {'max_features': 12, 'criterion': 'gini'}
# 0.944 (+/-0.004) for {'max_features': 100, 'criterion': 'gini'}
# 0.945 (+/-0.004) for {'max_features': 'auto', 'criterion': 'entropy'}
# 0.946 (+/-0.003) for {'max_features': 12, 'criterion': 'entropy'}
# 0.941 (+/-0.004) for {'max_features': 100, 'criterion': 'entropy'}
# ()
# ('Time used:', 814.006147)

RF_predict.py

# -*- coding: UTF-8 -*-
import time
import numpy as np
from sklearn.ensemble import RandomForestClassifier
import pandas as pd

clf=RandomForestClassifier(n_estimators=12)

start=time.clock()

#read data
print "reading data"
dataset = pd.read_csv("../train.csv")
X_train = dataset.values[0:, 1:]
y_train = dataset.values[0:, 0]

print "fitting the model"
clf.fit(X_train,y_train) #针对整个训练集训练分类器
elapsed = (time.clock() - start)
print("Training Time used:",int(elapsed/60) , "min")

#predicting data
print "predicting"
X_test = pd.read_csv("../test.csv").values
result=clf.predict(X_test)
result=np.c_[range(1,len(result)+1),result.astype(int)] #转化为int格式生成一列
df_result=pd.DataFrame(result,columns=['ImageID','Label'])

df_result.to_csv('./results.rf.csv',index=False)

#end time
elapsed = (time.clock() - start)
print("Test Time used:",int(elapsed/60) , "min")


# reading data
# fitting the model
# ('Training Time used:', 0, 'min')
# predicting
# ('Test Time used:', 0, 'min')
#0.94629

随机森林属于集成学习的方法。
随机森林由LeoBreiman(2001)提出,它通过自助法(bootstrap)重采样技术,从原始训练样本集N中有放回地重复随机抽取k个样本生成新的训练样本集合,然后根据自助样本集生成k个分类树组成随机森林,新数据的分类结果按分类树投票多少形成的分数而定。其实质是对决策树算法的一种改进,将多个决策树合并在一起,每棵树的建立依赖于一个独立抽取的样品,森林中的每棵树具有相同的分布,分类误差取决于每一棵树的分类能力和它们之间的相关性。特征选择采用随机的方法去分裂每一个节点,然后比较不同情况下产生的误差。能够检测到的内在估计误差、分类能力和相关性决定选择特征的数目。单棵树的分类能力可能很小,但在随机产生大量的决策树后,一个测试样品可以通过每一棵树的分类结果经统计后选择最可能的分类

随机森林优点
a. 在数据集上表现良好,两个随机性的引入,使得随机森林不容易陷入过拟合
b. 在当前的很多数据集上,相对其他算法有着很大的优势,两个随机性的引入,使得随机森林具有很好的抗噪声能力
c. 它能够处理很高维度(feature很多)的数据,并且不用做特征选择,对数据集的适应能力强:既能处理离散型数据,也能处理连续型数据,数据集无需规范化
d. 可生成一个Proximities=(pij)矩阵,用于度量样本之间的相似性: pij=aij/N, aij表示样本i和j出现在随机森林中同一个叶子结点的次数,N随机森林中树的颗数
e. 在创建随机森林的时候,对generlization error使用的是无偏估计
f. 训练速度快,可以得到变量重要性排序(两种:基于OOB误分率的增加量和基于分裂时的GINI下降量
g. 在训练过程中,能够检测到feature间的互相影响
h. 容易做成并行化方法
i. 实现比较简单

</br>

score.png

LR线性模型显然最弱。神经网络处理这种图像问题确实目前是最强的。svm的support vector在这里起到作用非常明显,准确地找出了最具区分度的“特征图像”。RF有点像非线性问题的万金油,这里默认参数已经很可以了。只比KNN结果稍微差一点,因为只用了像素的局部信息。当然了,模型的对比这里只针对数字识别的问题,对于其他问题可能有不同的结果,要具体问题具体分析,结合模型特点,选取合适的模型。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • 机器学习是做NLP和计算机视觉这类应用算法的基础,虽然现在深度学习模型大行其道,但是懂一些传统算法的原理和它们之间...
    在河之简阅读 20,488评论 4 65
  • 注:题中所指的『机器学习』不包括『深度学习』。本篇文章以理论推导为主,不涉及代码实现。 前些日子定下了未来三年左右...
    我偏笑_NSNirvana阅读 39,936评论 12 145
  • ML & DM 集成学习 模型融合 ensemble http://wakemeup.space/?p=109 E...
    章鱼哥呀阅读 1,798评论 0 6
  • 这里总结了常见的几个机器学习算法:朴素贝叶斯、决策树、逻辑回归、线性回归、KNN、SVM、Boosting、聚类、...
    xzhren阅读 900评论 0 6
  • 一个人的时候好像太久了。 一个人做饭,一个人吃饭,饭厅里一直用的是同一把椅子,对面的那把都落了灰尘,却从来没有用过...
    三宫主阅读 176评论 0 1