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

使用K-近鄰分類器構造手寫識別系統,手寫數字圖片已經經過處理成爲文本文件,如下所示:


每張圖片都是32像素X32像素

首先,我們要把每個輸入的文本文件轉換KNN算法(前面的KNN算法實踐已經有了,這裏就不貼了)可以處理的格式,即一維數組的形式,定義以下函數:

def img2vector(filename):
    """
    將32x32的圖像轉化爲1x1024的向量
    :param filename:
    :return:
    """
    return_vect = zeros((1, 1024))
    fr = open(filename)
    for i in range(32):              # 用for line in readlines()也可以
        line_str = fr.readline()      # 一行一行的讀
        for j in range(32):
            return_vect[0, 32*i+j] = int(line_str[j])
    fr.close()
    return return_vect

有了上面的函數,就可以設計循環,把訓練集,測試集,標籤都準備成KNN算法輸入的標準格式了

這裏標籤的提取需要從文件名稱中提取,比如文件名稱爲‘0_23.txt’,則表示這個圖像的正確分類爲數字‘0’

代碼如下:

from kNN import classify0
from numpy import *
from os import listdir
# 手寫數字識別系統測試代碼
def handwriting_class():
    hw_labels = []
    training_file_list = listdir('trainingDigits')    # 獲取目錄下的文件名
    m = len(training_file_list)
    training_mat = zeros((m, 1024))
    for i in range(m):
        file_name_str = training_file_list[i]
        file_str = file_name_str.split('.')[0]
        class_num = int(file_str.split('_')[0])
        hw_labels.append(class_num)
        training_mat[i, :] = img2vector(r'trainingDigits/%s' % file_name_str)
    test_file_list = listdir('testDigits')
    error_count = 0.0
    m_test = len(test_file_list)
    for i in range(m_test):
        file_name_str = test_file_list[i]
        file_str = file_name_str.split('.')[0]
        class_num = int(file_str.split('_')[0])
        vector_under_test = img2vector(r'testDigits/%s' % file_name_str)
        classifier_result = classify0(vector_under_test, training_mat, hw_labels, 3)
        print 'the classifier came back with: %d, the real answer is: %d' % (classifier_result, class_num)
        if classifier_result != class_num:
            error_count += 1.0
    print '\nthe total number of errors is : %d' % error_count
    print '\nthe total error rate is : %f' % (error_count/float(m_test))

handwriting_class()

運行結果:


錯誤率達到1.8%,很不錯的結果(這是K選5的結果)

改變變量K的值,改變訓練樣本的數目,都會對結果有影響。

實際使用這個算法時,發現算法速度比較慢,因爲每個測試樣本都要與訓練樣本做距離計算,計算量非常大

K-近鄰算法必須保存全部數據集,如果訓練數據集很大,必須使用大量的存儲空間。另外,由於必須對數據集中每個數據計算距離,實際使用可能非常耗時。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章