实验四 Python聚类决策树训练与预测 基于神经网络的MNIST手写体识别

news2025/3/14 9:02:23

一、实验目的

Python聚类决策树训练与预测:

1、掌握决策树的基本原理并理解监督学习的基本思想。

2、掌握Python实现决策树的方法。

基于神经网络的MNIST手写体识别:

1、学习导入和使用Tensorflow。

2、理解学习神经网络的基本原理。

3、学习使用Python实现MNIST手写体识别。

二、实验原理

        运用Jupyter notebook平台编写实例Python决策树构建、训练、可视化及预测程序。运用Jupyter notebook平台编写实例Python神经网络程序。

三、使用软件平台

1、Windows 11电脑一台。

2、Anaconda、Python、Spyder平台Jupyter notebook平台。

四、实验内容

实例一:

实例1:基于ONE-HOT编码的银行贷款决策树 

基于sklearn库和ONE-HOT编码的决策树,并实现可视化。

要求:

(1)使用pandas读取银行贷款信息数据集。

(2)使用DictVectorizer做数据处理,实现输入特征向量化。

(3)利用sklearn库构建决策树并开展训练。

(4)利用pydotplus库完成决策树可视化。

结果:

代码:

# 导入必要库
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.feature_extraction import DictVectorizer
import matplotlib.pyplot as plt
import matplotlib as mpl
# 自动检测文件编码
import chardet
# 检测文件编码
file_path = 'loan_YN.csv'
with open(file_path, 'rb') as f:
    raw_data = f.read()
    detected_encoding = chardet.detect(raw_data)['encoding']

# 解决中文显示问题
mpl.rcParams['font.sans-serif'] = ['SimHei']  # 使用中文字体(如 SimHei)
mpl.rcParams['axes.unicode_minus'] = False   # 正常显示负号

# 加载数据
data = pd.read_csv('loan_YN.csv', encoding=detected_encoding)  # 自动检测到的编码

# 查看数据前几行
print(data.head())

# 特征和目标变量
X = data[['age', 'income', 'guding', 'VIP']]
y = data['loan']

# 特征向量化(使用 DictVectorizer 进行 ONE-HOT 编码)
vec = DictVectorizer(sparse=False)
X_encoded = vec.fit_transform(X.to_dict(orient='records'))

# 训练决策树
clf = DecisionTreeClassifier(criterion='entropy', max_depth=4, random_state=42)
clf.fit(X_encoded, y)

# 可视化决策树
plt.figure(figsize=(20, 10))
plot_tree(clf, 
          feature_names=vec.get_feature_names_out(), 
          class_names=clf.classes_, 
          filled=True, 
          rounded=True)
plt.title("基于CSV数据的决策树")
plt.show()

思考题:

思考1:基于特征数字化的银行贷款决策树

要求:

(1)利用pandas导入特征数字化的银行贷款数据集,查看并分析数据内容。

(2)参照实例1完成决策树的构建和训练。

(3)利用pydotplus库完成决策树可视化。

(4)观察特征数字化和特征向量化对决策树的影响。

结果:

代码:

# 导入必要库
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_graphviz
import pydotplus

# 加载数据
file_path = 'loan_YN_01.csv'  # 确保路径正确,例如 'C:/path_to_file/loan_YN_01.csv'
data = pd.read_csv(file_path)

# 特征和目标变量分离
X = data[['age', 'income', 'guding', 'VIP']]  # 特征
y = data['loan']  # 目标

# 构建并训练决策树
clf = DecisionTreeClassifier(criterion='entropy', max_depth=5, random_state=42)
clf.fit(X, y)

# 导出决策树为 DOT 格式
dot_data = export_graphviz(
    clf,
    out_file=None,
    feature_names=['age', 'income', 'guding', 'VIP'],  # 特征名
    class_names=['N', 'Y'],  # 类别名
    filled=True,
    rounded=True,
    special_characters=True
)

# 使用 pydotplus 生成图片
graph = pydotplus.graph_from_dot_data(dot_data)

# 保存图片
graph.write_png("decision_tree.png")
print("决策树图片已保存为 decision_tree.png")

实例2:构建、训练、保存神经网络模型,并输出训练及测试准确率。

用Python编程实现,导入TensorFlow包,定义神经网络模型,读取并且输入MNIST数据集的训练图片和标签数据,启动网络训练,输出得到网络不同批次训练的损失值和准确率。

要求:

(1)初始化参数矩阵,定义一个init_weights(shape)函数,使得该函数可以返回一个与输入形状相同的tensor,标准差为0.01,并且利用该函数生成shape=[784, 16]的全连接层1、shape=[16, 16]的全连接层2和shape=[16, 10]的输出层。

(2)初始化网络模型,定义一个按顺序与以上两个全连接层和输出层相乘的神经网络model(x,h1,h2,out),x代表输入训练数据,h1,h2,out分别代表(1)中定义的两个全连接层和输出层,并且返回最终的输出结果。

(3)定义好损失函数、优化器后,设置模型训练的训练次数和每批次送入模型的图片数量,开始模型训练,要求训练次数在代码开始运行后可以从键盘输入。

(4)每隔1000个训练批次输出一次平均损失值和训练准确率,损失值保留6位小数,准确率保留3位小数,最后输出一个平均测试准确率,保留三位小数。

结果:

代码:

import tensorflow as tf
import numpy as np
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
from tqdm import tqdm  # 导入 tqdm 用于进度条

# 导入数据集
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(-1, 784).astype('float32') / 255.0
x_test = x_test.reshape(-1, 784).astype('float32') / 255.0
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)

# 注册自定义类为可序列化对象
@tf.keras.utils.register_keras_serializable()
# 定义模型
class NeuralNetwork(tf.keras.Model):
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        self.dense1 = tf.keras.layers.Dense(16, activation='relu')  # 第一隐藏层
        self.dense2 = tf.keras.layers.Dense(16, activation='relu')  # 第二隐藏层
        self.output_layer = tf.keras.layers.Dense(10)  # 输出层
    def call(self, x):
        x = self.dense1(x)
        x = self.dense2(x)
        return self.output_layer(x)
    def get_config(self):
       """返回模型配置字典"""
       config = super(NeuralNetwork, self).get_config()
       return config
    @classmethod
    def from_config(cls, config):
       """从配置字典恢复模型实例"""
       return cls()

# 自定义回调函数用于输出格式调整和进度条
class ProgressBarCallback(tf.keras.callbacks.Callback):
    def __init__(self, epochs):
        self.epochs = epochs
        self.progress_bar = tqdm(total=epochs, desc="训练进度", unit="epoch")

    def on_epoch_end(self, epoch, logs=None):
        # 更新进度条
        self.progress_bar.update(1)
        # 每 1000 次或最后一次打印日志
        if (epoch + 1) % 1000 == 0 or epoch + 1 == self.epochs:
            print(f"\n第 {epoch + 1} 次训练\t损失值: {logs['loss']:.6f}\t训练准确率: {logs['accuracy']:.3%}")

    def on_train_end(self, logs=None):
        # 关闭进度条
        self.progress_bar.close()

def calculate_average_accuracy(model, x, y, batch_size=128):
    num_batches = len(x) // batch_size
    accuracies = []
    for i in range(num_batches):
        batch_x = x[i * batch_size:(i + 1) * batch_size]
        batch_y = y[i * batch_size:(i + 1) * batch_size]
        _, acc = model.evaluate(batch_x, batch_y, verbose=0)
        accuracies.append(acc)
    return np.mean(accuracies)

# 初始化模型
model = NeuralNetwork()

# 编译模型
model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
    loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
    metrics=['accuracy']
)

# 输入训练次数
epochs = int(input("请输入训练次数: "))

# 训练模型,添加自定义回调和进度条
model.fit(
    x_train, y_train,
    batch_size=128,
    epochs=epochs,
    validation_data=(x_test, y_test),
    callbacks=[ProgressBarCallback(epochs)],
    verbose=0  # 禁用默认输出
)


# 测试集评估
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=0)
# 计算测试集的平均准确率
average_test_acc = calculate_average_accuracy(model, x_test, y_test)

# 打印结果
print(f"测试集整体准确率: {test_acc:.3%}")
print(f"测试集平均准确率: {average_test_acc:.3%}")

# 使用 .keras 扩展名保存为 Keras 推荐的保存格式
model.save("neural_network_plus_model.keras")
print("模型已保存为 neural_network_model.keras")

实例3:可视化模型输出结果和标签。

导入matplotlib.pyplot和numpy,利用实验1中训练好的模型来预测MNIST测试集的图片,并且在得到结果的同时与数据集中的标签进行对比,判断预测是否正确。

要求:

(1)定义图片展示函数display_compare(num),可以通过键盘选择需要预测的图片,num为需要进行预测和判断的图片序号(范围为0-10000)。

(2)将输入图片重构为网络需要的维度([1,784])送入模型进行预测并且保留下来,通过argmax激活函数获得模型的输出数字和实际标签进行比较,判断预测是否正确。

(3)利用matplotlib.pyplot包,展示所预测原始图片(需要将输入重构为28*28大小才能恢复成原始图片样式),并且在图片title处输出预测值和标签和预测是否正确。

结果:

代码:

import tensorflow as tf
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
from tensorflow.keras.models import load_model  # 用于加载模型

# 设置中文字体
matplotlib.rcParams['font.sans-serif'] = ['SimHei']  # 设置字体为黑体
matplotlib.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 加载 .keras 格式
model = load_model("neural_network_model.keras")
print("模型已加载: neural_network_model.keras")
# 加载测试数据
(_, _), (x_test, y_test) = tf.keras.datasets.mnist.load_data()  # 仅加载测试集
x_test = x_test.reshape(-1, 784).astype('float32') / 255.0  # 数据归一化
y_test = tf.keras.utils.to_categorical(y_test, 10)  # One-hot 编码

def display_compare(num):
    """
    可视化预测和标签
    :param num: 测试集中的图片序号
    """
    # 提取图片和标签
    img = x_test[num].reshape(1, 784)
    label = y_test[num]

    # 模型预测
    logits = model(img)
    pred = tf.argmax(logits, axis=1).numpy()[0]
    true_label = tf.argmax(label).numpy()

    # 判断预测是否正确
    is_correct = (pred == true_label)

    # 绘制图片
    plt.imshow(img.reshape(28, 28), cmap='gray')
    plt.title(f"预测值: {pred}, 实际值: {true_label}, 预测{'正确' if is_correct else '错误'}")
    plt.axis('off')
    plt.show()

# 输入图片编号
num = int(input("请输入想要查看的图片编号(0-9999范围): "))
display_compare(num)

注意:必须现有训练模型,才能进行图片判断。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2314774.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【原创】在高性能服务器上,使用受限用户运行Nginx,充当反向代理服务器[未完待续]

起因 在公共高性能服务器上运行OllamaDeepSeek,如果按照默认配置启动Ollama程序,则自己在远程无法连接你启动的Ollama服务。 如果修改配置,则会遇到你的Ollama被他人完全控制的安全风险。 不过,我们可以使用一个方向代理&#…

Spring boot3-WebClient远程调用非阻塞、响应式HTTP客户端

来吧&#xff0c;会用就行具体理论不讨论 1、首先pom.xml引入webflux依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId> </dependency> 别问为什么因为是响应式....…

18 | 实现简洁架构的 Handler 层

提示&#xff1a; 所有体系课见专栏&#xff1a;Go 项目开发极速入门实战课&#xff1b;欢迎加入 云原生 AI 实战 星球&#xff0c;12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力&#xff08;聚焦于 Go、云原生、AI Infra&#xff09;&#xff1b;本节课最终…

coding ability 展开第三幕(滑动指针——基础篇)超详细!!!!

文章目录 前言滑动窗口长度最小的子数组思路 无重复字符的最长子串思路 最大连续1的个数思路 将x减到0的最小操作数思路 总结 前言 前面我们已经把双指针的一些习题练习的差不多啦 今天我们来学习新的算法知识——滑动窗口 让我们一起来探索滑动窗口的魅力吧 滑动窗口 滑动窗口…

如何自己做奶茶,从此告别奶茶店

自制大白兔奶茶&#xff0c;奶香与茶香激情碰撞&#xff0c;每一口都是香浓与甜蜜的双重诱惑&#xff0c;好喝到跺脚&#xff01;丝滑口感在舌尖舞动&#xff0c;仿佛味蕾在开派对。 简单几步就能复刻&#xff0c;成本超低&#xff0c;轻松在家享受奶茶自由。 材料:大白兔奶糖&…

宇树人形机器人开源模型

1. 下载源码 https://github.com/unitreerobotics/unitree_ros.git2. 启动Gazebo roslaunch h1_description gazebo.launch3. 仿真效果 H1 GO2 B2 Laikago Z1 4. VMware: vmw_ioctl_command error Invalid argument 这个错误通常出现在虚拟机环境中运行需要OpenGL支持的应用…

【Linux】浅谈冯诺依曼和进程

一、冯诺依曼体系结构 冯诺依曼由 输入设备、输出设备、运算器、控制器、存储器 五部分组成。 冯诺依曼的设计特点 二进制表示 所有数据&#xff08;包括程序指令&#xff09;均以二进制形式存储和运算&#xff0c;简化了硬件逻辑设计&#xff0c;提高了可靠性。 存储程序原理…

linux操作系统实战

第一题 创建根目录结构中的所有的普通文件 [rootlocalhost ~]# cd /[rootlocalhost /]# mkdir /text[rootlocalhost /]# cd /text[rootlocalhost text]# mkdir /text/boot /text/root /text/home /text/bin /text/sbin /text/lib /text/lib64 /text/usr /text/opt /text/etc /…

浅谈时钟启动和Systemlnit函数

时钟是STM32的关键&#xff0c;是整个系统的心脏&#xff0c;时钟如何启动&#xff0c;时钟源如何选择&#xff0c;各个参数如何设置&#xff0c;我们从源码来简单分析一下时钟的启动函数Systemlnit&#xff08;&#xff09;。 Systemlnit函数简介 我们先来看一下源程序的注释…

MySql学习_基础Sql语句

目录 1.数据库相关概念 2.SQL 2.1 SQL通用语法 2.2 SQL分类 2.3 DDL&#xff08;数据库定义语言&#xff09; 2.4 DML&#xff08;数据操作语言&#xff09; 2.5 DQL&#xff08;数据查询语言&#xff09; 2.6 DCL&#xff08;数据控制语言&#xff09; 3. 函数 3.1 字…

小白学Agent技术[5](Agent框架)

文章目录 Agent框架Single Agent框架BabyAGIAutoGPTHuggingGPTHuggingGPT工作原理说明GPT-EngineerAppAgentOS-Copilot Multi-Agent框架斯坦福虚拟小镇TaskWeaverMetaGPT微软UFOAgentScope现状 常见Agent项目比较概述技术规格和能力实际应用案例开发体验比较ChatChain模式 Agen…

VSTO(C#)Excel开发4:打印设置

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

设计模式Python版 模板方法模式(上)

文章目录 前言一、模板方法模式二、模板方法模式示例 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&#xff1a;关注类和对象之间…

transformer bert 多头自注意力

输入的&#xff08;a1,a2,a3,a4&#xff09;是最终嵌入&#xff0c;是一个(512,768)的矩阵&#xff1b;而a1是一个token&#xff0c;尺寸是768 a1通过wq权重矩阵&#xff0c;经过全连接变换得到查询向量q1&#xff1b;a2通过Wk权重矩阵得到键向量k2&#xff1b;q和k点乘就是值…

python-leetcode-定长子串中元音的最大数目

1456. 定长子串中元音的最大数目 - 力扣&#xff08;LeetCode&#xff09; 可以使用 滑动窗口 方法来解决这个问题。步骤如下&#xff1a; 初始化&#xff1a;计算前 k 个字符中元音字母的个数&#xff0c;作为初始窗口的值。滑动窗口&#xff1a;遍历字符串&#xff0c;每次右…

MySQL增删改查操作 -- CRUD

个人主页&#xff1a;顾漂亮 目录 1.CRUD简介 2.Create新增 使用示例&#xff1a; 注意点&#xff1a; 3.Retrieve检索 使用示例&#xff1a; 注意点&#xff1a; 4.where条件查询 前置知识&#xff1a;-- 运算符 比较运算符 使用示例&#xff1a; 注意点&#xf…

【算法day9】回文数-给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&#xff0c;121 是回文&#…

蛋白质功能预测论文阅读记录2025(DPFunc、ProtCLIP)

前言 最近研究到瓶颈了&#xff0c;怎么优化都提升不了&#xff0c;遂开始看点最新的论文。 DPFunc 2025.1.2 Nature Communication 中南大学 论文地址&#xff1a;DPFunc: accurately predicting protein function via deep learning with domain-guided structure inform…

主流向量数据库对比

在 AI 的 RAG&#xff08;检索增强生成&#xff09;研发领域&#xff0c;向量数据库是存储和查询向量嵌入的核心工具&#xff0c;用于支持高效的语义搜索和信息检索。向量嵌入是文本或其他非结构化数据的数值表示&#xff0c;RAG 系统通过这些嵌入从知识库中检索相关信息&#…

54.HarmonyOS NEXT 登录模块开发教程(八):测试与调试技巧

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT 登录模块开发教程&#xff08;八&#xff09;&#xff1a;测试与调试技巧 文章目录 HarmonyOS NEXT 登录模块开发教程&#xff08;…