機器學習 使用k 近鄰演算法實現手寫識別系統

2021-09-28 18:02:10 字數 3216 閱讀 2365

knn概述

k-近鄰演算法就是通過計算不同特徵值之間的距離來進行分類的演算法。假設我們現在有乙個樣本集,每個樣本都有幾個特徵用來描述這個樣本,以及乙個它所屬分類的標籤。當我們拿到乙個沒有標籤的樣本時,該如何判斷它屬於哪個樣本呢?我們將這個樣本與每乙個已知標籤的樣本做比較,找到相似度最大的k個樣本,記錄它們的標籤。最後,我們統計這些標籤中每個類出現的次數,這個時候我們就有很大把握認為未知樣本屬於出現次數最多的類。

舉乙個電影分類的例子,要區分一部電影是動作片還是愛情片(沒有愛情動作片這個選項!),我們可以根據影片中親吻或者打鬥場景出現的次數來劃分。我們有如下資料集:

在座標系中標出這些樣本

我們計算一下未知樣本到各個樣本的距離,可以發現,未知樣本距離與標籤為愛情片的電影距離較近,於是我們可以認為未知樣本屬於愛情片。

好了,知道了knn的相關概念,我們用經典的手寫識別系統來進行knn演算法實戰

一、匯入樣本

樣本資料格式為32x32的二進位制影象

首先將樣本轉換成1x1024的向量

def

img2vector

(filename)

: vector = zeros((1

,1024))

f =open

(filename)

for i in

range(32

):s = f.readline(

)for j in

range(32

):vector[0,

32* i + j]

=int

(s[j]

)return vector

新增knn分類演算法

def

knn(testset, trainset, label, k)

: m = trainset.shape[0]

# 求歐式距離

diffmat = tile(testset,

(m,1))

- trainset

sqdiffmat = diffmat **

2# 計算每一行的和,即計算未知樣本和每乙個已知樣本的偏差的平方和

sqdistance = sqdiffmat.

sum(axis=1)

# 開根號

distances = sqdistance **

0.5# 將距離從小到大排列,並記錄索引

sorteddistindex = distances.argsort(

)# 建立乙個字典,用來統計投票結果

countdict =

# 記錄距離最近的前k個樣本,並進行投票

for i in

range

(k):

votelabel = label[sorteddistindex[i]

] countdict[votelabel]

= countdict.get(votelabel,0)

+1sortedcount =

sorted

(countdict.items(

), key=operator.itemgetter(1)

, reverse=

true

)return sortedcount[0][0]

新增測試**

def

test()

: label =

# 獲取目錄檔案

filelist = listdir(

"trainingdigits"

) m =

len(filelist)

trainmat = zeros(

(m,1024))

for i in

range

(m):

filename = filelist[i]

# 從檔名獲取樣本標籤

s = filename.split(

".")[0

] nums = s.split(

"_")[0

] trainmat[i,:]

= img2vector(

"trainingdigits/"

+ filename)

filelist = listdir(

"testdigits"

) errorcount =

0.0 m =

len(filelist)

for i in

range

(m):

filename = filelist[i]

s = filename.split(

".")[0

] testlabel = s.split(

"_")[0

] testset = img2vector(

"testdigits/"

+ filename)

result = knn(testset, trainmat, label,3)

print

("truelabel:"

+ testlabel +

" result:"

+ result +

" "+

str(result == testlabel)

)if result != testlabel:

errorcount = errorcount +

1print

("number of errors: "

+str

(errorcount)

)print

("error rate: "

+str

(errorcount / m *

100)

+"%"

)

執行test(),執行結果如下

樣本集以及機器學習實戰這本書的pdf都在這裡,提取碼8v0a

機器學習 k 近鄰演算法(手寫字識別)

knn演算法在簡單二維資料上計算時 d 根號 x0 x 2 y0 y 2 這裡被推廣到1024維,將32 32二進位制當成1 1024的向量。計算上和二維是一樣的。缺點是計算量太大了。usr bin python coding utf 8 用knn識別手寫數字 from numpy import i...

機器學習實戰 使用K 近鄰演算法識別手寫數字

每張都是32畫素x32畫素 def img2vector filename 將32x32的影象轉化為1x1024的向量 param filename return return vect zeros 1,1024 fr open filename for i in range 32 用for lin...

《機器學習實戰》 k 近鄰演算法實現

首先介紹一下k 近鄰演算法的偽 計算已知類別資料集中的點與當前點之間的距離 按照距離遞增次序排序 選取與當前點距離最小的k個點 確定k個點所在的類別出現的頻率 返回前k個點出現頻率最高的類別作為當前點的 分類結果 def classify0 inx,dataset,labels,k datasets...