訓練之後,即可識別手寫數字如下(我用windows自帶的畫板畫的,可能有點醜,見諒):
等等執行在自己安裝好jupyter的伺服器上,安裝可以參考:
在centos上安裝jupyter notebook (支援外網訪問)
一定要保證路徑正確,如果不希望做任何修改的話,請保證相對路徑如下:
此python檔案
如果遇到環境問題,請自行查資料解決,一般情況下是只需要安裝pillow就可以了,
pip install pillow -i
推薦安裝jupyter,能夠省去很多環境安裝問題
主要包括以下幾部分**:
把txt文字檔案寫入轉換為一維陣列
讀取label(即訓練集的檔名的字首)
knn 演算法
訓練,即把所有訓練集中資料轉換為二維陣列
測試,載入,使用上面的函式檢視識別結果
**如下
from pil import image,imagedraw
import operator
from numpy import
*from os import listdir
# 臨時檔案路徑,表示將轉換成的文字
text_path =
"data/num/test.txt"
# 訓練檔案的路徑
train_path =
"data/num/traindata"
def
image_to_text
(img)
:# resize
img = img.resize((32
,32))
width = img.size[0]
height = img.size[1]
# open 文字檔案進行寫操作
fh =
open
(text_path,
'w')
for j in
range
(height)
:for i in
range
(width)
: rgb = img.getpixel(
(i,j)
) r,g,b = rgb[0]
,rgb[1]
,rgb[2]
if(r==
255and g==
255and b==
255)
: fh.write(
'0')
elif
(r==
0and b==
0and g ==0)
: fh.write(
'1')
# 為了解決既不是白也不是黑的問題
else
: fh.write(
'0')
fh.write(
'\n'
) fh.close(
)
# 讀資料寫入一維陣列
defdatatoarray
(filepath)
: ary=
fh =
open
(filepath)
# 把二維陣列轉換為一維陣列
for i in
range(32
):line = fh.readline(
)for j in
range(32
):int(line[j]))
return ary
#取檔名字首,類似於5_45取5
defseplabel
(fname)
: label=
int(fname.split(
"_")[0
])return label
# knn演算法
defknn
(k,testdata,traindata,labels)
:# 獲得訓練資料的列數(即屬性數目)
traindatasize=traindata.shape[0]
''' 將測試資料(原本只有一行)複製成為traindatasize行,從而方便進行減法運算
舉個例子,測試資料和訓練資料都有n列(即n個屬性),
測試資料只有一行,但是訓練資料卻有k行,為了讓測試資料和所有的訓練資料都進行計算,得到距離
為了方便,擴充一下測試資料就可以了。
列數不變,所以為1
'''
dif = tile(testdata,
(traindatasize,1)
)-traindata
# 計算距離
sqdif = dif**
2 sumsqdif = sqdif.
sum(axis=1)
distance = sumsqdif**
0.5# 排序
sortdistance = distance.argsort(
)# 進行統計
count=
for i in
range(0
,k):
# 按照距離排序後,label中第i個最近的型別 + 1
vote = labels[sortdistance[i]
]# 字典中該元素+1
count[vote]
= count.get(vote,0)
+1# 排序,得到最近次數最多的
sortcount =
sorted
(count.items(
),key=operator.itemgetter(1)
,reverse=
true
)return sortcount[0]
[0]#建立訓練資料
deftraindata()
: labels=
trainfile=listdir(train_path)
num=
len(trainfile)
#長度1024(列),每一行儲存乙個檔案
#用乙個陣列儲存所有訓練資料,行:檔案總數,列:1024
trainarr=zeros(
(num,
1024))
for i in
range(0
,num)
: thisfname=trainfile[i]
thislabel=seplabel(thisfname)
trainarr[i,:]
=datatoarray(train_path+
"/"+thisfname)
return trainarr,labels
# 入口
# 訓練
trainarr,labels=traindata(
)for i in
range(10
):image_path =
"data/num/"
+str
(i)+
"_1.png"
img = image.
open
(image_path,
'r')
image_to_text(img)
# 單個檔案
testarr=datatoarray(text_path)
# knn演算法獲得結果
rknn=knn(
3,testarr,trainarr,labels)
print
(rknn)
'''# 6 7 9
image_path = "data/num/6_2.png"
img = image.open(image_path)
image_to_text(img)
# 單個檔案
testarr=datatoarray(text_path)
# knn演算法獲得結果
rknn=knn(3,testarr,trainarr,labels)
print(rknn)
'''
重點放在knn演算法的應用上,knn演算法很容易理解,也很容易應用。
smileyan2023年12月10日 10:34
手寫數字識別 實戰 KNN演算法識別手寫數字
鄰近演算法,或者說k最近鄰 knn,k nearestneighbor 分類演算法是資料探勘分類技術中最簡單的方法之一。所謂k最近鄰,就是k個最近的鄰居的意思,說的是每個樣本都可以用它最接近的k個鄰居來代表。下面是我學習knn演算法的思維導圖 其中距離的定義,各個距離的公式為 歐氏距離 n維空間的距...
KNN演算法識別手寫數字
前言 從現在開始博主要開始學習機器學習了,歡迎有共同興趣的人一起學習。廢話不多說了,開始上 一 將資料集csv檔案匯入到python中,並將csv格式轉為list格式 def dataset 讀取訓練集檔案路徑 path trains1.csv os.path.abspath machinelear...
KNN演算法識別手寫數字識別集
呼叫sklearn中knn演算法庫,資料級為matlab檔案,使用matplot讀取,並進行一維化處理 from scipy.io import loadmat as load import matplotlib.pyplot as plt from sklearn.neighbors import...