机器学习机器学习KNN算法之手写数字数字识别算法之手写数字数字识别
算法简介算法简介
手写数字识别是KNN算法一个特别经典的实例,其数据源获取方式有两种,一种是来自MNIST数据集,另一种是从UCI欧文大学机器学习存储库中下载,本文基于后者讲
解该例。
基本思想就是利用KNN算法推断出如下图一个32×32的二进制矩阵代表的数字是处于0-9之间哪一个数字。
数据集包括两部分,一部分是训练数据集,共有1934个数据;另一部分是测试数据集,共有946个数据。所有数据命名格式都是统一的,例如数字5的第56个样本
——5_56.txt,这样做为了方便提取出样本的真实标签。
数据的格式也有两种,一种是像上图一样由0、1组成的文本文件;另一种则是手写数字图片,需要对图片做一些处理,转化成像上图一样的格式,下文皆有介绍。
算法步骤算法步骤
收集数据:公开数据源
分析数据,构思如何处理数据
导入训练数据,转化为结构化的数据格式
计算距离(欧式距离)
导入测试数据,计算模型准确率
手写数字,实际应用模型
由于所有数据皆由由于所有数据皆由0和和1构成,所以不需要数据标准化和归一化这一步骤构成,所以不需要数据标准化和归一化这一步骤
算法实现算法实现
处理数据处理数据
在计算两个样本之间的距离时,每一个属性是一一对应的,所以这里将32×32的数字矩阵转化成1×1024数字矩阵,方便计算样本之间距离。
#处理文本文件
def img_deal(file):
#创建一个1*1024的一维零矩阵
the_matrix = np.zeros((1,1024))
fb = open(file)
for i in range(32):
#逐行读取
lineStr = fb.readline()
for j in range(32):
#将32*32=1024个元素赋值给一维零矩阵
the_matrix[0,32*i+j] = int(lineStr[j])
return the_matrix
计算欧式距离计算欧式距离
numpy有一个tile方法,可以将一个一维矩阵横向复制若干次,纵向复制若干次,所以将一个测试数据经过tile方法处理后再减去训练数据,得到新矩阵后,再将该矩阵中
每一条数据(横向)平方加和并开根号后即可得到测试数据与每一条训练数据之间的距离。
下一步将所有距离升序排列,取到前K个,并在这个范围里,每个数字类别的个数,并返回出现次数较多那个数字类别的标签。
def classify(test_data,train_data,label,k):
Size = train_data.shape[0] #将测试数据每一行复制Size次减去训练数据,横向复制Size次,纵向复制1次
the_matrix = np.tile(test_data,(Size,1)) - train_data
#将相减得到的结果平方
sq_the_matrix = the_matrix ** 2
#平方加和,axis = 1 代表横向
all_the_matrix = sq_the_matrix.sum(axis = 1)
#结果开根号得到最终距离
distance = all_the_matrix ** 0.5
#将距离由小到大排序,给出结果为索引
sort_distance = distance.argsort()
dis_Dict = {}
#取到前k个
for i in range(k):
#获取前K个标签
评论0