根号八的三次方

时间:2024-01-09 03:27:08编辑:小李

作者 | 奶糖猫

来源 | CSDN 博客,责编 | 夕颜

头图 | CSDN 下载自视觉中国

出品 | CSDN(ID:CSDNnews)

算法简介

手写数字识别是KNN算法一个特别经典的实例,其数据源获取方式有两种,一种是来自MNIST数据集,另一种是从UCI欧文大学机器学习存储库中下载,本文基于后者讲解该例。

基本思想就是利用KNN算法推断出如下图一个32x32的二进制矩阵代表的数字是处于0-9之间哪一个数字。

数据集包括两部分,一部分是训练数据集,共有1934个数据;另一部分是测试数据集,共有946个数据。所有数据命名格式都是统一的,例如数字5的第56个样本——5_56.txt,这样做为了方便提取出样本的真实标签。

数据的格式也有两种,一种是像上图一样由0、1组成的文本文件;另一种则是手写数字图片,需要对图片做一些处理,转化成像上图一样的格式,下文皆有介绍。

算法步骤

收集数据:公开数据源

分析数据,构思如何处理数据

导入训练数据,转化为结构化的数据格式

计算距离(欧式距离)

导入测试数据,计算模型准确率

手写数字,实际应用模型

由于所有数据皆由0和1构成,所以不需要数据标准化和归一化这一步骤

算法实现处理数据

在计算两个样本之间的距离时,每一个属性是一一对应的,所以这里将32x32的数字矩阵转化成1x1024数字矩阵,方便计算样本之间距离。


计算欧式距离

numpy有一个tile方法,可以将一个一维矩阵横向复制若干次,纵向复制若干次,所以将一个测试数据经过tile方法处理后再减去训练数据,得到新矩阵后,再将该矩阵中每一条数据(横向)平方加和并开根号后即可得到测试数据与每一条训练数据之间的距离。

下一步将所有距离升序排列,取到前K个,并在这个范围里,每个数字类别的个数,并返回出现次数较多那个数字类别的标签。

测试数据集应用

首先要对训练数据集处理,listdir方法是返回一个文件夹下所有的文件,随后生成一个行数为文件个数,列数为1024的训练数据矩阵,并且将训练数据集中每条数据的真实标签切割提取存入至labels列表中,即计算距离classify函数中传入的label。


然后对测试训练数据集做与上述一样的处理,并将测试数据矩阵TestClassify、训练数据矩阵train_matrix、训练数据真实标签labels、K共4个参数传入计算距离classify函数中,最后计算出模型准确率并输出预测错误的数据。


代码运行部分截图如下

当K=3时,准确率达到了98.94%,对于这个模型而言,准确率是十分可观的,但运行效率却比较低,接近30秒的运行时间。因为每个测试数据都要与近2000个训练数据进行距离计算,而每次计算又包含1024个维度浮点运算,高次数多维度的计算是导致模型运行效率低的主要原因。

K值

下图是K值与模型准确率的关系变化图,K=3时,模型准确率达到峰值,随着K增大,准确率越来越小,所以这份数据的噪声还是比较小的。

手写数字测试

建模完成了,模型的准确率也不错,为何自己手写的数字测试一下呢?所以偶就手动写了几个数字.

正常拍出的图片是RGB彩色图片,并且像素也各不相同,所以需要对图片做两项处理:转化成黑白图片、将像素转化为32x32,这样才符合我们上文算法的要求;对于像素点,数值一般位于0-255,255代表白、0代表黑,但因为手写数字像素点颜色并不规范,所以我们设置一个阈值用以判断黑白之分。

图片转文本代码如下:


整体代码运行截图如下:

正确率为70%,毕竟测试数据很少,10个数字中4、7、8三个数字预测错误,还算可观;由于光线问题,有几个数字左下角会有一些黑影,也会对测试结果产生一定的影响,若避免类似情况,并且多增加一些测试数据,正确率定会得到提升的。

上一篇:黑玫瑰的花语

下一篇:分户申请书