Python实验--手写五折交叉验证+调库实现SVM/RFC/KNN手写数字识别

2023-10-29

1. 数据读取

先说一下要用到的数据集:

数据集自取地址:

链接:https://pan.baidu.com/s/1Vd2ADHEalSNnuOEcPJD8gQ
提取码:3hk6

数据集构成:

0-9十个数字,总共1934个样本,以数字_n命名,每个样本为32*32大小的txt文件(事先将图片处理后二值化)

数据读取代码:

def img2vector(filename):
    # 创建向量
    returnVect = np.zeros((1, 1024))
    # 打开数据文件,读取每行内容
    fr = open(filename)
    for i in range(32):
        # 读取每一行
        lineStr = fr.readline()
        # 将每行前32字符转成int,存入向量
        for j in range(32):
            returnVect[0, 32 * i + j] = int(lineStr[j])
    return returnVect

最后生成数据集形式:

X:1934*1024的矩阵,每行代表一个样本,1024列为每个样本的1024个像素点(二值表示)

Y:1934*1的矩阵,每一行对应相同下标X中样本的标签

数据集生成代码:
 

def trainData(trainPath):
    trainfile = os.listdir(trainPath)  # 获取训练集文件下的所有文件名
    Y = np.zeros((len(trainfile), 1))
    # 先建立一个行数为训练样本数。列数为1024的0数组矩阵,1024为图片像素总和,即32*32
    X = np.zeros((len(trainfile), 1024))
    # 取文件名的第一个数字为标签名
    for i in range(0, len(trainfile)):
        thislabel = trainfile[i].split(".")[0].split("_")[0]
        if len(thislabel) != 0:
            Y[i][0] = int(thislabel)  # 保存标签
        X[i, :] = img2vector(trainPath + "/" + trainfile[i])  # 将训练数据写入0矩阵
    return X, Y

2. K折交叉验证

关于K折交叉验证的原理其他博文都有详细说明,我这就不赘述了,直接上代码

(本人水平有限,实现方法繁琐,但是能用,手动狗头保命)

代码思路介绍:

1. 将每个数字对应的下标打乱

2. 由于每个数字样本数不一致,这里将其统一到200,不足的随机抽样本补充,多余的随机剔除

3. 按照打乱后的下标生成shuffle后的数据集

4. 按照每个数字40个样本的方式提取出五折子数据集

详细代码:

# import dataset
X, Y = trainData('data1')
size = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] # 保存每个数字的样本数
for i in range(1934):
    size[int(Y[i][0])] += 1


# shuffle and balance
position = []
for i in range(10):
    left = 0
    right = 0
    for k in range(i + 1):
        right += size[k]
    left = right - size[i] # 计算每个数字对应的下标左右边界
    ran = list(range(left, right))
    random.shuffle(ran) # 生成打乱后的下标列表
    if len(ran) < 200:
        for j in range(200 - len(ran)):
            ran.append(np.random.randint(left, right)) # 随机抽取补充
    if len(ran) > 200:
        for j in range(len(ran) - 200):
            del ran[-1] # 随机剔除
    position.append(ran)
X_shuffled = np.zeros((2000, 1024))
for i in range(10):
    for j in range(200):
        x = X[position[i][j]]
        X_shuffled[j + 200*i] = x # 按照打乱后的下标生成新数据集


# split into 5 parts
X_part = []
for i in range(5):
    X_split = np.zeros((400, 1024))
    for j in range(10):
        for k in range(40):
            X_split[(k + 40*j), :] = X_shuffled[(k + 200*j + 40*i), :] 
    X_part.append(X_split)
Y_part = []
for i in range(10):
    for j in range(40):
        Y_part.append(i) #生成对应的标签集

3. 调库实现手写数字识别

1. RFC

# K-Folder
score =[]
for i in range(5):
    X_test = X_part[i]
    Y_test = Y_part
    X_train = np.concatenate((X_part[(i+1) % 5], X_part[(i+2) % 5], X_part[(i+3) % 5], X_part[(i+4) % 5]), axis=0)
    Y_train = Y_test*4
    clf = RandomForestClassifier(n_estimators=200, criterion='gini', max_depth=None,
                                 min_samples_split=3, min_samples_leaf=1, min_weight_fraction_leaf=0.0,
                                 max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0,
                                 min_impurity_split=None, bootstrap=True, oob_score=False, n_jobs=1,
                                 random_state=None, verbose=0, warm_start=False, class_weight=None)
    # train
    clf.fit(X_train, Y_train)
    score.append(clf.score(X_test, Y_test))
    Y_pred = clf.predict(X_test)
    cm = confusion_matrix(Y_test, Y_pred)
    plt.matshow(cm)
    plt.title('epoch %d' % (i + 1))

plt.show()
acc_sum = 0
for i in range(5):
    acc_sum += score[i]
print("Average Acc: %f" % (acc_sum / 5))

2. SVM

score =[]
for i in range(5):
    X_test = X_part[i]
    Y_test = Y_part
    X_train = np.concatenate((X_part[(i+1) % 5], X_part[(i+2) % 5], X_part[(i+3) % 5], X_part[(i+4) % 5]), axis=0)
    Y_train = Y_test*4
    clf = svm.SVC(C=200.0, kernel='rbf', degree=3, gamma='auto',
                  coef0=0.0, shrinking=True, probability=False, tol=0.001,
                  cache_size=200, class_weight=None, verbose=False,
                  max_iter=-1, decision_function_shape='ovr',
                  random_state=None)
    # train
    clf.fit(X_train, Y_train)
    score.append(clf.score(X_test, Y_test))
    Y_pred = clf.predict(X_test)
    cm = confusion_matrix(Y_test, Y_pred)
    plt.matshow(cm)
    plt.title('epoch %d' % (i + 1))

plt.show()
acc_sum = 0
for i in range(5):
    acc_sum += score[i]
print("Average Acc: %f" % (acc_sum / 5))

3. KNN

score =[]
plt.figure()
for i in range(5):
    X_test = X_part[i]
    Y_test = Y_part
    X_train = np.concatenate((X_part[(i+1) % 5], X_part[(i+2) % 5], X_part[(i+3) % 5], X_part[(i+4) % 5]), axis=0)
    Y_train = Y_test*4
    clf = KNeighborsClassifier(n_neighbors=3, weights='uniform',
                               algorithm='auto', leaf_size=30,
                               p=2, metric='minkowski', metric_params=None,
                               n_jobs=None, )
    # train
    clf.fit(X_train, Y_train)
    score.append(clf.score(X_test, Y_test))
    Y_pred = clf.predict(X_test)
    cm = confusion_matrix(Y_test, Y_pred)
    plt.matshow(cm)
    plt.title('epoch %d' % (i+1))
plt.show()
acc_sum = 0
for i in range(5):
    acc_sum += score[i]
print("Average Acc: %f" % (acc_sum / 5))

4. 用到的库列表

# KNN
import random

import numpy as np
import os
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix

# SVM
import random

import numpy as np
import os
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
from sklearn import svm

# RFC
import random

import numpy as np
import os
from sklearn. ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python实验--手写五折交叉验证+调库实现SVM/RFC/KNN手写数字识别 的相关文章

随机推荐

  • 网址与域名的区别

    目录 一 网址与域名的区别 二 主域名与子域名 一 网址与域名的区别 以网址https www baidu com为例 网址由协议加域名组成所以协议是https 域名 www baidu com 区别 1 包含与被包含的关系 网址包含域名
  • 如何判断某个值更改就让按钮可用_【教程】 如何创建自己的 NFT? 这里有份教程, 请收下!...

    AtomicHub 提供了 NFT 创建工具 让任何人都可以创建自己的 NFT 非同质代币 喜欢 NFT 的小伙伴们 一起搞起来吧 除了 WAX 之外 目前 AtomicAssets 也支持了 EOS 区块链 所以 两条链上的朋友都可以参考
  • pandas的定义以及pandas的DataFrame的初步使用(二)

    补充 Series自动对齐 当多个series对象之间进行运算的时候 如果不同series之间具有不同的索引值 那么运算会自动对齐不同索引值的数据 如果某个series没有某个索引值 那么最终结果会赋值为NaN 示例 DataFrame对象
  • 计算机网络c类网络划分子网介绍,IP地址的子网划分详解

    原标题 IP地址的子网划分详解 来源 今日头条北京炫亿时代 一 子网划分基础 1 子网划分的若干个好处 减少网络流量 提高网络性能 简化管理 可以更为灵活的形成大覆盖范围的网络 2 你最好遵循以下步骤来进行子网划分 确认所需要的网络ID数
  • 文件分片上传demo

    知识点 File File 接口也继承了 Blob 接口的属性 File 接口没有定义任何方法 但是它从 Blob 接口继承了以下方法 Blob slice start end contentType new File 字符串数组 file
  • 【C语言】错题本(4)

    一 题目及选项 答案解析 知识点 字符型在内存中的数据存储 char类型数据在内存中的图示 unsigned char类型数据在内存中的图示 二 题目及选项 答案解析 A B C D 三 题目及选项 答案解析 数据在计算机中是先转换成补码
  • @ApiImplicitParam注解使用说明

    ApiImplicitParam注解使用说明 ApiImplicitParam是Swagger框架中的一个注解 用于描述请求参数的详细信息 它可以帮助开发人员生成API文档 并提供给用户更清晰的接口信息 以下是对 ApiImplicitPa
  • 别再乱写了,Controller 层代码这样写才足够规范!

    前言 本篇主要要介绍的就是controller层的处理 一个完整的后端请求由4部分组成 接口地址 也就是URL地址 请求方式 一般就是get set 当然还有put delete 请求数据 request 有head跟body 响应数据 r
  • Deep learning:四十一(Dropout简单理解)

    前言 训练神经网络模型时 如果训练样本较少 为了防止模型过拟合 Dropout可以作为一种trikc供选择 Dropout是hintion最近2年提出的 源于其文章Improving neural networks by preventin
  • 马哥:linux云计算从入门到精通笔记

    前言 Linux可安装在各种计算机硬件设备中 比如手机 平板电脑 路由器 视频游戏控制台 台式计算机 大型机和超级计算机 互联网Linux运维工作 以服务为中心 以稳定 安全 高效为三个基本点 确保公司的互联网业务能够7 24小时为用户提供
  • 密码复杂度(四选三)

    密码复杂度 四选三 数字 大写字母 小写字母 特殊字符 四种里边任选其三 0 9 lt gt A Z W a z W 0 9a z A Z0 9 0 9 lt gt a zA Z a zA Z0 9 lt gt 8 32
  • java 有序列表_Java 中的 List —— 有序序列

    List 在 java 中是个有序序列 一 容量 ArrayList 中有一个容量概念 表示基础数组的大小 无参时默认为 10 在需要的时候 比如 add操作 会自动增加其容量 LinkedList 没有这个概念 TreeMap 也有容量
  • SpringBoot忽略HTTPS请求的SSL证书

    报错如下 java security cert CertificateException No subject alternative names present 解决方案 1 创建SslUtil工具类 import java securi
  • FreeRTOS移植到STM32F103

    1 下载FreeRTOS源码 官网 FreeRTOS官网 下载第一个带有示例的 2 在基础工程文件中创建文件夹FreeRTOS 3 打开下载好的源码 将FreeRTOSv202212 01 FreeRTOS Source 里面的两个文件夹和
  • 软中断 简介

    前言 中断服务程序往往实在CPU关中断的条件下执行的 以避免中断嵌套而使控制复杂化 但是CPU关中断的时间不能太长 否则会丢失中断信号 因此Linux将中断服务程序分为 上半部 和 下半部 前者对时间要求比较严格 必须在中断请求发生后立即
  • linux底线模式,linux编辑命令vi

    vi vim 的使用 基本上 vi vim 共分为三种模式 分别是命令模式 Command mode 输入模式 Insert mode 和底线命令模式 Last line mode 命令模式 以vi打开一个文件就直接进入一般模式了 这是默认
  • Modbus CRC和LRC算法研究及代码实现

    一 CRC 循环冗余校验 1 CRC16实现流程 XOR 异或 N 字节的信息位 POLY CRC16 多项式计算 1010 0000 0000 0001 生成多项式 1 x2 x15 x16 在CRC16中 发送的第一个字节位低字节 2
  • VsCode 搭建 Java 开发环境

    前提 已经安装 jdk 一 vscode 安装插件 1 点击扩展 Ctrl Shift X 2 搜索查找 Java Extension Pack 3 点击安装 注意如果是 jdk 11 可以直接安装 如果是 jdk 8 那么需要先安装 La
  • CAD怎么查询面积

    第一步 打开cad图形 在菜单栏 点击 工具 第二步 调出工具选项 用鼠标指着 查询Q 激活查询命令 第三步 弹出查询的更多功能选项 点击 面积 第四步 这时候使用鼠标拾取需要查询的围成面积的各个关键点 第五步 拾取各个点 围成一个 封闭图
  • Python实验--手写五折交叉验证+调库实现SVM/RFC/KNN手写数字识别

    1 数据读取 先说一下要用到的数据集 数据集自取地址 链接 https pan baidu com s 1Vd2ADHEalSNnuOEcPJD8gQ 提取码 3hk6 数据集构成 0 9十个数字 总共1934个样本 以数字 n命名 每个样