深度学习R7周:糖尿病预测模型优化探索

server/2025/2/27 8:48:04/
  • 🍨 本文为🔗365天深度学习训练营中的学习记录博客
  • 🍖 原作者:K同学啊

学习目标:

思考本案例是否还有进一步优化的空间

环境:

语言环境:Python3.8

编译器:pycharm

深度学习环境:pytorch

1.数据预处理

1.1 设置GPU

#设置GPU
import torch.nn as nn
import torch.nn.functional as F
import torchvision,torchdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")print(device)

结果输出:

1.2数据导入

#导入数据
import numpy   as np
import pandas  as pd
import seaborn as sns
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
plt.rcParams['savefig.dpi'] = 500 #图片像素
plt.rcParams['figure.dpi'] = 500 #分辨率plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签import warnings
warnings.filterwarnings('ignore')DataFrame = pd.read_excel('/pythonProject/dia.xls')
print(DataFrame.head())
print(DataFrame.shape)

结果输出:

1.3数据检查

#查看数据是否有缺失值
print('数据缺失值--------------------------')
print(DataFrame.isnull().sum())#查看数据是否有重复值
print('数据重复值--------------------------')
print('数据集的重复值为:'f'{DataFrame.duplicated().sum()}')

结果输出:

 

2.数据分析

2.1数据分布分析

feature_map = {'年龄': '年龄','高密度脂蛋白胆固醇': '高密度脂蛋白胆固醇','低密度脂蛋白胆固醇': '低密度脂蛋白胆固醇','极低密度脂蛋白胆固醇': '极低密度脂蛋白胆固醇','甘油三酯': '甘油三酯','总胆固醇': '总胆固醇','脉搏': '脉搏','舒张压': '舒张压','高血压史': '高血压史','尿素氮': '尿素氮','尿酸': '尿酸','肌酐': '肌酐','体重检查结果': '体重检查结果'}plt.figure(figsize=(15, 10))for i, (col, col_name) in enumerate(feature_map.items(), 1):plt.subplot(3, 5, i)sns.boxplot(x=DataFrame['是否糖尿病'], y=DataFrame[col])plt.title(f'{col_name}的箱线图', fontsize=14)plt.ylabel('数值', fontsize=12)plt.grid(axis='y', linestyle='--', alpha=0.7)plt.tight_layout()
plt.show()

结果输出:一直找怎么解决字体变大问题,但都没找到,猜测是不是电脑问题

 

2.2相关性分析

#相关性分析
import plotly
import plotly.express as px#删除列“卡号”
DataFrame.drop(columns=['卡号'], inplace =True)
#计算各列之间的相关系数
df_corr = DataFrame.corr()#相关矩阵生成函数
def corr_generate(df):fig = px.imshow(df,text_auto=True, aspect="auto", color_continuous_scale= 'RdBu_r')fig.show()#生成相关矩阵
corr_generate(df_corr)

结果分析:

 

三、LSTM模型

3.1划分数据集

#划分数据集
from sklearn.preprocessing import StandardScaler# '高密度脂蛋白胆固醇'字段与糖尿病负相关,故而在 X 中去掉该字段
X = DataFrame.drop(['卡号','是否糖尿病','高密度脂蛋白胆固醇'],axis=1)
y = DataFrame['是否糖尿病']# 数据集标准化处理
sc_X    = StandardScaler()
X = sc_X.fit_transform(X)X = torch.tensor(np.array(X), dtype=torch.float32)
y = torch.tensor(np.array(y), dtype=torch.int64)train_X, test_X, train_y, test_y = train_test_split(X, y,test_size=0.2,random_state=1)
print(train_X.shape, train_y.shape)

3.2数据集构建

#数据集构建
from torch.utils.data import TensorDataset, DataLoadertrain_dl = DataLoader(TensorDataset(train_X, train_y),batch_size=64,shuffle=False)
test_dl  = DataLoader(TensorDataset(test_X, test_y),batch_size=64,shuffle=False)

3.3定义模型

# 定义模型
class model_lstm(nn.Module):def __init__(self):super(model_lstm, self).__init__()self.lstm0 = nn.LSTM(input_size=13, hidden_size=200, num_layers=1, batch_first=True)self.lstm1 = nn.LSTM(input_size=200, hidden_size=200, num_layers=1, batch_first=True)self.fc0 = nn.Linear(200, 2)def forward(self, x):out, hidden1 = self.lstm0(x)out, _ = self.lstm1(out, hidden1)out = self.fc0(out)return outmodel = model_lstm().to(device)
print(model)

结果输出:

 

4.训练模型

4.1定义训练函数

# 定义训练函数
def train(dataloader, model, loss_fn, optimizer):size = len(dataloader.dataset)  # 训练集的大小num_batches = len(dataloader)  # 批次数目, (size/batch_size,向上取整)train_loss, train_acc = 0, 0  # 初始化训练损失和正确率for X, y in dataloader:  # 获取图片及其标签X, y = X.to(device), y.to(device)# 计算预测误差pred = model(X)  # 网络输出loss = loss_fn(pred, y)  # 计算网络输出和真实值之间的差距,targets为真实值,计算二者差值即为损失# 反向传播optimizer.zero_grad()  # grad属性归零loss.backward()  # 反向传播optimizer.step()  # 每一步自动更新# 记录acc与losstrain_acc += (pred.argmax(1) == y).type(torch.float).sum().item()train_loss += loss.item()train_acc /= sizetrain_loss /= num_batchesreturn train_acc, train_loss

4.2定义测试函数

# 定义测试函数
def test(dataloader, model, loss_fn):size = len(dataloader.dataset)  # 测试集的大小num_batches = len(dataloader)  # 批次数目, (size/batch_size,向上取整)test_loss, test_acc = 0, 0# 当不进行训练时,停止梯度更新,节省计算内存消耗with torch.no_grad():for imgs, target in dataloader:imgs, target = imgs.to(device), target.to(device)# 计算losstarget_pred = model(imgs)loss = loss_fn(target_pred, target)test_loss += loss.item()test_acc += (target_pred.argmax(1) == target).type(torch.float).sum().item()test_acc /= sizetest_loss /= num_batchesreturn test_acc, test_loss

4.3训练模型

# 训练模型
loss_fn = nn.CrossEntropyLoss()  # 创建损失函数
learn_rate = 1e-4  # 学习率
opt = torch.optim.Adam(model.parameters(), lr=learn_rate)
epochs = 30train_loss = []
train_acc = []
test_loss = []
test_acc = []for epoch in range(epochs):model.train()epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)model.eval()epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)train_acc.append(epoch_train_acc)train_loss.append(epoch_train_loss)test_acc.append(epoch_test_acc)test_loss.append(epoch_test_loss)# 获取当前的学习率lr = opt.state_dict()['param_groups'][0]['lr']template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%, Test_loss:{:.3f}, Lr:{:.2E}')print(template.format(epoch + 1, epoch_train_acc * 100, epoch_train_loss,epoch_test_acc * 100, epoch_test_loss, lr))print("=" * 20, 'Done', "=" * 20)

结果输出:

 

5.模型评估

5.1Loss与Accuracy图

#Loss与Accuracy图
import matplotlib.pyplot as plt
#隐藏警告
import warnings
warnings.filterwarnings("ignore")               #忽略警告信息
plt.rcParams['font.sans-serif']    = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False      # 用来正常显示负号
plt.rcParams['figure.dpi']         = 100        #分辨率from datetime import datetime
current_time = datetime.now()epochs_range = range(epochs)plt.figure(figsize=(12, 3))
plt.subplot(1, 2, 1)plt.plot(epochs_range, train_acc, label='Training Accuracy')
plt.plot(epochs_range, test_acc, label='Test Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.xlabel(current_time)plt.subplot(1, 2, 2)
plt.plot(epochs_range, train_loss, label='Training Loss')
plt.plot(epochs_range, test_loss, label='Test Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()

结果输出:

6.总结

根据数据,可以看到,划分数据集后添加标准化处理,对精度是有一定改善的。但看图,仍存在有一定的过拟合现象,这是还需要再改进的,可能可以考虑正则化方法或者增加数据量的方法缓解过拟合问题。

在划分数据集过程中添加标准化处理可以提升测试数据集准确率的原因主要有以下几点:

消除量纲影响:

1.不同特征往往具有不同的量纲和尺度。例如,一个特征可能取值范围在 0 到 100 之间,而另一个特征可能取值在 0 到 1 之间。这会使得在某些算法中,具有较大数值范围的特征对模型的影响更大,从而可能导致模型偏向于这些特征,而忽略了其他重要特征的作用。

2.标准化处理将数据的各个特征转换到相同的尺度上,通常使得特征的均值为 0,标准差为 1。这样可以确保每个特征在模型中具有相对平等的影响力,避免了因量纲差异而导致的不公平性。

加速模型收敛

1.许多优化算法在处理标准化后的数据时能够更快地收敛。例如,梯度下降算法在标准化的数据上能够更有效地确定下降的方向和步长,因为数据的分布更加稳定,不会因为特征的尺度差异而导致梯度在不同方向上的变化幅度差异巨大。
2.当数据经过标准化后,模型在训练过程中可以更稳定地更新参数,减少了因数据尺度不一致而引起的震荡,从而更快地找到最优解,这也有助于提高模型在测试集上的准确率。

③提高模型泛化能力

1.标准化可以使模型对不同单位和尺度的输入数据具有更好的适应性,从而提高模型的泛化能力。如果模型在训练时只适应了特定尺度的数据集,那么在面对测试集上不同尺度的数据时,可能表现不佳。
2.标准化处理可以减少异常值对模型的影响。异常值在未标准化的数据中可能会对模型产生较大的干扰,而经过标准化后,异常值的影响相对减小,模型能够更加关注数据的整体分布特征,从而提高在测试集上的准确率。

此部分来自:R6:LSTM实现糖尿病探索与预测_lstm疾病预测-CSDN博客

 


http://www.ppmy.cn/server/170988.html

相关文章

开源程序wordpress在海外品牌推广中的重要作用

WordPress作为全球最流行的开源内容管理系统(CMS),在全球网站搭建中占据超过40%的市场份额。其强大的功能、灵活性和易用性使其成为企业进行海外品牌推广的首选平台。以下是WordPress在海外品牌推广中的重要性分析: 1. 多语言支持与本地化 WordPress通…

京准电钟:NTP精密时钟服务器在自动化系统中的作用

京准电钟:NTP精密时钟服务器在自动化系统中的作用 京准电钟:NTP精密时钟服务器在自动化系统中的作用 NTP精密时钟服务器在自动化系统中的作用非常重要,特别是在需要高精度时间同步的场景中。NTP能够提供毫秒级的时间同步精度,这…

STM32编译过程

STM32编译过程 1. 编译过程介绍2. 程序的组成、存储与运行3. 编译工具链3.1 armcc 工具3.2 armasm 工具3.3 armlink 工具3.4 armar 工具3.5 fromelf 工具 4. MDK工程的文件类型 1. 编译过程介绍 编译MDK 软件使用的编译器是 armcc 和 armasm,它们根据每个 c/c 和汇编…

Qt 中实现链表

Qt 中实现链表&#xff0c;我将使用模板类来支持泛型数据&#xff0c;并通过封装确保数据安全。 完整实现代码 #include <QCoreApplication> #include <QDebug> #include <functional> // 用于遍历时的回调函数template<typename T> class LinkedLis…

二叉树中的深搜(典型算法思想)—— OJ例题算法解析思路

目录 一、2331. 计算布尔二叉树的值 - 力扣&#xff08;LeetCode&#xff09; 算法代码&#xff1a; 代码思路概述 详细代码逻辑解释 节点定义 求值函数 基线条件 递归步骤 逻辑操作 总结 二、129. 求根节点到叶节点数字之和 - 力扣&#xff08;LeetCode&#xff09…

2025中国经济白皮书赋能CES Asia,国际合作成新亮点

近日&#xff0c;2025年中国经济白皮书的发布&#xff0c;为第七届亚洲消费电子技术贸易展&#xff08;CES Asia 2025&#xff09;的招商工作带来了重大利好消息&#xff0c;其在国际合作方面展现出的显著优势&#xff0c;成为吸引全球企业参与的重要因素。 白皮书重申了中国坚…

将VsCode变得顺手好用(1

目录 设置中文 配置调试功能 提效和增强相关插件 主题和图标相关插件 创建js文件 设置中文 打开【拓展】 输入【Chinese】 下载完成后重启Vs即可变为中文 配置调试功能 在随便一个位置新建一个文件夹&#xff0c;用于放置调试文件以及你未来写的代码&#xff0c;随便命名但…

<02.26>Leetcode

想想为什么要a走b的路b走a的路 因为这样到达相交点的话是同时的&#xff08;路程才是一样的&#xff09; 这样能保证第二圈就相遇了 如果各走各的路很难相遇 两个无交点的链表也有一个null交点 /*** Definition for singly-linked list.* public class ListNode {* int…