knn算法实现手写数字识别的背景_knn手写数字识别60000训练集

knn算法实现手写数字识别的背景_knn手写数字识别60000训练集KNN最邻近分类算法:(近邻取样)邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是机器学习分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。属于监督学习,有类别标记,且KNN是惰性学习。叫做Memory-basedlearning、也叫instance-basedlearning.他…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

KNN 最邻近分类算法:

(近邻取样)
邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是机器学习分类技术中最简单的方法之一。
所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。

属于监督学习,有类别标记,且KNN是惰性学习。叫做Memory-based learning、也叫instance-based learning. 他没有明显的前期训练过程,在程序运行之后,把数据加载到内存后,不需要进行训练就可以分类。

算法实现:
1、计算出每一个样本点与测试点的距离
2、选取距离最近的K个样本,并获取他们的标签 label
3、然后找出K个样本中数量最多的标签,返回该标签

KNN的本质是基于一种数据统计的方法。

下面的是KNN案例的应用:手写数字识别。
我这里的案例是文本格式。没有图片转换的步骤。
素材模型:(源码+素材最后会贴上githup的链接)

在这里插入图片描述

KNN 手写数字识别

实现思路:

  • 将测试数据转换成只有一列的0-1矩阵形式 将所有(L个)训练数据也都用上方法转换成只有一列的0-1矩阵形式

  • 把L个单列数据存入新矩阵A中——矩阵A每一列存储一个字的所有信息

  • 用测试数据与矩阵A中的每一列求距离,求得的L个距离存入距离数组中

  • 从距离数组中取出最小的K个距离所对应的训练集的索引 拥有最多索引的值就是预测值

第一步:
导入模块:

import os,time,operator             #导入os内置库来读取文件名     导入time来测试效率
import pandas as pd                 #导入数据处理库pandas        安装方法pip install pandas
import numpy as np                  #导入科学计算库numpy         安装方法pip install numpy
import matplotlib.pyplot as plt     #导入绘图库matplotlib        安装方法pip install matplotlib

第二步:
引入文件,定义一个读取数据的转换数据的函数

## print(len(tarining))      #1934个训练集                     ## print(len(test))   #945个测试集
trainingDigits =r'D:\work\日常任务6机器学习\day2手写数字识别\trainingDigits'
testDigits = r'D:\work\日常任务6机器学习\day2手写数字识别\testDigits'
                                                      ## ↑数据路径
tarining = (os.listdir(trainingDigits))                 ## 读取训练集
test = (os.listdir(testDigits))                        ## 读取测试集
def read_file(doc_name):                             ## 定义一个把32x32格式转为1行的函数
    data=np.zeros((1,1024))                         ## 创建1个zero数组
    f=open(doc_name)                               ## 打开文件
    for i in range(32):                          ## 已知每个文件中有32行32列
        hang=f.readline()                       ## 取行
        for j in range(32):                   ## 取每行中的每一列
            data[0,32*i+j]=int(hang[j])      ## 给data值
    # print(pd.DataFrame(data))             ## 不要在这里转换成DataFrame。
    return data                           ## 否则测试集效率会降低7倍
                                         ## 读取训练集效率会降低12倍

第三步:
定义一个字段转列表的函数,后面会用。
因为我为了提高效率没有使用pandas里面的Dataframe来操作数据。

def dict_list(dic:dict):               ## 定义函数将字典转化为列表
    keys = dic.keys()                 ## dic.keys()就是字典的k
    values = dic.values()            ## dic.values()就是字典的V
    lst = [(key,val) for  key,val in zip(keys, values)] ## for k,v in zip(k,v)
    return lst                        ## zip是一个可迭代对象
                                        ## 返回一个列表

第四步:
定义相似度函数:

def xiangsidu(tests,xunlians,labels,k):    ## tests:测试集 # xulians:训练样本集 # labels:标签 # k: 邻近的个数
    data_hang=xunlians.shape[0]              ## 获取训练集的行数data_hang
    zu=np.tile(tests,(data_hang,1))-xunlians   ## 用tile把测试集tests重构成一个 data_hang行、1列的1维数组
    q=np.sqrt((zu**2).sum(axis=1)).argsort()     ## 计算完距离后从低到高排序,argsort返回的是索引
    my_dict = {}                                   ## 设置一个dict
    for i in range(k):                              ## 根据我们的k来统计出现频率,样本类别
        votelabel=labels[q[i]]                         ## q[i]是索引值,通过labels来获取对应标签
        my_dict[votelabel] = my_dict.get(votelabel,0)+1   ## 统计每个标签的次数
    sortclasscount=sorted(dict_list(my_dict),key=operator.itemgetter(1),reverse=True)
                                                         ## 获取votelabel键对应的值,无返回默认
    return sortclasscount[0][0]                        ## 返回出现频次最高的类别

第五步:
编写识别函数:

def shibie():                                        ## 定义一个识别手写数字的函数
    label_list = []                                    ## 将训练集存储到一个矩阵并存储他的标签
    train_length = len(tarining)                        ## 直接一次获取训练集长度
    train_zero = np.zeros((train_length,1024))           ## 创建(训练集长度,1024)维度的zeros数组
    for i in range(train_length):                         ## 通过遍历训练集长度
        doc_name = tarining[i]                              ## 获取所有的文件名
        file_label = int(doc_name[0])                         ## 取文件名第一位文件的标签
        label_list.append(file_label)                           ## 将标签添加至handlabel中
        train_zero[i,:] = read_file(r'%s\%s'%(trainingDigits,doc_name))## 转成1024的数组
                                                                    ## 下面是测试集
    errornum = 0                                                  ## 记录error的初值
    testnum = len(test)                                         ## 同上 获取测试集的长度
    errfile = []                                              ## 定义一个空列表
    for i in range(testnum):                               ## 将每一个测试样本放入训练集中使用KNN进行测试
        testdoc_name = test[i]                           ## 通过i当作下标来获取测试集里面的文件
        test_label = int(testdoc_name[0])              ## 拿到测试文件的名字 拿到我们的数字标签
        testdataor = read_file(r'%s\%s' %(testDigits,testdoc_name)) ## 调用read_file操作测试集
        result = xiangsidu(testdataor, train_zero, label_list, 3)  ## 调用xiangsidu返回了result
        print("正在测试 %d, 内容是 %d" % (test_label,result))    ## 输出result和标签
        if (result != test_label):                               ## 判断标签是否等于测试名
            errornum += 1                                       ## 不是则+1 记录次数
            errfile.append(testdoc_name)                       ## 并把错误的文件名加入错误列表
    print("错误数量有 :%d" % errornum)                       ## 输出错误的数量
    print("错误的有 :%s"%[i for i in errfile])             ## 输出错误的列表中的名字
    print("准确率 %.2f%%" % ((1 - (errornum / float(testnum))) * 100)) ## 计算准确率

最后调用:

if __name__ == '__main__':                                        ## 声明主函数
    a = time.time()                                              ## 设置起始时间
    shibie()                                                   ## 调用测试函数
    b= time.time() - a                                       ## 计算运行时间
    print("运行时间:",b)                                   ## 输出运行时间

没啥太多好说的,为了改进效率在中间进行了很多技巧性的操作,虽然还是一堆for循环。
但是每个步骤的注释都写的很清楚,相信大家是可以看懂的,如有不懂请留言。

Github完整链接: https://github.com/lixi5338619/KNN_Distinguish/tree/master
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/194026.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • javascript断点调试

    javascript断点调试一、方法11.断点文件位置打开chrome,找到Sources,在一堆的文件夹里面找到你要调试的js文件,打开它:下面是html前端展示:2.打断点当你运行代码的时候,例如:操作搜索按钮点击事件,出现未知问题。首先,给Sources里面的js文件打断点。点击你要调试的代码的行数,发现行数会被标记为蓝色(chrome),这说明已经成功打断点了,恭喜你成功了第一步。3.断点调试对断点进行调试,首

  • java进销存ERP管理系统源码[通俗易懂]

    java进销存ERP管理系统源码[通俗易懂]java进销存ERP管理系统源码基于SpringBoot框架进销存源码+财务ERP源码+数据库技术框架核心框架:SpringBoot2.0.0持久层框架:Mybatis1.3.2日志管理:Log4j2.10.0JS框架:Jquery1.8.0UI框架:EasyUI1.3.5模板框架:AdminLTE2.4.0项目管理框架:Maven3.2.3开发环境IDE:IntelliJIDEA2017+eclipseDB:Mysql5.7.4JDK:JDK1.8

  • DTW和DBA_电台文本

    DTW和DBA_电台文本DTW(动态时间调整)动态时间调整算法是大多用于检测两条语音的相似程度,由于每次发言,每个字母发音的长短不同,会导致两条语音不会完全的吻合,动态时间调整算法,会对语音进行拉伸或者压缩,使得它们竟可能

  • c# MD5加密

    c# MD5加密usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Security.Cryptography;usingSystem.Text;usingSystem.Threading.Tasks;/****************************** *概要:MD5加密 *设…

  • Java基础算法详解

    Java基础算法详解查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中。因为其实现代码较短,应用较常见。所以在面试中经常会问到排序算法及其相关的问题。但万变不离其宗,只要熟悉了思想,灵活运用也不是难事。一般在面试中最常考的是快速排序和归并排序,并且经常有面试官要求现场写出这两种排序的代码。对这两种排序的代码一定要信手拈来才行。还有插入排序、冒泡排序、堆排序、基数排序、桶排序等。面试官对于这些排序可能会…

  • Java 枚举(enum) 详解7种常见的用法

    Java 枚举(enum) 详解7种常见的用法JDK1.5引入了新的类型——枚举。在Java中它虽然算个“小”功能,却给我的开发带来了“大”方便。大师兄我【大师兄】又加上自己的理解,来帮助各位理解一下。用法一:常量在JDK1.5之前,我们定义常量都是:publicstaticfinal….。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。Java代码publ…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号