Python利用sklearn库进行手写体识别。Python利用sklearn库进行手写体识别。

0.引言

0.引言

   介绍了动用sklearn的几乎独机器上型进行手写体识别。 

   介绍了使sklearn的几乎单机械上型进行手写体识别。 

 

 

1.开支环境

1.开销条件

  python:  3.6.3

  python:  3.6.3

  PIL,cv2, pandas, numpy, os, csv, random

  PIL,cv2, pandas, numpy, os, csv, random

  需要调用的sklearn库:

  需要调用的sklearn库:

1 from sklearn.linear_model import LogisticRegression     #线性模型中的Logistic回归模型
2 from sklearn.linear_model import SGDClassifier          #线性模型中的随机梯度下降模型
3 from sklearn.svm import LinearSVC                       #SVM模型中的线性SVC模型
4 from sklearn.neural_network import MLPClassifier        #神经网络模型中的多层网络模型
1 from sklearn.linear_model import LogisticRegression     #线性模型中的Logistic回归模型
2 from sklearn.linear_model import SGDClassifier          #线性模型中的随机梯度下降模型
3 from sklearn.svm import LinearSVC                       #SVM模型中的线性SVC模型
4 from sklearn.neural_network import MLPClassifier        #神经网络模型中的多层网络模型

 

 

2.整体规划思路

2.整统筹思路

  图片 1

  图片 2

               图1 整体的框架设计

               图1 整体的框架设计

 

 

  工程的目的,是怀念使机械上型去训练识别生成的妄动验证码图像(单个数字1-9),通过以下三独步骤实现:

  工程的目的,是眷恋以机械上型去训练识别生成的任性验证码图像(单个数字1-9),通过以下三单步骤实现:

    1.生变成多摆单个验证码图像

    1.生变为多张单个验证码图像

    2.提取特征向量写副CSV

    2.提特征向量写副CSV

    3.sklearn模型训练以及测试

    3.sklearn模型训练和测试

   图片 3

   图片 4

                希冀2 整体的宏图流程

                贪图2 整体的计划性流程

 

 

3.编程过程

3.编程过程

  3.1 生成多张单个验证码图像

  3.1 生成多布置单个验证码图像

    图片 5               
  图片 6

    图片 7               
  图片 8

        祈求3 生成的差不多摆设单个验证码图像

        希冀3 生成的大多张单个验证码图像

 

 

    项目之第一步,是得转变单个手写体图像。

    项目之第一步,是索要扭转单个手写体图像。

    随机大成数字1-9,然后采用PIL的画笔工具进行打图,然后根据随便数的真标记1-9,保存到对应文件夹内,然后用标记+序号命名。重心在介绍机器上型的使用,验证码生成这里不再了多介绍。

    随机大成数字1-9,然后用PIL的画笔工具进行写生图,然后根据随便数的实标记1-9,保存至对应文件夹内,然后用标记+序号命名。重心在介绍机器上型的使,验证码生成这里不再了多介绍。

1 draw = ImageDraw.Draw(im)  # 画笔工具
1 draw = ImageDraw.Draw(im)  # 画笔工具

  

  

  **3.2 **提取特征向量写副CSV

  **3.2 **提取特征向量写副CSV

    这同一步是提图像被之特点。生成的么图像是30*30尽管900只像素点的。

    这同步是提图像中之表征。生成的么图像是30*30就900只像素点的。

    为了降低维度,没有选择900只像素点每点的灰度作为输入,而是挑了30尽每行的非法点往往,和30排列每列的不法点往往作为输入,这样降到了60维。

    为了降低维度,没有选择900只像素点每点的灰度作为输入,而是选择了30履每行的暗点往往,和30列每列的伪点往往作为输入,这样降到了60维。

    图片 9   

    图片 10   

            (a)提取900维特征

            (a)提取900维特征

   图片 11

   图片 12

             (b)提取60维特征

             (b)提取60维特征

             贪图4 提取图像特点

             图4 提取图像特点

特征的领也比较简单,逐行逐列计算然后计数求和:

特性的取也比较简单,逐行逐列计算然后计数求和:

 1     def get_feature(img):
 2         # 提取特征
 3         # 30*30的图像,
 4 
 5         width, height = img.size
 6 
 7         global pixel_cnt_list
 8         pixel_cnt_list=[]
 9 
10         height = 30
11         for y in range(height):
12             pixel_cnt_x = 0
13             for x in range(width):
14                 # print(img.getpixel((x,y)))
15                 if img.getpixel((x, y)) == 0:  # 黑点
16                     pixel_cnt_x += 1
17 
18             pixel_cnt_list.append(pixel_cnt_x)
19 
20         for x in range(width):
21             pixel_cnt_y = 0
22             for y in range(height):
23                 if img.getpixel((x, y)) == 0:  # 黑点
24                     pixel_cnt_y += 1
25 
26             pixel_cnt_list.append(pixel_cnt_y)
27 
28         return pixel_cnt_list
 1     def get_feature(img):
 2         # 提取特征
 3         # 30*30的图像,
 4 
 5         width, height = img.size
 6 
 7         global pixel_cnt_list
 8         pixel_cnt_list=[]
 9 
10         height = 30
11         for y in range(height):
12             pixel_cnt_x = 0
13             for x in range(width):
14                 # print(img.getpixel((x,y)))
15                 if img.getpixel((x, y)) == 0:  # 黑点
16                     pixel_cnt_x += 1
17 
18             pixel_cnt_list.append(pixel_cnt_x)
19 
20         for x in range(width):
21             pixel_cnt_y = 0
22             for y in range(height):
23                 if img.getpixel((x, y)) == 0:  # 黑点
24                     pixel_cnt_y += 1
25 
26             pixel_cnt_list.append(pixel_cnt_y)
27 
28         return pixel_cnt_list

    

    

    所以我们接下去要做的干活是,遍历访问之前放入single文件夹中子文件夹1-9中之具备图像文件,进行特征提取,然后形容副csv文件被:

    所以我们接下去需要开的干活是,遍历访问前放入single文件夹中子文件夹1-9中的装有图像文件,进行特征提取,然后形容副csv文件被:

 

 

 1 with open("D:/***/" + "***.csv", "w", newline="") as csvfile:
 2     writer = csv.writer(csvfile)
 3     # 访问文件夹 1-9
 4     for i in range(1, 10):
 5         namedir = os.listdir("D:/***/single/single_test/" + str(i))
 6         # 访问逐个图像文件
 7         for j in range(0, (len(namedir))):
 8             img = Image.open("D:/***/single/single_test/" + str(i) + "/" + namedir[j])
 9             get_feature(img)
10             
11             # 写入csv
12             pixel_cnt_list.append(namedir[j][0])
13             writer.writerow(pixel_cnt_list)
 1 with open("D:/***/" + "***.csv", "w", newline="") as csvfile:
 2     writer = csv.writer(csvfile)
 3     # 访问文件夹 1-9
 4     for i in range(1, 10):
 5         namedir = os.listdir("D:/***/single/single_test/" + str(i))
 6         # 访问逐个图像文件
 7         for j in range(0, (len(namedir))):
 8             img = Image.open("D:/***/single/single_test/" + str(i) + "/" + namedir[j])
 9             get_feature(img)
10             
11             # 写入csv
12             pixel_cnt_list.append(namedir[j][0])
13             writer.writerow(pixel_cnt_list)

   

   

  **3.3 sklearn模型训练和测试**

  **3.3 sklearn模型训练与测试**

    之前的备选干活且举行扫尾以后,就得使用sklearn的机上型进行建模处理。

    之前的备选干活还做扫尾以后,就足以运用sklearn的机械上型进行建模处理。

 

 

  3.3.1 特征数据加工

  3.3.1 特征数据加工

首先步要针对CSV文件中之多少开展提取,利用pd.read_csv进行读取。写副CSV时,前60列为60维的特征向量,第61名列输出标记1-9。  

第一步要对CSV文件中之数码开展提取,利用pd.read_csv进行读取。写副CSV时,前60名列60维的特征向量,第61名列输出标记1-9。  

 1 import pandas as pd
 2 from sklearn.model_selection import train_test_split
 3 
 4 # 设定的生成样本个数
 5 sample_num = 100
 6 
 7 column_names = []
 8 
 9 # 前60列为60维特征
10 for i in range(0, 60):
11     column_names.append("feature_"+str(i))
12 # 第61列为输出标记
13 column_names.append("true_number")
14 
15 data = pd.read_csv("D:/***/data/test_"+str(sample_num)+".csv"
16                    , names=column_names)
17 
18 # print(data.shape)
19 
20 # 得到训练集X—train和y_train,测试集X_test和y_test,此处取75%和25%分割
21 X_train, X_test, y_train, y_test = train_test_split(
22                                                       data[column_names[0:60]],
23                                                       data[column_names[60]],
24                                                       test_size=0.25,
25                                                       random_state=33
26                                                     )
 1 import pandas as pd
 2 from sklearn.model_selection import train_test_split
 3 
 4 # 设定的生成样本个数
 5 sample_num = 100
 6 
 7 column_names = []
 8 
 9 # 前60列为60维特征
10 for i in range(0, 60):
11     column_names.append("feature_"+str(i))
12 # 第61列为输出标记
13 column_names.append("true_number")
14 
15 data = pd.read_csv("D:/***/data/test_"+str(sample_num)+".csv"
16                    , names=column_names)
17 
18 # print(data.shape)
19 
20 # 得到训练集X—train和y_train,测试集X_test和y_test,此处取75%和25%分割
21 X_train, X_test, y_train, y_test = train_test_split(
22                                                       data[column_names[0:60]],
23                                                       data[column_names[60]],
24                                                       test_size=0.25,
25                                                       random_state=33
26                                                     )

  通过 data.shape()
可以落data的维度,此时出口结果(100,61),表示出100个样本,61单维度,其中60单维度时独自征值,第61只维度为出口标记值1-9。

  通过 data.shape()
可以赢得data的维度,此时出口结果(100,61),表示出100独样本,61独维度,其中60个维度时就征值,第61个维度为出口标记值1-9。

  利用sklearn库的 train_test_split函数 以数据开展划分,

  利用sklearn库的 train_test_split函数 用数据进行分割,

    得到训练集数据:X_train,
y_train

    得到训练集数据:X_train,
y_train

    得到测试集数据:X_test,
y_test

    得到测试集数据:X_test,
y_test

 

 

  3.3.2 模型训练

  3.3.2 模型训练

通过前一多重之备选工作举行扫尾,这里正式开动sklearn的机器上型,利用训练多少对范进行训练,然后运测试数据开展性能测试。

经前一名目繁多的备选干活做得了,这里正式开始运用sklearn的机上型,利用训练多少对范进行训练,然后采用测试数据进行性能测试。

  1 from sklearn.preprocessing import StandardScaler
  2 
  3 from sklearn.linear_model import LogisticRegression     #线性模型中的Logistic回归模型
  4 from sklearn.linear_model import SGDClassifier          #线性模型中的随机梯度下降模型
  5 from sklearn.svm import LinearSVC                       #SVM模型中的线性SVC模型
  6 from sklearn.neural_network import MLPClassifier        #神经网络模型中的多层网络模型
  7 
  8 # LR
  9 def con_lr():
 10 
 11     X_train_LR = X_train
 12     y_train_LR = y_train
 13 
 14     X_test_LR = X_test
 15     y_test_LR = y_test
 16 
 17     ss = StandardScaler()
 18     X_train_LR = ss.fit_transform(X_train_LR)
 19     X_test_LR = ss.transform(X_test_LR)
 20 
 21     # 初始化LogisticRegression
 22     lr = LogisticRegression()
 23 
 24     # 调用LogisticRegression中的fit()来训练模型参数
 25     lr.fit(X_train_LR, y_train_LR)
 26 
 27     # 使用训练好的模型lr对X_test进行预测,结果储存在lr_y_predict中
 28     global y_predict_LR
 29     y_predict_LR = lr.predict(X_test_LR)
 30 
 31     # 性能分析
 32     print('Accuarcy of LR Classifier2:', lr.score(X_test_LR, y_test_LR))
 33     print (classification_report(y_test_LR, y_predict_LR))
 34 
 35 #SGD
 36 def con_sgd():
 37 
 38     X_train_SC = X_train
 39     y_train_SC = y_train
 40 
 41     X_test_SC = X_test
 42     y_test_SC = y_test
 43 
 44     # 标准化数据
 45     ss = StandardScaler()
 46     X_train_SC = ss.fit_transform(X_train_SC)
 47     X_test_SC = ss.transform(X_test_SC)
 48 
 49     # 初始化SGDClassifier
 50     sgdc = SGDClassifier()
 51 
 52     # 调用SGDClassifier中的fit函数用来训练模型参数
 53     sgdc.fit(X_train_SC, y_train_SC)
 54 
 55     # 使用训练好的模型sgdc对X_test进行预测,结果储存在sgdc_y_predict中
 56     global y_predict_SC
 57     y_predict_SC = sgdc.predict(X_test_SC)
 58 
 59     print ('Accarcy of SGD Classifier:', sgdc.score(X_test_SC, y_test_SC))
 60     print(classification_report(y_test_SC,y_predict_SC))
 61 
 62 #SVM方法
 63 def con_svm():
 64 
 65     X_train_SVM = X_train
 66     y_train_SVM = y_train
 67 
 68     X_test_SVM = X_test
 69     y_test_SVM = y_test
 70 
 71     ss = StandardScaler()
 72     X_train_SVM = ss.fit_transform(X_train_SVM)
 73     X_test_SVM = ss.transform(X_test_SVM)
 74 
 75     #调用线性SVC实例化
 76     lsvc = LinearSVC()
 77     lsvc.fit(X_train_SVM, y_train_SVM)
 78 
 79     global y_predict_SVM
 80     y_predict_SVM = lsvc.predict(X_test_SVM)
 81 
 82     print("The accurary:", lsvc.score(X_test_SVM, y_test_SVM))
 83     print(classification_report(y_test_SVM, y_predict_SVM))  # , target_names=digits.target_names.astype(str)))
 84 
 85 #神经网络
 86 def con_MLPClass():
 87 
 88     X_train_MLP = X_train
 89     y_train_MLP = y_train
 90 
 91     X_test_MLP = X_test
 92     y_test_MLP = y_test
 93 
 94     ss = StandardScaler()
 95     X_train_MLP = ss.fit_transform(X_train_MLP)
 96     X_test_MLP = ss.transform(X_test_MLP)
 97 
 98     #调用MLP实例化
 99     MLP = MLPClassifier(hidden_layer_sizes=(13,13,13), max_iter=500)
100     MLP.fit(X_train_MLP, y_train_MLP)
101 
102     global y_predict_MLP
103     y_predict_MLP = MLP.predict(X_test_MLP)
104 
105     print("The accurary:", MLP.score(X_test_MLP, y_test_MLP))
106     print(classification_report(y_test_MLP, y_predict_MLP))  # , target_names=digits.target_names.astype(str)))
  1 from sklearn.preprocessing import StandardScaler
  2 
  3 from sklearn.linear_model import LogisticRegression     #线性模型中的Logistic回归模型
  4 from sklearn.linear_model import SGDClassifier          #线性模型中的随机梯度下降模型
  5 from sklearn.svm import LinearSVC                       #SVM模型中的线性SVC模型
  6 from sklearn.neural_network import MLPClassifier        #神经网络模型中的多层网络模型
  7 
  8 # LR
  9 def con_lr():
 10 
 11     X_train_LR = X_train
 12     y_train_LR = y_train
 13 
 14     X_test_LR = X_test
 15     y_test_LR = y_test
 16 
 17     ss = StandardScaler()
 18     X_train_LR = ss.fit_transform(X_train_LR)
 19     X_test_LR = ss.transform(X_test_LR)
 20 
 21     # 初始化LogisticRegression
 22     lr = LogisticRegression()
 23 
 24     # 调用LogisticRegression中的fit()来训练模型参数
 25     lr.fit(X_train_LR, y_train_LR)
 26 
 27     # 使用训练好的模型lr对X_test进行预测,结果储存在lr_y_predict中
 28     global y_predict_LR
 29     y_predict_LR = lr.predict(X_test_LR)
 30 
 31     # 性能分析
 32     print('Accuarcy of LR Classifier2:', lr.score(X_test_LR, y_test_LR))
 33     print (classification_report(y_test_LR, y_predict_LR))
 34 
 35 #SGD
 36 def con_sgd():
 37 
 38     X_train_SC = X_train
 39     y_train_SC = y_train
 40 
 41     X_test_SC = X_test
 42     y_test_SC = y_test
 43 
 44     # 标准化数据
 45     ss = StandardScaler()
 46     X_train_SC = ss.fit_transform(X_train_SC)
 47     X_test_SC = ss.transform(X_test_SC)
 48 
 49     # 初始化SGDClassifier
 50     sgdc = SGDClassifier()
 51 
 52     # 调用SGDClassifier中的fit函数用来训练模型参数
 53     sgdc.fit(X_train_SC, y_train_SC)
 54 
 55     # 使用训练好的模型sgdc对X_test进行预测,结果储存在sgdc_y_predict中
 56     global y_predict_SC
 57     y_predict_SC = sgdc.predict(X_test_SC)
 58 
 59     print ('Accarcy of SGD Classifier:', sgdc.score(X_test_SC, y_test_SC))
 60     print(classification_report(y_test_SC,y_predict_SC))
 61 
 62 #SVM方法
 63 def con_svm():
 64 
 65     X_train_SVM = X_train
 66     y_train_SVM = y_train
 67 
 68     X_test_SVM = X_test
 69     y_test_SVM = y_test
 70 
 71     ss = StandardScaler()
 72     X_train_SVM = ss.fit_transform(X_train_SVM)
 73     X_test_SVM = ss.transform(X_test_SVM)
 74 
 75     #调用线性SVC实例化
 76     lsvc = LinearSVC()
 77     lsvc.fit(X_train_SVM, y_train_SVM)
 78 
 79     global y_predict_SVM
 80     y_predict_SVM = lsvc.predict(X_test_SVM)
 81 
 82     print("The accurary:", lsvc.score(X_test_SVM, y_test_SVM))
 83     print(classification_report(y_test_SVM, y_predict_SVM))  # , target_names=digits.target_names.astype(str)))
 84 
 85 #神经网络
 86 def con_MLPClass():
 87 
 88     X_train_MLP = X_train
 89     y_train_MLP = y_train
 90 
 91     X_test_MLP = X_test
 92     y_test_MLP = y_test
 93 
 94     ss = StandardScaler()
 95     X_train_MLP = ss.fit_transform(X_train_MLP)
 96     X_test_MLP = ss.transform(X_test_MLP)
 97 
 98     #调用MLP实例化
 99     MLP = MLPClassifier(hidden_layer_sizes=(13,13,13), max_iter=500)
100     MLP.fit(X_train_MLP, y_train_MLP)
101 
102     global y_predict_MLP
103     y_predict_MLP = MLP.predict(X_test_MLP)
104 
105     print("The accurary:", MLP.score(X_test_MLP, y_test_MLP))
106     print(classification_report(y_test_MLP, y_predict_MLP))  # , target_names=digits.target_names.astype(str)))

    Python使用比较受欢迎原因有就是是代码的可读性比较高,这段模型实例化的代码比较简单,几种植机器上型的以实例化的代码也蛮接近。

    Python使用于让欢迎原因有就是是代码的可读性比较大,这段模型实例化的代码比较简单,几栽机器上型的利用实例化的代码也格外近乎。

  

  

  3.3.3 测试结果

  3.3.3 测试结果

    以样本数 sample_num=50
的状况下,训练75%数量,用25%底多寡就是13独样本进行测试。  

    当样本数 sample_num=50
的场面下,训练75%多少,用25%的数目就是13个样本进行测试。  

    几种植模型的测试结果使图5所著,可见除了SVM达到84.7%底精度之外,其他还在60-70%横。

    几种植模型的测试结果使图5所展示,可见除了SVM达到84.7%的精度之外,其他还当60-70%左右。

    但是盖只发生50只样本点,小样本之场面下测试精度的偶然性误差比较好。

    但是坐只发50只样本点,小样本之景象下测试精度的偶然性误差比较坏。

   图片 13

   图片 14

          祈求5 
手写体识别的性能分析(在样本数为50底情事下)

          图5 
手写体识别的性能分析(在样本数为50底情下)

 

 

   充实样本数到100,即死成了100摆放单个手写体图像,75张用来训练,25张用来测试。

   加样本数到100,即杀成了100张单个手写体图像,75张用来训练,25张用来测试。

   25摆设之测试结果图6所出示,几栽机器上的模型的测试精度都落得了90%横。

   25摆设之测试结果图6所显示,几种机器上之模子的测试精度都落得了90%横。

   图片 15

   图片 16

          图6 
手写体识别的性能分析(在样本数为100底景况下)

          图6 
手写体识别的性能分析(在样本数为100的动静下)

 

 

  图片 17

  图片 18

        图7  不同样本数下的季种植模型的测试精度

        图7  不同样本数量下之季种植模型的测试精度

 

 

 #转载或是使用图片代码请尊重作者劳动成果,注明出处,谢谢

 #转载或是使用图片代码请珍惜作者劳动成果,注明出处,谢谢