1. 程式人生 > >python資料建模與KNN演算法實現手寫體數字識別

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()