python数据建模与KNN算法实现手写体数字识别

      数据建模指的是对现实世界各类数据的抽象组织,建立一一个适合的模型对数据进行处理。在数据分析与挖掘中,我们通常需要根据一-些数据建 立起特定的模型,然后处理。模型的建立需要依赖于算法, - -般,常见的算法有分类、聚类、关联、回归等。

python数据分类实现过程

       数据分类主要处理现实生活中的分类问题,一般处理思路如下:

1、首先明确需求并对数据进行观察

2、其次,确定算法

3、确定步骤

4、编程实现

常见分类算法:

1、KNN算法   2、贝克斯方法     3、决策树    4、人工神经网络   5、支持向量机(SVM)

KNN算法实现步骤:

  1. 处理数据
  2. 数据向量化
  3. 计算欧几里得距离
  4. 根据距离进行分类

实现代码:

from numpy import *
import operator

#labels为类别名,k为取多少个
def knn(k,testdata,traindata,labels):
    traindatasize=traindata.shape[0]#shape得到多少行多少列
    #tile()函数扩展为相同的维数,第一个参数为要扩展的数据,第二个参数为重复次数
    #tile(a,(2,1))表示从列上扩展,2为重复次数,1表示从列上扩展
    
    dif=tile(testdata,(traindatasize,1))-traindata#dif差值
    sqdif=dif**2
    sumsqdif=sqdif.sum(axis=1)#axis=1表示每一行求和
    distance=sumsqdif**0.5
    sortdistance=distance.argsort()#函数返回原来数组的index
    indices = sortdistance[:k] # 取最小的k个
    count={}
    for i in indices:
        vote=labels[i]
        count[vote]=count.get(vote,0)+1#统计个数
sortcount=sorted(count.items(),key=operator.itemgetter(1),reverse=True)
    return sortcount[0][0]#排序的最终结果

手写体数字识别:

#处理图片,将图片转换为文本形式,用pillow模块

#先将所有图片转为固定宽高,比如32*32,然后在转为文本

from PIL import Image

for i1 in range(1,4):
    for j1 in range(1,6):
        path='E:/programCode/手写数字识别实验/'+str(i1)+'-'+str(j1)+'.png'
        im=Image.open(path)
        #im.save('E:/programCode/9-1.bmp')
        fh=open('E:/programCode/手写数字识别实验/'+str(i1)+'-'+str(j1)+'.txt','a')
        width=im.size[0]#图片的宽
        height=im.size[1]#图片的高
        #k=im.getpixel((1,9))#获得像素的颜色
        for i in range(0,height):
            for j in range(0,width):
                cl=im.getpixel((j,i))
                clall=cl[0]+cl[1]+cl[2]
                if(clall==0):
                    #黑色
                    fh.write('1')
                else:
                    fh.write('0') 
            fh.write('\n')
        fh.close()

knn算法实现手写体数字识别完整代码:

from numpy import *
import operator
from os import listdir
#labels为类别名,k为取多少个
def knn(k,testdata,traindata,labels):
    traindatasize=traindata.shape[0]#shape得到多少行多少列
    #tile()函数扩展为相同的维数,第一个参数为要扩展的数据,第二个参数为重复次数
    #tile(a,(2,1))表示从列上扩展,2为重复次数,1表示从列上扩展
    
    dif=tile(testdata,(traindatasize,1))-traindata#dif差值
    sqdif=dif**2
    sumsqdif=sqdif.sum(axis=1)#axis=1表示每一行求和
    distance=sumsqdif**0.5
    sortdistance=distance.argsort()#函数返回原来数组的index
    indices = sortdistance[:k] # 取最小的k个
    count={}
    for i in indices:
        vote=labels[i]
        count[vote]=count.get(vote,0)+1#统计个数
    sortcount=sorted(count.items(),key=operator.itemgetter(1),reverse=True)
return sortcount[0][0]#排序的最终结果
#手写体数字识别
#加载数据
def datatoarray(fname):
    arr=[]
    fh=open(fname)
    for i in range(0,32):
        thisline=fh.readline()
        for j in range(0,32):
            arr.append(int(thisline[j]))
    return arr
#arr1=datatoarray('E:/programCode/手写数字识别实验/1-1.txt')
#取文件的前缀
def seplabel(fname):
    filestr=fname.split('.')[0]
    label=int(filestr.split('-')[0])
    #print(label)
    return label
#建立训练数据
def traindata():
    labels=[]
    tranfile=listdir('E:/programCode/手写数字识别实验')#listdir()得到所有的文件名
    num=len(tranfile)
    #行的长度1024,每一行存储一个文件
    #用一个数组存储所有训练数据,行:文件总数,列:1024
    trainarr=zeros((num,1024))
    for i in range(0,num):
        thisfname=tranfile[i]
        thislabel=seplabel(thisfname)
        labels.append(thislabel)
        trainarr[i,:]=datatoarray('E:/programCode/手写数字识别实验/'+thisfname)
    return trainarr,labels
#用测试数据调用KNN算法去测试,看是否能够准确识别
def datatest():
    trainarr,labels=traindata()
    testlist=listdir('E:/programCode/test')
    tnum=len(testlist)
    for i in range(0,tnum):
        thistestfile=testlist[i]
        testarr=datatoarray('E:/programCode/test/'+thistestfile)
        rknn=knn(3,testarr,trainarr,labels)
        print(rknn)
datatest()

猜你喜欢

转载自blog.csdn.net/xx20cw/article/details/84887799