机器学习实战——使用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-近邻算法必须保存全部数据集,如果训练数据集很大,必须使用大量的存储空间。另外,由于必须对数据集中每个数据计算距离,实际使用可能非常耗时。


你可能感兴趣的:(python,机器学习,knn,手写识别)