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])

 

posted @ 2020-07-21 20:58  电竞杰森斯坦森  阅读(465)  评论(0编辑  收藏  举报