#二、KNN 算法 ''' traindata.shape #返回一个列表,第一个行数,第二个列数 numpy.tile(a,(b,c)) #参数 a 为扩展的对象,b 方向扩展,c 为列方向扩展 ''' import numpy from collections import defaultdict #参数 k:选取距离最小的 k 个样本,labels:每个训练数据所属类型的列表 def knn(k,testdata,traindata,labels): traindatasize=traindata.shape[0] #将 testdata 扩展为 traindata 一样的维数 dif=numpy.tile(testdata,(traindatasize,1))-traindata sq_dif=dif**2 sum_sql_dif=sq_dif.sum(axis=1) #axis=1,表示每列之和,axis=0 表示每行之和
distance=sum_sql_dif**0.5 #得到元素索引的排序列表 sortdistance=distance.argsort() #选取距离最小的 k 个样本,并对其所属类型的频率计算 frequency=defaultdict(int) for i in range(k): type=labels[sortdistance[i]] #sortdistance[i]为 labels 的索引 frequency[type]+=1 sortcount=sorted(frequency.items(),key=lambda a:a[1])#类型频率高低排序 return sortcount[0][0] #三、图片及手写体数字的识别 #1、图片处理 #pillow 模块的缩写为 PIL ''' im.size 获得宽、高 k=im.getpixel((1,9)) 获取图片某个位置的像素 print(k) 得到的是 rgb 格式(三种基本色) (255,255,255)为白色,(0,0,0)为黑色, 所以三者之和为 0 则为黑,非零则为白。 ''' from PIL import Image im=Image.open('C:\\Users\\coffee\\Desktop\\7.png') fh=open('C:\\Users\\coffee\\Desktop\\7.txt','a') width=im.size[0] height=im.size[1] for i in range(width): for j in range(height): k=im.getpixel((i,j)) #得到三个数的列表 cl_all=k[0]+k[1]+k[2] if(cl_all==0): fh.write('0') else: fh.write('1') fh.write('\n') fh.close() #2、手写体 数字的识别 ''' data=open('C:\\Users\\coffee\\Desktop\\7.txt','r') data.readline(5) #默认读取行所有的数据,括号中的参数 5 表示输出该行的 5 个字符。 for line in data.readlines(): print(line) ''' #建立一个函数专门实现数据的加载,将数据转化为一行 1024(32*32)个数字的数组。 def datatoarray(file_dir): arr=[] fh=open(file_dir) for i in range(32): thisline=fh.readline() for j in range(32): arr.append(int(thisline[j])) return arr ''' fname='C:\\Users\\coffee\\Desktop\\7.txt' datatoarray(fname) '''
#建立一个函数,提取文件的前缀--label(文件名:0_2.txt) def seplabel(fname): filestr=fname.split('.')[0] #分割后得到的是列表 label=int(filestr.split('_')[0]) return label #建立训练数据--提取 train 数据,labels import os def traindata(): labels=[] trainfile=os.listdir('D:\\python\\Python3 数 据 分 析 与 挖 掘 实 战 \\ 源码\\ 第 7 周 \\testandtraindata\\traindata') #获取文件名的列表 trainarr=numpy.zeros((len(trainfile),1024)) #生成一个二维数组 for i in range(len(trainfile)): thislabel=seplabel(trainfile[i]) labels.append(thislabel) trainarr[i,:]=datatoarray('D:\\python\\Python3 数据分析与挖掘实战\\源码\\第 7 周 \\testandtraindata\\traindata\\'+trainfile[i]) return trainarr,labels ''' trainarr,labels=traindata() ''' #建立测试数据函数-得到测试函数集(将每个测试数据转化为一行向量) def datatest(): testfile=os.listdir('D:\\python\\Python3 数据分析与挖掘实战\\ 源码\\ 第 7 周 \\testandtraindata\\testdata') test_labels=[] testarr=numpy.zeros((len(testfile),1024)) for i in range(len(testfile)): label=seplabel(testfile[i]) test_labels.append(label) testarr[i,:]=datatoarray('D:\\python\\Python3 数据分析与挖掘实战\\源码\\第 7 周 \\testandtraindata\\traindata\\'+testfile[i]) return testarr,test_labels ''' testarr,test_labels=datatest() ''' #调用数据进行检验 trainarr,labels=traindata() testarr,test_labels=datatest() oks=[] t=0 for i in range(len(testarr)): testarr_=testarr[i] ok=knn(5,testarr_,trainarr,labels) oks.append(ok) print(ok) if ok!=test_labels[i]: t+=1 error_ration=t/len(testarr) print('错误率为'+str(error_ration))