zoukankan      html  css  js  c++  java
  • knn算法手写字识别案例

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    import os
    from sklearn.neighbors  import KNeighborsClassifier
    
    
    def build_data(dir_name):
        """
        构建数据
        :param dir_name: 指定传入文件夹名称
        :return: 构建好的数据
        """
        # 获取文件名列表
        file_name_list = os.listdir(dir_name + "/")
        print("获取到的文件名列表:
    ", file_name_list)
        # 进行读取文件
    
        data = np.zeros(shape=(len(file_name_list), 1025))
    
        # 循环读取文件
        for file_index, file_name in enumerate(file_name_list):
            # file_index  文本名称所对应的下标
            # file_name  文本名称
            # 加载数据
            file_data = np.loadtxt(dir_name + "/" + file_name, dtype=np.str)
    
            # 构建一个列表
            arr = []
            for file_data_index, file_data_content in enumerate(file_data):
                # print(file_data_content)
                # print("*"*80)
                # 将 每一个元素转化为一个int 类型的列表
                arr_sigle_list = [int(tmp) for tmp in file_data_content]
                # print(arr)
                # 把每个元素添加到列表中
                arr.append(arr_sigle_list)
    
            # print(arr)
            # 将一个样本转化为数组
            arr_single_sample = np.array(arr)
            # print(arr_single_sample)
            # np.savetxt("./hh.txt",arr_single_sample,fmt="%d")
            # 将二维数组展开为一维---特征值
            arr_single_sample = arr_single_sample.ravel()
            # print(arr_single_sample)
            # 目标值
            label = int(file_name[0])
            # print(res)
            # print(arr_single_sample.shape)
            # 将一个 完整的样本拼接起来,组成完整的样本
            arr_single_sample = np.concatenate((arr_single_sample, [label]), axis=0)
    
            # print(arr_single_sample)
            # print(arr_single_sample.shape)
    
            data[file_index, :] = arr_single_sample
    
        # print(data)
        return data
    
    
    def save_data(file_name, data):
        """
        保存文件
        :param file_name: 保存的文件名称
        :param data: 保存的数组
        :return: None
        """
        if not os.path.exists("./data/"):
            os.makedirs("./data/")
    
        np.save("./data/" + file_name, data)
    
    
    def load_data(file_name):
        """
        加载数据
        :param file_name:文件路径+ 名称
        :return: 数据
        """
        data = np.load(file_name, allow_pickle=True)
    
        return data
    
    
    def distance(v1, v2):
        """
        计算距离
        :param v1: 点1
        :param v2: 点2
        :return: 距离
        """
        dist = np.sqrt(np.sum(np.power((v1 - v2), 2)))
    
        return dist
    
    
    def knn_owns(train, test, k):
        """
        自定knn算法实现手写字识别
        :param train: 训练集数据
        :param test: 测试集数据
        :param k: 邻居个数
        :return: 准确率
        """
        # 设置计数器
        true_num = 0
        # 获取训练集的特征值 目标值
        train_x = train.iloc[:, :-1].values
        train_y = train.iloc[:, -1].values
        # 获取测试集的特征值 目标值
        test_x = test.iloc[:, :-1].values
        test_y = test.iloc[:, -1].values
        # 计算每一个测试样本特征与每一个训练样本特征的距离
        for i in range(test.shape[0]):  # 循环每一个 测试样本
            for j in range(train.shape[0]):
                # 计算距离
                dist = distance(test_x[i,:],train_x[j,:])
                train.loc[j,'dist'] = dist
    
            res = train.sort_values(by='dist')
    
            mode = res.iloc[:,-2][:k].mode()[0]
    
            if mode == test_y[i]:
                true_num  += 1
            # print(test_y)
    
        score =  true_num / test.shape[0]
    
        print(score)
    
        return  score
    
    
    
    # train_data  = build_data("./trainingDigits")
    # test_data  = build_data("./testDigits")
    #
    # save_data("train_data",train_data)
    # save_data("test_data",test_data)
    
    # 加载数据
    train = load_data("./data/train_data.npy")
    test = load_data("./data/test_data.npy")
    
    train = pd.DataFrame(train)
    test = pd.DataFrame(test)
    
    
    
    # print(train)
    # print("*"*80)
    # print(test)
    k_list = [5,6,7,8,9,10]
    score_list = []
    for k  in k_list:
        # score = knn_owns(train, test, k)
        # score_list.append(score)
        knn = KNeighborsClassifier(n_neighbors=k)
        #训练数据
        knn.fit(train.iloc[:,:-1].values,train.iloc[:,-1].values)
        # 进行预测
        y_predict = knn.predict(test.iloc[:,:-1].values)
    
        # 可以获取准确率
        score = knn.score(test.iloc[:,:-1].values,test.iloc[:,-1].values)
    
        score_list.append(score)
    print(score_list)
    
    
    #进行结果可视化
    # 1、创建画布
    plt.figure()
    # 默认不支持中文,需要配置RC 参数
    plt.rcParams['font.sans-serif']='SimHei'
    # 设置字体之后不支持负号,需要去设置RC参数更改编码
    plt.rcParams['axes.unicode_minus']=False
    # 2、绘图
    x = np.array(k_list)
    y = np.array(score_list)
    
    plt.plot(x,y)
    
    plt.title("k与准确率的关系走势图")
    plt.xlabel("k值")
    plt.ylabel("准确率")
    plt.savefig("./k值对准确率的影响.png")
    # 3、展示
    
    plt.show()
    

      

  • 相关阅读:
    jquery----->helloworld
    hibernate------->第一个程序
    spring使用jdbcTemplate和jdbcdaosupport和namedparameter
    spring--------------->AOP
    spring------>Helloworld
    JS全选
    表单重复提交
    session
    cookies
    83. Remove Duplicates from Sorted List
  • 原文地址:https://www.cnblogs.com/wutanghua/p/11548287.html
Copyright © 2011-2022 走看看