第R2周:医疗成本预测
- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
- 编译器:jupyterlab
一、前期准备
1. 数据导入
2. 探索热力图
numeric_cols=df.select_dtypes(include=['int64','float64'])plt.figure(figsize=(12,8))sns.heatmap(numeric_cols.corr(),cmap='coolwarm',annot=True)plt.title("Correlation Heatmap")plt.show()Correlation Heatmap(相关性热图):
不同数值变量之间 Pearson 相关系数(correlation coefficient)的大小。
其中,insurance_coverage_pct vs annual_medical_cost 的 r=-0.86,说明二者存在较强烈的线性关系,即可能意味着特征冗余。此时纳入机器学习,会导致回归参数不稳定、标准误增加。
3. 探索分类特征与回归数值的关系
3.1 箱线图
importmatplotlib.pyplotaspltimportseabornassnsfrommatplotlib.font_managerimportFontProperties#中文字体路径font=FontProperties(fname="/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc")# Seaborn风格设置sns.set_style("darkgrid")sns.set(font_scale=0.8)# 创建matplotlib的fig对象和子图对象axfig,ax=plt.subplots(1,3,figsize=(12,4))# 多个数值变量的箱线图sns.boxplot(data=df.loc[:,['annual_medical_cost']],ax=ax[0],whis=3)ax[0].set_title('多个数值变量',fontproperties=font)# 一个数值变量多个分组的箱线图sns.boxplot(x=df["hospital_admissions"],y=df["annual_medical_cost"],ax=ax[1],whis=3)ax[1].set_title('一个数值变量多个分组',fontproperties=font)# 一个数值变量多个分组子分组的箱线图sns.boxplot(x="hospital_admissions",y="annual_medical_cost",hue="smoker",data=df,palette="Set1",width=0.5,ax=ax[2],whis=3)ax[2].set_title('一个数值变量多个分组/子分组',fontproperties=font)plt.tight_layout()plt.show()在这里插入图片描述
由于字体无法显示原因,修改了代码
3.2 小提琴图
# Seaborn风格设置sns.set(font_scale=0.8,style="darkgrid")# 创建fig和子图fig,ax=plt.subplots(1,3,figsize=(12,4))# 多个数值变量的小提琴图sns.violinplot(data=df.loc[:,['annual_medical_cost']],ax=ax[0])ax[0].set_title('多个数值变量',fontproperties=font)# 一个数值变量多个分组sns.violinplot(x=df["heart_disease"],y=df["annual_medical_cost"],ax=ax[1])ax[1].set_title('一个数值变量多个分组',fontproperties=font)# 一个数值变量多个分组/子分组sns.violinplot(x="heart_disease",y="annual_medical_cost",hue="smoker",data=df,palette="Set1",width=0.5,ax=ax[2])ax[2].set_title('一个数值变量多个分组/子分组',fontproperties=font)plt.tight_layout()plt.show()3.3 条形统计图和散点图(探索)
sns.set_style("darkgrid")plt.figure(figsize=(6,4))sns.barplot(x="heart_disease",y="annual_medical_cost",data=df,errorbar="ci")plt.title("不同心脏病状态的平均医疗费用",fontproperties=font)plt.xlabel("Heart Disease")plt.ylabel("Annual Medical Cost")plt.show()plt.figure(figsize=(7,4))sns.stripplot(x="heart_disease",y="annual_medical_cost",data=df,jitter=True)plt.title("不同心脏病状态下医疗费用分布",fontproperties=font)plt.show()4. 探索数值特征与回归特征的关系
4.1 气泡图
4.2散点图+回归线![]()
二、数据预处理
1. 处理缺失值
2. 编码object对象
即代表1、3、8、15、17列为类别变量
oe = OrdinalEncoder() 创建编码器,自动分配数字,具有大小关系
3. 划分训练集与测试集
4. 探索字段重要性排行
5. 标准化
6. 创建dataloader
fromtorch.utils.dataimportDataLoader batch_size=32# 封装数据train_dataset=data.TensorDataset(X_train,y_train)test_dataset=data.TensorDataset(X_test,y_test)# 加载数据train_dataloader=DataLoader(train_dataset,batch_size=batch_size,shuffle=True)#test_dataloader=DataLoader(test_dataset,batch_size=batch_size)#, shuffle=True三、构建模型
1. 设置模型参数
device=torch.device("cuda"iftorch.cuda.is_available()else"cpu")device>>>device(type='cuda')2. 定义模型
classmodel_lstm(nn.Module):def__init__(self):super(model_lstm,self).__init__()self.lstm0=nn.LSTM(input_size=19,hidden_size=200,num_layers=1,batch_first=True)#LSTM内部隐藏状态维度 200维,1层self.fc0=nn.Linear(200,1)defforward(self,x):out,_=self.lstm0(x)out=self.fc0(out)returnout model=model_lstm()fromtorchinfoimportsummary summary(model,(64,1,19))
做了两件事:
定义一个 LSTM 神经网络模型
用 torchinfo.summary() 查看模型结构和参数量
3. 编写训练函数
deftrain(dataloader,model,loss_fn,optimizer):size=len(dataloader.dataset)num_batches=len(dataloader)train_loss,train_acc=0,0pred_list=[]y_list=[]forX,yindataloader:X,y=X.to(device),y.to(device)pred=model(X)pred=pred.squeeze()y_list+=[i.detach().numpy()foriiny.cpu()]pred_list+=[i.detach().numpy()foriinpred.cpu()]#loss=loss_fn(pred,y)optimizer.zero_grad()loss.backward()optimizer.step()train_loss+=loss.item()R2=metrics.r2_score(y_list,pred_list)#第一个必须是真实值,第二个必须是预测值,否值 R2 可能会为负数train_loss/=num_batchesreturnR2,train_loss4. 编写测试函数
deftest(dataloader,model,loss_fn):size=len(dataloader.dataset)num_batches=len(dataloader)test_loss,test_acc=0,0pred_list=[]y_list=[]withtorch.no_grad():forX,yindataloader:X,y=X.to(device),y.to(device)pred=model(X)pred=pred.squeeze()y_list+=[i.detach().numpy()foriiny.cpu()]pred_list+=[i.detach().numpy()foriinpred.cpu()]loss=loss_fn(pred,y)test_loss+=loss.item()R2=metrics.r2_score(y_list,pred_list)test_loss/=num_batchesreturnR2,test_loss四、训练模型
五、Loss与R2图
今天就没有总结啦,学习内容都放在各章节里了。这一章对我们临床研究的人很友好,顺便还温故了一些统计学知识。