机器学习-手写数字识别实现
- 使用knn实现手写数字图片的识别
from sklearn.model_selection import cross_val_score import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import train_test_split #加载一张图片数据 img_arr = plt.imread('./digist/3/3_100.bmp') img_arr.shape (28, 28) plt.imshow(img_arr)
- 对所有数据的读取和加载,将其封装成样本数据
feature_list = [] target_list = [] #1.加载数据,封装成样本数据 for i in range(10): for j in range(1,501): img_path = './digist/'+str(i)+'/'+str(i)+'_'+str(j)+'.bmp' img_arr = plt.imread(img_path) feature_list.append(img_arr) target_list.append(i) len(feature_list) 5000 len(target_list) 5000 #每一个列表元素为2维,则当前列表一定是一个三维数据结构 #训练模型需要的特征数据必须是二维 feature_list[0].shape (28, 28) #需要对feature_list进行扁平化处理:三维的列表变成二维 #如果将每一个列表元素由二维变成1维,则整体列表就变形成了2维 feature = [] for img_arr in feature_list: feature.append(img_arr.reshape((28*28,))) feature = np.array(feature) #将列表转换成数组 target = np.array(target_list) #拆分数据集 x_train,x_test,y_train,y_test = train_test_split(feature,target,test_size=0.1,random_state=2020) #找寻模型最优的超参数 scores = [] ks = [] for k in range(3,100): knn = KNeighborsClassifier(n_neighbors=k) score = cross_val_score(knn,x_train,y_train,cv=5).mean() ks.append(k) scores.append(score) best_k = ks[np.argmax(np.array(scores))] best_k
3 # knn = KNeighborsClassifier(n_neighbors=best_k) knn = KNeighborsClassifier(n_neighbors=best_k) knn.fit(x_train,y_train) knn.score(x_test,y_test)
0.939
#使用模型进行图像识别 print('真实的图像识别结果:',y_test[0:10]) print('模型分类的结果:',knn.predict(x_test)[0:10]) 真实的图像识别结果: [4 4 6 0 2 4 7 7 8 4] 模型分类的结果: [4 4 6 0 2 4 7 7 8 4]
- 让模型识别外部图片
img_arr = plt.imread('./123.jpg') plt.imshow(img_arr)
#将5切出来 five_img_arr = img_arr[300:430,185:290] plt.imshow(five_img_arr)
five_img_arr.shape
(130, 105)
- 训练好的模型识别的图片数据只能是对28*28像素图片进行扁平化处理后的数据
#将five_img_arr进行像素的等比例压缩(28*28),在对其进行扁平化处理即可 import scipy.ndimage as ndimage five_img_arr_zoom = ndimage.zoom(five_img_arr,zoom=(28/130,28/105)) plt.imshow(five_img_arr_zoom) #扁平化处理 # five_img_arr_zoom.reshape((28*28,)) #这是一个1维的结构 #在进行predict的时候需要传入的X,必须是二维 knn.predict(five_img_arr_zoom.reshape((1,784)))
array([5])