python資料建模與KNN演算法實現手寫體數字識別
阿新 • • 發佈:2018-12-08
資料建模指的是對現實世界各類資料的抽象組織,建立一一個適合的模型對資料進行處理。在資料分析與挖掘中,我們通常需要根據一-些資料建 立起特定的模型,然後處理。模型的建立需要依賴於演算法, - -般,常見的演算法有分類、聚類、關聯、迴歸等。
python資料分類實現過程
資料分類主要處理現實生活中的分類問題,一般處理思路如下:
1、首先明確需求並對資料進行觀察
2、其次,確定演算法
3、確定步驟
4、程式設計實現
常見分類演算法:
1、KNN演算法 2、貝克斯方法 3、決策樹 4、人工神經網路 5、支援向量機(SVM)
KNN演算法實現步驟:
- 處理資料
- 資料向量化
- 計算歐幾里得距離
- 根據距離進行分類
實現程式碼:
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()