KNN手写体数字识别

KNN手写体数字识别

思路:首先这是一个通过KNN分类来完成的数字识别,数据集的格式全部是经过处理后的32x32de1二进制数字矩阵,把一个样本(32x32)转化为1x1024的向量,即一行代表一个样本,然后把训练样本也转化为一个数字矩阵,每次输入一个测试集都与训练集的矩阵进行作差,然后平方和开根号,最后将每一个输入的测试集进行比较,和哪个差值最小(即形状最相似)即为哪一类(0~9)

'''KNN算法实现手写体数字识别'''
import numpy as np
from os import listdir
import operator

def img2vector(filename):
    """实现将图片转换为向量形式"""
    return_vector = np.zeros((1, 1024))
    fr = open(filename)
    for i in range(32):
        line = fr.readline()
        for j in range(32):
            return_vector[0, 32*i + j] = int(line[j])
    return return_vector


# inX 用于分类的输入向量
# dataSet表示训练样本集
# 参数k表示选择最近邻居的数目
def classify0(inx, data_set, labels, k):
    """实现knn"""
    diff_mat = inx - data_set   # 各个属性特征做差
    sq_diff_mat = diff_mat**2  # 各个差值求平方
    sq_distances = sq_diff_mat.sum(axis=1)  # 按行求和
    distances = sq_distances**0.5   # 开方
    sorted_dist_indicies = distances.argsort()  # 按照从小到大排序,并输出相应的索引值
    class_count = {}  # 创建一个字典,存储k个距离中的不同标签的数量

    for i in range(k):
        vote_label = labels[sorted_dist_indicies[i]]  # 求出第i个标签
        # 访问字典中值为vote_label标签的数值再加1,
        class_count[vote_label] = class_count.get(vote_label, 0)+1
    # 将获取的k个近邻的标签类进行排序
    # print(class_count)
    sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1), reverse=True)
    # 标签类最多的就是未知数据的类
    return sorted_class_count[0][0]


def hand_writing_class_test():
    hand_writing_labels = []  # 手写数字类别标签
    training_file_list = listdir('G:\\YJS\\datatra\\KNN\\trainingDigits')  # 获得文件中目录列表,训练数据集
    m = len(training_file_list)   # 求得文件中目录文件个数(训练数据集)
    training_mat = np.zeros((m, 1024))  # 创建训练数据矩阵,特征属性矩阵

    for i in range(m):
        file_name_str = training_file_list[i]  # 获取单个文件名
        file_str = file_name_str.split(' ')[0]  # 将文件名中的空字符去掉,这里的[0]是将文件名取出来
        class_num_str = int(file_str.split('_')[0])  # 取出数字类别
        hand_writing_labels.append(class_num_str)  # 将数字类别添加到类别标签矩阵中

        # 将图像格式转换为向量形式
        training_mat[i, :] = img2vector('G:\\YJS\\datatra\\KNN\\trainingDigits\%s' % file_name_str)

    test_file_list = listdir('G:\\YJS\\datatra\\KNN\\testDigits')  # 获得文件中目录列表,测试数据集
    error_count = 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_str = int(file_str.split('_')[0])
        # 将图像格式转换为向量形式(测试数据集)
        vector_under_test = img2vector('G:\\YJS\\datatra\\KNN\\testDigits\%s' % file_name_str)
        # KNN分类,以测试数据集为未知数据,训练数据为训练数据
        classifier_result = classify0(vector_under_test, training_mat, hand_writing_labels, 3)
        # 输出分类结果和真实类别
        print('分类结果: %d, 真实结果: %d' % (classifier_result, class_num_str))
        # 计算错误分类个数
        if classifier_result != class_num_str:
            error_count += 1

    # 输出错误分类个数和错误率
    print("\n 错误分类个数 is: %d" % error_count)
    print("\n 错误率: %f" % (error_count/float(m_test)))


# 调用手写识别
if __name__=='__main__':
    hand_writing_class_test()
    print("--end--")


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值