MachineLearning— (KNN)k Nearest Neighbor實現手寫數字識別(三)
本篇博文主要結合前兩篇的knn演算法理論部分knn理論理解(一)和knn理論理解(二),做一個KNN的實現,主要是根據《機器學習實戰》這本書的內容,一個非常經典有趣的例子就是使用knn最近鄰演算法來實現對手寫數字的識別,下面將給出Python程式碼,儘量使用詳盡的解釋和註解讓大家更好地理解每一步的目的和方法,歡迎大家一起交流學習~~~
我們使用的training資料儲存在trainingDigits當中,我們總共使用了100個樣本點資料,從0到9總共十個數字,每個數字有十個手寫資料,所以我們準備了總共100個樣本點來作為基準計算樣本;
而每個手寫數字則是以文字的形式儲存,每一個手寫數字都被提前進行了二值化處理,即只是用0,1兩個數字來表現手寫數字,如下所示:
這樣做的目的顯然可以方便我們將其轉化為特徵行向量進行計算,同時能夠儲存足夠的原資訊量用來進行數字識別;
而測試資料則是儲存在testDigits檔案當中,我們準備了50個樣本點用來測試識別分類效果,十個數字,每個數字有五個測試點,所以我們總共有50個樣本資料;(這裡我們要注意一下檔案的命名格式)
下面給出Python實現程式碼,程式碼主要包括三大塊吧,每一塊主要的功能分別是:
第一塊的目的是要將原本32*32大小的矩陣數字轉化為1*1024的行向量,第二塊是測試分類模組程式(獲得handwritinglabels數字標籤列表 將訓練資料儲存到大矩陣trainingMat當中去)(逐一讀取測試圖片並將其送到classify0分類器當中得出分類識別結果並最終列印結果),第三塊的目的是編寫分類主程式即knn演算法核心部分計算歐氏距離找出k近鄰點並將最多的那個作為測試樣本的識別結果;
<span style="font-size:14px;"># -*- coding: utf-8 -*- #樣本是32*32的二值圖片,將其處理成1*1024的特徵行向量 #第一塊</span> from numpy import * import operator from os import listdir def img2vector(filename): returnVect = zeros((1,1024)) <span style="font-size:14px;">#產生一個數組將來用於儲存圖片資料</span> fr = open(filename) for i in range(32): lineStr = fr.readline() <span style="font-size:14px;">#讀取第一行的32個二值資料</span> for j in range(32): returnVect[0,32*i+j] = int(lineStr[j]) <span style="font-size:14px;">#以32為一個迴圈 逐漸填滿1024個</span> return returnVect <span style="font-size:14px;">#第二塊</span> def handwritingClassTest(): <span style="font-size:14px;">#載入訓練集到大矩陣trainingMat</span> hwLabels = [] trainingFileList = listdir('C:\\Anaconda\\trainingDigits') <span style="font-size:14px;">#os模組中的listdir('str')可以讀取目錄str下的所有檔名,返回一個字串列表</span> m = len(trainingFileList) <span style="font-size:14px;">#m表示總體訓練樣本個數</span> trainingMat = zeros((m,1024)) <span style="font-size:14px;">#用來存放m個樣本</span> for i in range(m): fileNameStr = trainingFileList[i] <span style="font-size:14px;">#訓練樣本的命名格式:1_120.txt 獲取檔名</span> fileStr = fileNameStr.split('.')[0] <span style="font-size:14px;">#string.split('str')以字元str為分隔符切片,返回list,這裡去list[0],得到類似1_120這樣的</span> classNumStr = int(fileStr.split('_')[0]) <span style="font-size:14px;">#以_切片,得到1,即數字類別</span> hwLabels.append(classNumStr) <span style="font-size:14px;">#這樣hwLabels列表中儲存了m個樣本點的所有類別</span> trainingMat[i,:] = img2vector('C:\\Anaconda\\trainingDigits\\%s' % fileNameStr) <span style="font-size:14px;">#將每個樣本存到m*1024矩陣</span> <span style="font-size:14px;">#逐一讀取測試圖片,同時將其分類 </span> testFileList = listdir('C:\\Anaconda\\testDigits') <span style="font-size:14px;">#測試檔名列表 </span> errorCount = 0.0 mTest = len(testFileList) for i in range(mTest): fileNameStr = testFileList[i] <span style="font-size:14px;">#獲取此刻要測試的檔名</span> fileStr = fileNameStr.split('.')[0] classNumStr = int(fileStr.split('_')[0]) <span style="font-size:14px;">#數字標籤分類 重新生成的classNumStr 並沒有使用上面已有的classNumStr</span> vectorUnderTest = img2vector('C:\\Anaconda\\testDigits\\%s' % fileNameStr) <span style="font-size:14px;">#將要測試的數字轉化為一行向量</span> classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3) <span style="font-size:14px;">#傳參</span> print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr) if (classifierResult != classNumStr): errorCount += 1.0 print "\nthe total number of errors is: %d" % errorCount print "\nthe total error rate is: %f" % (errorCount/float(mTest)) <span style="font-size:14px;">#第三塊 #分類主程式,計算歐式距離,選擇距離最小的前k個,返回k箇中出現頻次最高的類別作為分類別 #inX是所要測試的向量 #dataSet是訓練樣本集,一行對應一個樣本,dataSet對應的標籤向量為labels #k是所選的最近鄰數</span> def classify0(inX, dataSet, labels, k): <span style="font-size:14px;">#引數和上面的一一對應</span> dataSetSize = dataSet.shape[0] <span style="font-size:14px;">#shape[0]得出dataSet的行數,即訓練樣本個數 diffMat = tile(inX, (dataSetSize,1)) - dataSet #tile(A,(m,n))將陣列A作為元素構造m行n列的陣列 100*1024的陣列 sqDiffMat = diffMat**2 sqDistances = sqDiffMat.sum(axis=1) #array.sum(axis=1)按行累加,axis=0為按列累加 distances = sqDistances**0.5 #就是sqrt的結果 sortedDistIndicies = distances.argsort() #array.argsort(),得到每個元素按次排序後分別在原陣列中的下標 從小到大排列 classCount={} #sortedDistIndicies[0]表示排序後排在第一個的那個數在原來陣列中的下標 for i in range(k): voteIlabel = labels[sortedDistIndicies[i]] #最近的那個在原來陣列中的下標位置 classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 #一個字典從無到有的生成過程 get(key,x)從字典中獲取key對應的value,沒有key的話返回0 #classCount的形式:{5:3,0:6,1:7,2:1} sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) #sorted()函式,按照第二個元素即value的次序逆向(reverse=True)排序 #sorted第一個引數表示要排序的物件 iteritems代表鍵值對 return sortedClassCount[0][0] #經過sorted後的字典變成了[(),()]形式的鍵值對列表</span>
測試結果:
import knn
knn.handwritingClassTest()
the classifier came back with: 0, the real answer is: 0
the classifier came back with: 0, the real answer is: 0
the classifier came back with: 0, the real answer is: 0
the classifier came back with: 0, the real answer is: 0
the classifier came back with: 0, the real answer is: 0
the classifier came back with: 1, the real answer is: 1
the classifier came back with: 1, the real answer is: 1
the classifier came back with: 1, the real answer is: 1
the classifier came back with: 1, the real answer is: 1
the classifier came back with: 1, the real answer is: 1
the classifier came back with: 2, the real answer is: 2
the classifier came back with: 2, the real answer is: 2
the classifier came back with: 2, the real answer is: 2
the classifier came back with: 2, the real answer is: 2
the classifier came back with: 2, the real answer is: 2
the classifier came back with: 3, the real answer is: 3
the classifier came back with: 3, the real answer is: 3
the classifier came back with: 3, the real answer is: 3
the classifier came back with: 3, the real answer is: 3
the classifier came back with: 3, the real answer is: 3
the classifier came back with: 4, the real answer is: 4
the classifier came back with: 4, the real answer is: 4
the classifier came back with: 4, the real answer is: 4
the classifier came back with: 4, the real answer is: 4
the classifier came back with: 4, the real answer is: 4
the classifier came back with: 5, the real answer is: 5
the classifier came back with: 5, the real answer is: 5
the classifier came back with: 5, the real answer is: 5
the classifier came back with: 5, the real answer is: 5
the classifier came back with: 5, the real answer is: 5
the classifier came back with: 6, the real answer is: 6
the classifier came back with: 6, the real answer is: 6
the classifier came back with: 6, the real answer is: 6
the classifier came back with: 6, the real answer is: 6
the classifier came back with: 6, the real answer is: 6
the classifier came back with: 7, the real answer is: 7
the classifier came back with: 7, the real answer is: 7
the classifier came back with: 7, the real answer is: 7
the classifier came back with: 7, the real answer is: 7
the classifier came back with: 7, the real answer is: 7
the classifier came back with: 8, the real answer is: 8
the classifier came back with: 8, the real answer is: 8
the classifier came back with: 8, the real answer is: 8
the classifier came back with: 8, the real answer is: 8
the classifier came back with: 8, the real answer is: 8
the classifier came back with: 9, the real answer is: 9
the classifier came back with: 9, the real answer is: 9
the classifier came back with: 9, the real answer is: 9
the classifier came back with: 9, the real answer is: 9
the classifier came back with: 9, the real answer is: 9
the total number of errors is: 0
the total error rate is: 0.000000
我們發現準確率還是挺高的,沒有一個錯誤的,原因是我們使用的資料量比較小,恰巧沒有一個錯誤的;
相關推薦
MachineLearning— (KNN)k Nearest Neighbor實現手寫數字識別(三)
本篇博文主要結合前兩篇的knn演算法理論部分knn理論理解(一)和knn理論理解(二),做一個KNN的實現,主要是根據《機器學習實戰》這本書的內容,一個非常經典有趣的例子就是使用knn最近鄰演算法來實現對手寫數字的識別,下面將給出Python程式碼,儘量使用詳盡的解
MNIST手寫數字識別(三)應用優化
本篇的主要內容 應用三種優化方式,對之前的模型進行優化 介紹一些在程式中用到的函式 學習於《TensorFlow實戰Google深度學習框架》一書 程式 相比於第一次的簡單邏輯迴歸模型,這一次的調整了網路結構,添加了一個500個節點的隱藏層,在結構中,設定了
基於tensorflow的MNIST手寫數字識別(三)--神經網路篇
想想還是要說點什麼 抱歉啊,第三篇姍姍來遲,確實是因為我懶,而不是忙什麼的,所以這次再加點料,以表示我的歉意。廢話不多說,我就直接開始講了。 加入神經網路的意義 前面也講到了,使用普通的訓練方法,也可以進行識別,但是識別的精度不夠高,
Matlab實現手寫數字識別(PCA+KNN)
</pre><pre name="code" class="plain">clear; addpath('../data/'); % images_train = loadMNISTImages('train-images-idx3-ubyte')'
KNN演算法——實現手寫數字識別(Sklearn實現)
KNN專案實戰——手寫數字識別 1、資料集介紹 需要識別的數字已經使用圖形處理軟體,處理成具有相同的色彩和大小:寬高是32畫素x32畫素的黑白影象。儘管採用本文格式儲存影象不能有效地利用記憶體空間,但是為了方便理解,我們將圖片轉換為文字格式。 數字的文字格式如下:
MNIST資料集實現手寫數字識別(基於tensorflow)
主要應用了下面幾個方法來提高準確率; 使用隨機梯度下降(batch) 使用Relu啟用函式去線性化 使用正則化避免過擬合 使用帶指數衰減的學習率 使用滑動平均模型 使用交叉熵損失函式來刻畫預測值和真實值之間的差距的損失函式 第一步,匯入MNIST資料集 from
MNIST手寫數字識別(二)幾種模型優化方式介紹
本篇的主要內容有: 動態衰減法設定可變學習率 為損失函式新增正則項 滑動平均模型介紹 為了讓MNIST數字識別模型更準確,學習幾種常用的模型優化手段: 學習率的優化 學習率的設定一定程度上也會影響模型的訓練,如果學習率過小,那麼將會經過很長時間才會收斂到想要
基於tensorflow的MNIST手寫數字識別(二)--入門篇
一、本文的意義 因為谷歌官方其實已經寫了MNIST入門和深入兩篇教程了,那我寫這些文章又是為什麼呢,只是抄襲?那倒並不是,更準確的說應該是筆記吧,然後用更通俗的語言來解釋,並且補充
手寫數字識別(一)
在學習識別手寫輸入數字時,初始化矩陣那裡,有點不理解。原始碼是這樣的:self.biases=[np.random.randn(y,1) for y in sizes[1:]] '''建立一個偏差向量''' self.weights=[np.random.ra
MNIST 手寫數字識別(一)
MNIST 手寫數字識別模型建立與優化 本篇的主要內容有: TensorFlow 處理MNIST資料集的基本操作 建立一個基礎的識別模型 介紹 SoftmaxSoftmaxSoftmax迴歸以及交叉熵等 MNIST是一個很有名的手寫數字識別資料集(基本可以算
機器學習--k-近鄰演算法(kNN)實現手寫數字識別
這裡的手寫數字以0,1的形式儲存在文字檔案中,大小是32x32.目錄trainingDigits有1934個樣本。0-9每個數字大約有200個樣本,命名規則如下: 下劃線前的數字代表是樣本0-9的
MachineLearning— (KNN)k Nearest Neighbor之最近鄰法原理舉例理解(一)
K近鄰法(k-nearest neighbor)是機器學習當中較為簡單理解的一種基本分類與迴歸方法,KNN輸入的是例項的特徵向量,也就是特徵空間上的點;輸出的是其對應的類別標籤,KNN的訓練資料集的
一看就懂的K近鄰演算法(KNN),K-D樹,並實現手寫數字識別!
1. 什麼是KNN 1.1 KNN的通俗解釋 何謂K近鄰演算法,即K-Nearest Neighbor algorithm,簡稱KNN演算法,單從名字來猜想,可以簡單粗暴的認為是:K個最近的鄰居,當K=1時,演算法便成了最近鄰演算法,即尋找最近的那個鄰居。 用官方的話來說,所謂K近鄰演算法,即是給定一個訓練資
各種機器學習方法(線性迴歸、支援向量機、決策樹、樸素貝葉斯、KNN演算法、邏輯迴歸)實現手寫數字識別並用準確率、召回率、F1進行評估
本文轉自:http://blog.csdn.net/net_wolf_007/article/details/51794254 前面兩章對資料進行了簡單的特徵提取及線性迴歸分析。識別率已經達到了85%, 完成了數字識別的第一步:資料探測。 這一章要做的就各
學習KNN(三)KNN+HOG實現手寫數字識別
在學習KNN(二)KNN演算法手寫數字識別的OpenCV實現我們直接將畫素值作為特徵,實現了KNN演算法的手寫數字識別問題,並得到了較好的準確率,但是就像其他機器學習演算法一樣,KNN的物件同樣是特徵,所以我們可以用一種特徵提取演算法配合KNN實現手寫數字識
第二節,TensorFlow 使用前饋神經網絡實現手寫數字識別
com net config return pyplot dataset 運行 算法 但是 一 感知器 感知器學習筆記:https://blog.csdn.net/liyuanbhu/article/details/51622695 感知器(Percep
第三節,TensorFlow 使用CNN實現手寫數字識別
啟用 out min 灰度 HA 打破 gre 大量 gray 上一節,我們已經講解了使用全連接網絡實現手寫數字識別,其正確率大概能達到98%,著一節我們使用卷積神經網絡來實現手寫數字識別, 其準確率可以超過99%,程序主要包括以下幾塊內容 [1]: 導入數據,即測試集和
TensorFlow(九):卷積神經網絡實現手寫數字識別以及可視化
writer orm true 交叉 lar write 執行 one 界面 上代碼: import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data mnist =
TensorFlow(十二):使用RNN實現手寫數字識別
rop mea pre rnn ext ini tro truncate tutorial 上代碼: import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data #
10 行程式碼,實現手寫數字識別
識別手寫的阿拉伯數字,對於人類來說十分簡單,但是對於程式來說還是有些複雜的。 不過隨著機器學習技術的普及,使用10幾行程式碼,實現一個能夠識別手寫數字的程式,並不是一件難事。這是因為有太多的機器學習模型可以拿來直接用,比如tensorflow、caffe,在python下