用k_nn算法手写数字识别

用k_nn算法手写数字识别

import numpy as np
from os import listdir  # listdir可以列出给定目录的文件名


def knnPredict(newInput, dataset, labels, k):
    dataset = np.array(dataset)
    # 表示样本数量
    datasize = dataset.shape[0]
    # 求解欧式距离(类似于均方差)(x^2 + y^2)^0.5
    # tile属于numpy模块下边的函数
    # tile(A, reps)返回一个shape=reps的矩阵,矩阵的每个元素是A
    # 比如 A=[0,1,2] 那么,tile(A, 2)= [0, 1, 2, 0, 1, 2]
    # tile(A,(2,2)) = [[0, 1, 2, 0, 1, 2],
    #                  [0, 1, 2, 0, 1, 2]]
    # tile(A,(2,1,2)) = [[[0, 1, 2, 0, 1, 2]],
    #                    [[0, 1, 2, 0, 1, 2]]]
    # 上边那个结果的分开理解就是:
    # 最外层是2个元素,即最外边的[]中包含2个元素,类似于[C,D],而此处的C=D,因为是复制出来的
    # 然后C包含1个元素,即C=[E],同理D=[E]
    # 最后E包含2个元素,即E=[F,G],此处F=G,因为是复制出来的
    # F就是A了,基础元素
    # 综合起来就是(2,1,2)= [C, C] = [[E], [E]] = [[[F, F]], [[F, F]]] = [[[A, A]], [[A, A]]]
    # 这个地方就是为了把输入的测试样本扩展为和dataset的shape一样,然后就可以直接做矩阵减法了。
    # 比如,dataset有4个样本,就是4*2的矩阵,输入测试样本肯定是一个了,就是1*2,为了计算输入样本与训练样本的距离
    # 那么,需要对这个数据进行作差。这是一次比较,因为训练样本有n个,那么就要进行n次比较;
    # 为了方便计算,把输入样本复制n次,然后直接与训练样本作矩阵差运算,就可以一次性比较了n个样本。
    # 比如inX = [0,1],dataset就用函数返回的结果,那么
    # tile(inX, (4,1))= [[ 0.0, 1.0],
    #                    [ 0.0, 1.0],
    #                    [ 0.0, 1.0],
    #                    [ 0.0, 1.0]]
    # 作差之后
    # diffMat = [[-1.0,-0.1],
    #            [-1.0, 0.0],
    #            [ 0.0, 1.0],
    #            [ 0.0, 0.9]]
    diffMat = np.tile(newInput, (datasize, 1)) - dataset
    sqDisMat = diffMat ** 2
    # 对横轴进行求和
    sqDistance = np.sum(sqDisMat, axis=1)
    # 开根号
    distance = sqDistance ** 0.5
    # 对距离进行升序排序,返回的是数组下标
    sortDistance = distance.argsort()

    # 字典结构,存放对应的投票数
    classcount = {}

    # 投票过程
    for i in range(k):
        voteLabel = labels[sortDistance[i]]
        # 如果不存在这个类,则默认为0,每次都加1
        classcount[voteLabel] = classcount.get(voteLabel, 0) + 1

    # 返回一个降序的列表
    Realresult = sorted(classcount.items(), key=lambda item: item[1], reverse=True)
    return Realresult[0][0]


# 将图片转换成1*1024的向量
def imgVector(filename):
    resultVector = np.zeros((1, 1024))
    fr = open(filename)
    for i in range(32):
        lineStr = fr.readline()
        for j in range(32):
            resultVector[0, 32 * i + j] = int(lineStr[j])
    return resultVector


def handwritingTest():
    handLabels = []
    handDigitsList = listdir('./Data/handDigits/')  # 返回的是列表对象
    num = len(handDigitsList)
    trainDataset = np.zeros((num, 1024))
    for i in range(num):
        handLabels.append(int(handDigitsList[i][0]))
        trainDataset[i, :] = imgVector('./Data/handDigits/' + handDigitsList[i])
    testDataList = listdir('./Data/handtestDigits/')
    wrongNum = 0.0
    testNum = len(testDataList)
    for i in range(testNum):
        testVector = imgVector('./Data/handtestDigits/' + testDataList[i])
        testLabel = int(testDataList[i][0])
        classResult = knnPredict(testVector, trainDataset, handLabels, 3)
        print("这个样例被分类为:" + str(classResult) + ",实际分类为:" + str(testLabel))
        if testLabel != classResult:
            wrongNum += 1.0
    print("样例中被错误分类的个数为:" + str(wrongNum))
    print("错误率为:" + str(wrongNum / float(testNum)))

handwritingTest()

图片信息类似为

在这里插入图片描述
在这里插入图片描述

运行结果为:

在这里插入图片描述

很抱歉,我无法提供完整的代码,但我可以给出一个概述。mnist_matlab_手写数字识别是一个基于MATLAB编程实现手写数字识别算法。它使用了mnist手写数字数据集,该数据集包含60000张训练图片和10000张测试图片。原始图片大小为28x28,经过处理后的图片大小为20x20。该程序的目标是训练一个模型,能够准确地识别手写数字。 在MATLAB中,可以使用各种机器学习或深度学习算法实现手写数字识别。常见的方法包括支持向量机(SVM)、K最近邻(K-NN)、卷积神经网络(CNN)等。具体实现过程包括数据预处理、特征提取、模型训练和测试等步骤。 首先,需要加载mnist手写数字数据集,并进行预处理。预处理包括去除边缘填充像素、将图片转换为灰度图像、对像素进行归一化等操作。 接下来,可以选择合适的特征提取方法。常用的特征提取方法包括像素值、梯度方向直方图(HOG)、局部二值模式(LBP)等。特征提取的目的是将图片转化为一个向量,以便于机器学习算法进行处理。 然后,使用训练集对模型进行训练。训练过程中,可以选择适当的机器学习算法,并根据训练集的标签进行监督学习。 最后,使用测试集对训练好的模型进行评估。评估指标可以是准确率、召回率、F1分数等。 需要注意的是,mnist_matlab_手写数字识别的具体实现可能会因为算法选择、参数设置等因素而有所不同。因此,如果您需要完整的代码,请参考相应的教程或文档,以确保您得到最新和最准确的代码。<span class="em">1</span> #### 引用[.reference_title] - *1* [mnist_matlab_手写数字识别_](https://download.csdn.net/download/weixin_42691388/25807725)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值