機器學習之KNN-手寫數字識別

操作平臺: windows10, python37, jupyter
數據下載: https://www.lanzous.com/iae2wyh


1、讀取數據

  • 這些數據全部都是圖片,從0~9,一個數字共500張,並且每個數字圖片都在對應的文件夾下,以 自身值_序號.bmp 的方式進行命名,如圖:

● data文件夾下:
在這裏插入圖片描述


● 0文件夾下:
在這裏插入圖片描述


1.1、導入相關庫

import numpy as np
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
%matplotlib inline

1.2、讀取一張圖片測試

img = plt.imread('./data/0/0_1.bmp')
plt.imshow(img,cmap = plt.cm.gray) #這些圖片都是黑白的,

在這裏插入圖片描述


1.3、讀取所有圖片

data = []
for i in range(10):
    for j in range(1,501):
        data.append(plt.imread('./data/%d/%d_%d.bmp'%(i,i,j)))

查看data大小:

len(data)
5000


2、數據預處理

2.1、list轉numpy

  • 上面得到的data是list類型,但是圖片是用維度的,需要把它的數據還原。
# 數據
X = np.array(data)
X.shape
(5000, 28, 28)

2.2、添加對應數字

  • 上面得到的信息只是圖片本身的數據,但是卻不明確是哪個數字,所以必須給它指定,並賦值給 y。

(1)構造數組

y = [0,1,2,3,4,5,6,7,8,9]*500
y

結果:從0-9,0-9,0-9,一共500次。總共有5000個數值。


(2)數組轉numpy

y = np.array(y)
y
array([0, 1, 2, ..., 7, 8, 9])

(3)排序

  • 因爲上面的data是每一個文件夾分別讀取的,一樣的數值就在一起了,前500個全是0, 第二個500全是1… …,我們只需要y排序就可以對應它的值了。
y.sort()
y
array([0, 0, 0, ..., 9, 9, 9])


3、隨機抽取訓練集與測試集

  • 隨機抽樣,不影響算法,算法根據距離來進行
  • 訓練集和測試集可能會被重複抽取到
index = np.random.randint(0,5000,size = 4000)#隨機抽取80%來訓練

X_train = X[index]
y_train = y[index]

index = np.random.randint(0,5000,size = 1000) #隨機抽取20%來測試

X_test = X[index]
y_test = y[index]

(1)查看數據形狀

在這裏插入圖片描述
結果分析: x的訓練集和y的訓練集數據維度不能對應,x是3維的,y屬於1維的,必須要把它統一維度才能進行運算,接下了對x進行降維處理。


(2)降維處理

  • 每張圖片的分辨率都是28*28,相乘等於784
X_train.reshape(4000,784)
array([[255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255],
       ...,
       [255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255],
       [255, 255, 255, ..., 255, 255, 255]], dtype=uint8)



4、訓練模型並預測

4.1、訓練模型

%%time
knn = KNeighborsClassifier(n_neighbors=5)#鄰近值個數爲5

knn.fit(X_train.reshape(4000,-1),y_train) #如果不想計算出28*28=784,可以直接用-1代替784
Wall time: 1.97 s
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
                     metric_params=None, n_jobs=None, n_neighbors=5, p=2,
                     weights='uniform')

4.2、預測

%%time  #耗時Wall time: 12.1 s
# 預測
y_ = knn.predict(X_test.reshape(1000,784))

查看前20個結果:
在這裏插入圖片描述

4.3、計算準確率

(1)方法一

(y_test == y_).mean()
0.931

(2)方法二

knn.score(X_test.reshape(1000,-1),y_test)
0.931



4.4、精確度調整

%%time
# n_neighbors=鄰近值,weights=權重, p = 距離,n_jobs=線程
knn = KNeighborsClassifier(n_neighbors=5,weights='distance', p = 1,n_jobs=-1)

knn.fit(X_train.reshape(4000,-1),y_train) #訓練模型

# predict ,計算準確率
knn.score(X_test.reshape(1000,-1),y_test)
Wall time: 3.88 s

0.953



5、識別某張圖片

5.1、讀取圖片

img = plt.imread('./data/9/9_1.bmp') #隨便讀取一張圖片
plt.imshow(img,cmap = plt.cm.gray) #展示
plt.show()

在這裏插入圖片描述

5.2、識別數字

knn.predict(img.reshape(1,-1))[0]
9
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章