利用KNN算法实现手写数字识别

利用KNN算法实现手写数字识别

数据介绍

1.数据文件包含从0到9的手绘数字的灰度图像。

2.每个图像高28像素,宽28像素,共784个像素。

3 每个像素取值范围[0,255],取值越大意味着该像素颜色越深

4 训练数据集共785列。第一列为 “标签”,为该图片对应的手写数字。其余784列为该图像的像素值

5 训练集中的特征名称均有pixel前缀,后面的数字([0,783])代表了像素的序号。

# 导入numpy库和matplotlib库的pyplot模块,用于处理图像数据和绘图
import numpy as np
from matplotlib import pyplot as plt

# 读取图像文件,这里使用了绝对路径来指定图像文件的位置
# 我们真实拿到的数据应该是一组图片,我们需要将图片转换成矩阵形式,才能进行后续的运算。
img = plt.imread(r'D:\pythonProject2\data\0.png')

# 将二维图像数据转换为一维数组,方便后续处理
# print(f'读取的图片数据:{img.shape}')
img = img.reshape(1, -1)

# 在一维数组的开头插入一个值为2的元素,用于表示某种特征或标识
# print(f'转换后的图片数据:{img}')
# print(f'图片转换成矩阵:{img.shape}')
img = np.insert(img[0], 0, 2)

# 输出处理后的图像数据和其形状信息
print(img)
print(img.shape)

模型的训练

超参的选择方法

交叉验证

一种数据集的分割方法,将训练集划分为 n 份,拿一份做验证集(测试集)、其他n-1份做训练集

• 交叉验证法原理:将数据集划分为 cv=4

  1. 第一次:把第一份数据做验证集,其他数据做训练

  2. 第二次:把第二份数据做验证集,其他数据做训练

  3. …以此类推,总共训练4次,评估4次。

  4. 使用训练集+验证集多次评估模型,取平均值做交叉验证为模型得分

  5. 若k=5模型得分最好,再使用全部训练集(训练集+验证集) 对k=5模型再训练一边,再使用测试集对k=5模型做评估
    在这里插入图片描述

    交叉验证法,是划分数据集的一种方法,目的就是为了得到更加准确可信的模型评分。

    网格搜索

    • 为什么需要网格搜索?
    模型有很多超参数,其能力也存在很大的差异。需要手动产生很多超参数组合,来训练模型
    每组超参数都采用交叉验证评估,最后选出最优参数组合建立模型。
    • 网格搜索是模型调参的有力工具。寻找最优超参数的工具!

    ​ 只需要将若干参数传递给网格搜索对象,它自动帮我们完成不同超参数的组合、模型训练、模型评估,

    ​ 最终返回一组最优的超参数。
    • 网格搜索 + 交叉验证的强力组合 (模型选择和调优)
    ​ 交叉验证解决模型的数据输入问题(数据集划分)得到更可靠的模型
    ​ 网格搜索解决超参数的组合
    ​ 两个组合再一起形成一个模型参数调优的解决方案

    交叉验证网格搜索 – API和应用举例

    • 交叉验证网格搜索API介绍
    在这里插入图片描述

训练模型
# 加载手写数字识别数据集
data = pd.read_csv(r'D:\...\手写数字识别.csv')
# 对数据进行预处理,包括归一化
scaler = MinMaxScaler()
x = scaler.fit_transform(data.iloc[:,1:])
y = data.iloc[:,0]
# 将数据集划分为训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=20) 
# 实例化KNN分类器,并使用GridSearchCV进行超参数调优
estimator = KNeighborsClassifier(n_neighbors=5)
params = {'n_neighbors':range(3,10,2)}
estimator = GridSearchCV(estimator,params,cv=5)
estimator.fit(x_train,y_train)
# 选择最佳模型进行预测,并计算预测准确率
estimator = estimator.best_estimator_
score = estimator.score(x_test,y_test)
print(f'模型预测准确率:{score}')
# 保存训练好的模型
joblib.dump(estimator,'D:\...\model\knn_digit.pkl')

模型的预测

# 加载图片数据
img = plt.imread(r'D:\...\data\0.png')
# 将二维图片数据转换为一维数组
img = img.reshape(1,-1)
# 加载已训练好的KNN分类器模型
estimator = joblib.load(r'D:\...\model\knn_digit.pkl')
# 使用模型预测图片代表的数字
y_pred = estimator.predict(img)
# 输出预测结果
print(f'预测结果:{y_pred}')

完整代码

#-*- coding:utf-8 -*-
#Desc TODO 手写数字识别
#todo 0.导包
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import MinMaxScaler
import joblib

#todo 1.数据转换(图片转换)

def knn_train():
    # 加载手写数字识别数据集
    #todo 2.加载数据集并查看
    data = pd.read_csv(r'D:\...\data\手写数字识别.csv')
    # 对数据进行预处理,包括归一化
    # todo 3.数据基本处理
    # todo 3.1归一化
    scaler = MinMaxScaler()
    x = scaler.fit_transform(data.iloc[:,1:])
    y = data.iloc[:,0]

    # 将数据集划分为训练集和测试集
    # todo 3.2 划分数据集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=20)

    # 实例化KNN分类器,并使用GridSearchCV进行超参数调优
    # todo 4.实例化模型
    # todo 5.超参调优
    estimator = KNeighborsClassifier(n_neighbors=5)
    params = {'n_neighbors':range(3,10,2)}
    estimator = GridSearchCV(estimator,params,cv=5)
    estimator.fit(x_train,y_train)

    # 选择最佳模型进行预测,并计算预测准确率
    # todo 6.模型预测
    estimator = estimator.best_estimator_
    score = estimator.score(x_test,y_test)
    print(f'模型预测准确率:{score}')

    # 保存训练好的模型
    # todo 7.模型保存
    joblib.dump(estimator,'D:\...\model\knn_digit.pkl')
def knn_predict():
    # 加载图片数据
        # todo 1.加载图片
        img = plt.imread(r'D:\...\data\0.png')
        # 将二维图片数据转换为一维数组
        # todo 2.图片转换成矩阵
        img = img.reshape(1,-1)
        # 加载已训练好的KNN分类器模型
        # todo 3.加载模型
        estimator = joblib.load(r'D:\...\model\knn_digit.pkl')
        # 使用模型预测图片代表的数字
        # todo 4.预测图片
        y_pred = estimator.predict(img)
        # 输出预测结果
        print(f'预测结果:{y_pred}')
if __name__ == '__main__':
    knn_predict()
    knn_train()



  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值