KNN算法實現數字識別


KNN算法介紹

KNN算法(K-NearestNeighor Algorithm) 是一種最簡單的分類算法。

算法核心:

假設在一個二維坐標平面中已經有了\(n\)個點,每個點的顏色已知,現在給定查詢點\(p\)的坐標\((x,y)\),判斷\(p\)的顏色。

對於已知的\(n\)個點,計算每個點和點\(p\)的歐幾里得距離:

\[dis_i=\sqrt{(x_i-x)^2+(y_i-y)^2} \]

按照\(dis\)從小到大排序,選擇距離最近的前\(k\)個點,在這前k個點中統計顏色出現次數最多的點,則點\(p\)的顏色就被划分為該點的顏色。

數字識別的實現

已有的數據集(TraingData):

若干份txt文件,每份txt文件都是32*32的01矩陣,代表對應的數字,下圖中的矩陣就是數字0:

若干份txt文件,是測試數據集,用於校驗算法的正確率。

算法流程:

  1. 將32x32的矩陣轉換成1x1024的向量
  2. 計算輸入的數據向量和所有的訓練集向量的歐幾里得距離。
  3. 按照歐幾里得距離排序,選前K近的,選擇出現次數最多的作為數字。
  4. 計算正確率

代碼:

import numpy as np
import os
import operator
#返回inputdata所屬的種類
def KNN(inputdata,TrainingSet,lable,k):
	m=TrainingSet.shape[0] #訓練集大小
	difmaze=np.tile(inputdata,(m,1))-TrainingSet #距離矩陣,第i行代表inputdata與第i個訓練樣例的距離
	sqdifmaze=difmaze ** 2## 距離的平方
	sqsum=sqdifmaze.sum(axis=1) ## 計算每一行的和
	distance=sqsum ** 0.5 ## 歐幾里得距離
	sorteddistanceID=distance.argsort() ## 歐幾里得距離從小到大排序后的下標
	classcount={} ## 計數器
	for i in range(k): ## 前k近的lable
		nowlable=lable[sorteddistanceID[i]] ##對每個label計數 
		classcount[nowlable]=classcount.get(nowlable,0)+1
	sortedClasscount=sorted(classcount.items(),key=operator.itemgetter(1),reverse=True)
	return sortedClasscount[0][0] ## 返回出現次數最多的
# 對每個32*32的數字向量化為1*1024的向量
def Vectorfy(filename):
	vec=[]
	fr=open(filename)
	for i in range(32):
		lineStr=fr.readline()
		for j in range(32):
			vec.append(int(lineStr[j]))
	return vec;
def Getlable(filename):
	return filename[0]
# 獲取訓練集	
def TrainingSet():
	Label=[]
	traininglst=os.listdir('trainingDigits')
	m=len(traininglst)
	trainingmat=np.zeros((m,1024))# 訓練矩陣
	for i in range(m):
		filenamestr=traininglst[i]
		Label.append(Getlable(filenamestr))
		trainingmat[i,:]=Vectorfy('trainingDigits/%s' %filenamestr)
	return Label,trainingmat
def Test():#測試測試集
	testlst=os.listdir('testDigits')
	n=len(testlst)
	Lable=[]
	testmat=np.zeros((n,1024))
	for i in range(0,n):
		filenamestr=testlst[i]
		Lable.append(Getlable(filenamestr))
		testmat[i,:]=Vectorfy('testDigits/%s' %filenamestr)
	return Lable,testmat
testlable,testmat=Test()
trainlabel,trainingmat=TrainingSet()
n=testmat.shape[0]
for k in range(1,20):
	err=0.0
	for i in range(n):
		actlable=KNN(testmat[i],trainingmat,trainlabel,k)
		#print("The correct answer is %d and the actual answer is %d" %(int(testlable[i]),int(actlable)))
		if(testlable[i]!=actlable):
			err+=1
	print('k is {} and the correct rate is {}%'.format(k,(n-err)*100/n))

不同K下的正確率


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM