3、收集和預處理資料
4、訓練和測試
手寫識別是不是很高大上?但是,只要你想學,還是對你很友好的。
python**好啊,python中有好幾種機器學習通用庫,提供了類似於stl那樣的演算法模板函式。由於python函式引數傳遞的特殊用法,它們還支援手動調參。
目前常用的機器學習庫有sklearn(通用機器學習庫)、tensorflow(深度學習庫,支援nvidia的gpu加速)、pytorch(深度學習庫)、keras(也算深度學習庫,特別適合構建神經網路)等。我們用sklearn,它特別適用於解決輕量級、不需要搭建神經網路的機器學習問題,比如簡單的分類和回歸。
如果沒有安裝sklearn,立即開啟命令列,輸入pip install sklearn即可。如果需要國內映象源,輸入pip install sklearn -i --trusted-host mirrors.aliyun.com
我們今天要解決的是手寫阿拉伯數字識別。它是乙個10分類問題(阿拉伯數字只有10個)。
分類是這樣一種問題,對於每乙個資料,都有乙個類別,並且類別的總個數是有限的、離散的。任務是通過一定演算法,根據訓練資料,找到測試資料對應的類別。
再來說一下分類演算法中的資料。資料是乙個復合結構,它包含多個特徵,所以,可以把資料看成向量。向量每個維度(分量)都是乙個特徵。
sklearn已經替我們寫好了k近鄰的實現。我們只需要傳入相關引數,進行訓練和分類**即可。下面就來說說sklearn中相關函式的用法。
這個函式用來建立乙個k近鄰分類器。它位於sklearn.neighbors包中。用法:
knn = sklearn.neighbors.kneighborsclassifier(n_neighbors=
5)
n_neighbors是關鍵字引數,用來指定k的大小,即演算法中選取幾個鄰居。使用時,要在檔案開頭import sklearn.neighbors
。
fit函式是訓練函式,它用於把訓練集的資料和訓練目標(也就是分類的類別)傳入到乙個分類器中。分類器會用乙個**來儲存你傳入的資料,稱之為「學習」。用法:
knn.fit(x_train, y_train)
# knn就是你剛才建立的分類器
說明:
1、x_train必須是二維陣列,稱之為訓練集。每一行表示乙個資料,或稱樣本,比如乙個具體的人;每一列表示資料的乙個特徵,比如,人的「虹膜顏色」、「髮色」、「膚色」三個特徵。
2、y_train必須是一維陣列,稱之為訓練目標。每個元素表示乙個類別。比如,黃種人、白種人、黑種人。
3、使用時,x_train的行必須和y_train對應位置的元素一一對應。比如,x_train的第一行是「黑眼睛」、「黑頭髮」、「黃**」,那麼y_train的第乙個元素就是「黃種人」。
predict是**函式。它的作用是,以剛才訓練好的資料集作為依據,來**新資料的分類結果。x_test必須是乙個二維陣列,稱之為測試集。資料的結構同訓練集。用法:
result = knn.predict(x_test)
它的返回值是乙個一維陣列,也就是對應位置資料的**結果。
它有兩個資料夾,乙個是訓練資料trainingdigits,乙個是測試資料testdigits。我們解壓後,把它們放在py檔案的同級目錄下。注意這一步非常重要,如果目錄放錯,則下面的程式根本無法執行。
每個檔案都是乙個01矩陣,但我們要求乙個資料是乙個一維向量。接下來要解決的是,二維矩陣如何轉化為一維向量。答案就是,按行拼接。比如4*4的矩陣:
0100
0010
0001
1000
拼接成0100001000011000
這樣,它就是乙個具有16個特徵的資料。同理,我們的32階矩陣,就能按行拼接成乙個具有1024個特徵的資料。
我們的每個檔名第乙個字元就是相應的阿拉伯數字,所以將它提取出來,並轉化為整數即可。
編寫乙個遍歷函式,來對每個檔案進行處理:
# 需要import os
defwalk_files
(directory, x, y)
:# x是二維陣列,y是一維陣列
for root, dirs, files in os.walk(directory)
:for filename in files:
vector =
"" fp =
open
(directory +
"\\"
+ filename,
"r")
line = fp.readline(
)while line:
vector += line.strip(
"\n\r"
)# 字串拼接,並去掉換行符
line = fp.readline(
) fp.close(
)# 隨手關閉檔案是乙個好習慣
list
(vector)
)# 字串轉化為陣列,並追加到x之後
int(filename[0]
))# 檔名的第乙個字元就是對應的阿拉伯數字
有了檔案遍歷的函式,我們就可以抓取資料並訓練了。接下來的操作非常簡單。直接上**:
train_dir =
"trainingdigits"
test_dir =
"testdigits"
x_train =
y_train =
x_test =
y_test =
walk_files(train_dir, x_train, y_train)
# 構造訓練集
knn = sklearn.neighbors.kneighborsclassifier(n_neighbors=3)
# 建立分類器
knn.fit(x_train, y_train)
# 訓練
walk_files(test_dir, x_test, y_test)
# 構造測試集
result = knn.predict(x_test)
# **
correct =
0for i in
range(0
,len
(result)):
if result[i]
== y_test[i]
: correct +=
1print
("score: %.3f"
%(correct /
len(result)))
# 檢測**正確率
執行結果:
score: 0.987
錯誤率1.3%。我們圓滿完成了提出的問題。
如果有興趣,可以試試手動調整k(也就是n_neighbors)的數值,看看正確率的變化。我可以把結論先給大家,k=3的時候**效果最好。
最後,我把完整的python**貼給大家:
import os
import sklearn.neighbors
defwalk_files
(directory, x, y)
:for root, dirs, files in os.walk(directory)
:for filename in files:
vector =
"" fp =
open
(directory +
"\\"
+ filename,
"r")
line = fp.readline(
)while line:
vector += line.strip(
"\n\r"
) line = fp.readline(
) fp.close(
)list
(vector)
)int
(filename[0]
))train_dir =
"trainingdigits"
test_dir =
"testdigits"
x_train =
y_train =
x_test =
y_test =
walk_files(train_dir, x_train, y_train)
knn = sklearn.neighbors.kneighborsclassifier(n_neighbors=3)
knn.fit(x_train, y_train)
walk_files(test_dir, x_test, y_test)
result = knn.predict(x_test)
correct =
0for i in
range(0
,len
(result)):
if result[i]
== y_test[i]
: correct +=
1print
("score: %.3f"
%(correct /
len(result)
))
python的最大魅力就在於import,對不對?很簡短,乙個機器學習的程式也就不到40行。 第乙個機器學習演算法,k 近鄰演算法,(一種分類方法)
連線 提取碼 szdg 工作原理 第一 要存在乙個帶標籤的樣本集合。所有樣本對應的類別是已知的 第二 當有乙個新資料輸入後,將新資料的每個特徵與樣本集中中的 每乙個樣本的特徵進行比較。第三 提取最接近的 k 個樣本。一般k 20.第四 在這 k 個樣本中,選取出現最多的類別。作為新資料的分類。優缺點...
機器學習第乙個演算法
單變數線性回歸 導包import numpy as np import matplotlib.pyplot as plt plt.rcparams font.sans serif simhei 正常顯示中文 plt.rcparams axes.unicode minus false 正常顯示符號 讀...
機器學習 k近鄰演算法(分類電影)
案例 利用k近鄰演算法判斷電影類別。假設有如下資料,判斷新電影 打鬥鏡頭24,接吻鏡頭67 應該屬於愛情片還是動作片。繪製圖表如下 k 近鄰演算法步驟如下 1 計算已知類別資料集中的點與當前點之間的距離 2 按照距離遞增次序排序 3 選取與當前點距離最小的k個點 4 確定前k個點所在類別的出現頻率 ...