使用KNN识别MNIST手写数据集(手写,不使用KNeighborsClassifier)

KNN识别MNIST手写数据集(32*32维),根据KNN原理一步步实现。

大家好,又见面了,我是你们的朋友全栈君。

数据集
提取码:mrfr

浏览本文前请先搞懂K近邻的基本原理:最简单的分类算法之一:KNN(原理解析+代码实现)

算法实现步骤:

  1. 数据处理。每一个数字都是一个32X32维的数据,如下所示:
    在这里插入图片描述
    knn中邻居一词指的就是距离相近。我们要想计算两个样本之间的距离,就必须将每一个数字变成一个向量。具体做法就是将32X32的数据每一行接在一起,形成一个1X1024的数据,这样我们就可以计算欧式距离。
  2. 计算测试数据到所有训练数据的距离,并按照从小到大排序,选出前K个
  3. 根据距离计算前K个样本的权重
  4. 将相同的训练样本的权重加起来,返回权重最大样本的标签

代码实现:

import os

def load_data(path):
    check = [i for i in range(10)]
    final_data = []
    
    for i in range(10):
        final_data.append([])
        
    files = os.listdir(path)    #文件夹
    for file in files:
        data = open(path + "/" + file)
        str = ""      #将所有数据接在一起
        temp = []
        for line in data.readlines():
            str = str + line[:-1]   #去掉回车,一行接一行
        for i in str:
            temp.append(int(i))   #变成数字
        final_data[check.index(int(file[0]))].append(temp)   #根据标签放在列表相应的位置

    return final_data, len(files)

def knn_mnist(K,test_data):
    train_data, length = load_data('manifold/digits/trainingDigits')
    distance = []     #存储测试数据到所有训练数据的距离
    
    for i in range(len(train_data)):
        for j in range(len(train_data[i])):
            res = 0
            for k in range(len(test_data)):
                res += (test_data[k]-train_data[i][j][k]) ** 2   #欧氏距离
            distance.append([res ** 0.5, i])   #距离+训练集数据标签

    distance = sorted(distance, key=(lambda x: x[0]))  #按距离从小到大排序
    weight = []   #权重与序号
    sum_distance = 0.0
    for i in range(K):
        sum_distance += distance[i][0]   #计算前K个距离的和
    for i in range(K):
        weight.append([1 - distance[i][0] / sum_distance, distance[i][1]])  #权重+序号
        
    #将相同序号的加起来
    num = []   #统计有哪些序号
    for i in range(K):
        num.append(weight[i][1])
    num = list(set(num))   #去重
    
    final_res = []
    for i in range(len(num)):
        res = 0.0
        for j in range(len(weight)):
            if weight[j][1] == num[i]:   #前K个标签一样的样本权值加起来
                res += weight[j][0]
        final_res.append([res, num[i]])

    final_res = sorted(final_res, key=(lambda x: x[0]),reverse=True)  # 按照权重从大到小排序

    return final_res[0][1]   #最终返回最大权值对应的标签

def test():
    K = 5
    test_data, length = load_data('manifold/digits/testDigits')
    #测试
    for i in range(len(test_data)):
        for j in range(len(test_data[i])):
            print(knn_mnist(K, test_data[i][j]))

if __name__ == '__main__':
    test()

  欢迎大家关注我的微信公众号:KI的算法杂记,有什么问题可以直接发私信。

在这里插入图片描述

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

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/125683.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 多级时间轮定时器_时间轮与哈希表定时

    多级时间轮定时器_时间轮与哈希表定时时间轮简述顾名思义,时间轮就像一个轮子,在转动的时候外界会指向轮子不同的区域,该区域就可以被使用。因此只要将不同时间的定时器按照一定的方法散列到时间轮的不同槽(即时间轮划分的区域)之中,就可以实现在运转到某个槽时,进行判断该定时器是否已经到达运行时间(需要判断是由于有的定时器并非在这一圈就需要运行,可能需要后面几圈才会运行。从图中也可以看出,每个槽中的定时器是以(双向)链表…

    2022年9月29日
    3
  • Centos 7 安装 yum 命令

    Centos 7 安装 yum 命令在Centos7上安装yum命令在官网下载centos7最新ios镜像,用VM进行安装,具体安装步骤在这里不做赘述,可以翻阅网上其他教程。一般安装完成后centos都会自带yum。执行yumlist命令可能会报以下几种错误。错误一:couldnotfindmirror  表明无法找到软件镜像源,因为是网络的原因。因此我们要去修改网络配置解决方式:执…

    2022年6月4日
    51
  • GridView删除事件

    GridView删除事件首先:转摘一段GridView删除的文章RowDeleting和RowDeleted事件RowDeleting发生在删除数据之前,RowDeleted发生在删除数据之后。使用RowDeletin

    2022年7月3日
    23
  • 图遍历算法的应用

    图遍历算法的应用1.判断图的连通性图的遍历算法可以用来判断图的连通性。如果一个无向图是联通的,如果无向图是联通的,则从任一节点出发,仅需一次遍历就可以访问图中的所有节点。如果无向图是非联通的,则从某一节点出发,一次遍历仅能访问到该顶点所在联通分量的所有顶点,而对于图中其他联通分量的顶点,则无法通过这次遍历访问。对于有向图来说,若从初始点到图中的每个顶点都有路径,则能够访问到图中的所有顶点,否则不能访问到所有顶…

    2022年5月4日
    51
  • IDEA/Pycharm等中全局搜索无效(win10)

    IDEA/Pycharm等中全局搜索无效(win10)IDEA/Pycharm等中全局搜索无效(win10)原因:系统输入法热键占用了Ctrl+Shift+F找到设置里的语言选中微软的输入法点击按键关闭热键结束语系统就能用Ctrl+Shift+F全局搜索了

    2022年5月20日
    79
  • yarn安装程序[通俗易懂]

    yarn安装程序[通俗易懂]链接:yarn提取码:7zw7

    2025年6月12日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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