2-机器学习-KNN+交叉验证案例实践之手写数字识别项目
使用knn实现手写数字图片的识别
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,cross_val_score # 1.加载数据,封装成样本数据 feature_list = [] target_list = [] 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), len(target_list) # (5000, 5000) # 每个元素是一个img_arr,是一个二维数组,整体列表就是一个三维数据 # 训练模型需要的特征数据必须时二维数据 feature_list[0].shape # (28, 28) # 需要对feature_list进行扁平化处理:将三维的列表变成二维 # 如果将每一个列表元素由二维变成1维,则整体列表就变形成了2维 feature = [] for img_arr in feature_list: feature.append(img_arr.reshape((28*28,))) # reshape将列表2维元素转1维 feature[0].shape, len(feature) # ((784,), 5000) feature = np.array(feature) # 将列表形式的特征数据变成numpy数组 target = np.array(target_list) # 将列表形式的标签数据变成numpy数组 feature.shape # (5000, 784) # 2.拆分数据集 x_train,x_test,y_train,y_test = train_test_split(feature, target, test_size=0.2, random_state=2020) # 3.找寻模型最优的超参数 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.fit(x_train,y_train) knn.score(x_test,y_test) # 0.939 # 4.使用模型进行图像识别 print('真实图像的结果:',y_test[:10]) print('模型识别的结果', knn.predict(x_test)[: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),在对其进行扁平化处理即可 from scipy import 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)).shape # (784,) x_train[0].shape # (784,) x_test[0].shape # (784,) # 扁平化处理 # five_img_arr_zoom.reshape((28*28,)) # 这是一个1维的结构 # 在进行predict的时候需要传入的X,必须是二维 knn.predict(five_img_arr_zoom.reshape((1,784))) # array([5])