python_手写数字识别案例、手写数字图片处理
1、手写数字识别案例步骤:
收集数据
带有标签的训练数据集来源于trainingDigits文件夹里面所有的文件,接近2000个文件,每个文件中有32*32的二维数组,由01构成,文件名称就是该文件数据对应的标签类型(即一个数字)。处理数据使其符合算法要求
最终我们要求是一个二维数组作为数据源,所以需要将每一个文件对应的特征数据处理成一行,即1*1024,这样所有样本集就变成了2000行的1024列的大二维数组根据以上得到的标签集合和大二维数据数据集,再确定一个k紧邻的k值,就可以作为输入条件进行训练了。给定一个测试文件,将其跟第2步一样处理成为1*1024数组,作为未知样本,然后根据knn分类算法,进行分类操作,算法同电影分类案例。
函数头:def getcls(cur,cls,dataSet,k): def getcls(cur,cls,dataSet,k)
Cur:未知样本,cls:训练数据集标签集合,dataSet:训练数据集 k:最近的几个邻居
‘’’
#coding=utf-8
#手写数字识别案例
import numpy as np
import os
‘’‘fnames为所有的文件名,fname为每一个文件名,vec为一个1*1024的二维数组,f表示整个文件内容,line为某一行’’’
‘’‘函数用来根据样本集合和未知点判断最终未知点所属类别,knn’’’
def knncls(dataSet,cur,labels,k):
#1、判断当前点到每个样本点距离
a=np.tile(cur,(dataSet.shape[0],1)) #重复cur使其dataSet数组的shape相同
#a与dataSet距离
diff=dataSet-a;
diff=diff2 diff=np.sum(diff,axis=1) diff=diff
#对diff进行排序
indexes=np.argsort(diff) #返回值是距离在原来样本集合下标
#寻找前k个邻居的标签都是什么,确定了标签及出现次数{‘爱情’:11,‘动作’:80}
dic={}
for i in range(k):
key=labels[indexes[i]]
dic[key]=dic.get(key,0)+1
#对字典按照value进行排序,次数多的在前面
lst=sorted(dic.items(),key=lambda kv:kv[1],reverse=True)
return lst[0][0]
‘’‘创建一个训练集合20001024,未知数据就是11024’’’
def createDataSet():
#从traningset文件夹读取所有的文件,然后每个文件处理成一个1*1024的数组
fnames=os.listdir(‘D:/trainingDigits’)
dataSet=np.zeros((len(fnames),1024))#训练集合二维数组
labels=[]#分类标签
i=0
for fname in fnames:
#读取这个文件,然后将文件内容转为一维数组
vec=img2vec(‘D:/trainingDigits/’+fname)
dataSet[i,:]=vec[0]
labels.append(fname[0])
i+=1
return dataSet,labels #python可以返回两个值
‘’‘将图片变成一维数组’’’
def img2vec(fname):
#定义一个11024的数组
vec=np.zeros((1,1024))
f=open(fname,‘r’)
row=0
for line in f:
for j in range(32):
vec[0][row32+j]=line[j] #例如vec[0][1]=line[1]
row+=1
return vec
ifname==‘main’:
num=0
i=0
k=input(“请输入k值:”) #提示用户输入k值
k=int(k)
#创建训练集
dataSet,labels=createDataSet()
#定义一个未知数据
tnames=os.listdir(‘D:/testDigits’) #读取testDigits文件
curs=np.zeros((len(tnames),1024))#测试集合二维数组
for tname in tnames:
#读取这个文件,然后将文件内容转为一维数组
cur=img2vec(‘D:/testDigits/’+tname)
curs[i,:]=cur[0] #curs中是所有的文件内容
res=knncls(dataSet,cur,labels,k)
#判断正确的个数用num记录,正确时加一
if tname[0]==res:
num+=1
accuracy=round(100*num/curs.shape[0],3) #计算手写数字识别的正确率,用百分率表示
print(“正确率为:{}%”.format(accuracy))
‘’’
2、手写数字图片处理
处理问题:给定一张图片,对图片进行灰阶处理,然后进行二进制化,最终变成我们knn算法需要的样子。函数:将图片变成01
将处理图片为二进制的函数定义在单独的一个py文件中,形成一个模块,方便别的模块进行导入。
主要的流程就是将图片打开之后,进行降噪处理,然后将其灰度化,最后设置一个阙值将其二值化保存到一个32*32的数组中
import numpy as np
from PIL import Image
import img2vec as pic
import os
‘’‘函数用来根据样本集合和未知点判断最终未知点所属类别,knn’’’
def knncls(dataSet,cur,labels,k):
#1、判断当前点到每个样本点距离
a=np.tile(cur,(dataSet.shape[0],1))
#a与dataSet距离
diff=dataSet-a;
diff=diff2 diff=np.sum(diff,axis=1) diff=diff
#对diff进行排序
indexes=np.argsort(diff) #返回值是距离在原来样本集合下标
#寻找前k个邻居的标签都是什么,确定了标签及出现次数{‘爱情’:11,‘动作’:80}
dic={}
for i in range(k):
key=labels[indexes[i]]
dic[key]=dic.get(key,0)+1
#对字典按照value进行排序,次数多的在前面
lst=sorted(dic.items(),key=lambda kv:kv[1],reverse=True)
return lst[0][0]
‘’‘创建一个训练集合20001024,未知数据就是11024’’’
def createDataSet():
#从traningset文件夹读取所有的文件,然后每个文件处理成一个1*1024的数组
fnames=os.listdir(‘D:/trainingDigits’) #注意是/而不是
dataSet=np.zeros((len(fnames),1024))#训练集合二维数组
labels=[]#分类标签
i=0
for fname in fnames:
#读取这个文件,然后将文件内容转为一维数组
vec=img2vec(‘D:/trainingDigits/’+fname)
dataSet[i,:]=vec
labels.append(fname[0])
i+=1
return dataSet,labels
‘’‘将图片变成一维数组’’’
def img2vec(fname):
#定义一个11024的数组
vec=np.zeros((1,1024))
f=open(fname,‘r’)
row=0
for line in f:
for j in range(32):
vec[0][row32+j]=line[j]
row+=1
return vec
ifname==‘main’:
#创建训练集
dataSet,labels=createDataSet()
#定义一个未知数据
testfile=‘test.png’
#将图片处理成txt文件,里面是0、1
pic.picTo01(testfile)
cur=img2vec(“test.txt”)
res=knncls(dataSet,cur,labels,3)
print(res)
附代码链接:
http://localhost:8888/notebooks/cyl_day4(手写数字识别).ipynb
如果觉得《手写数字识别案例 手写数字图片处理》对你有帮助,请点赞、收藏,并留下你的观点哦!