机器学习还能预测心血管疾病?没错,我用 Python 写出来了

news2024/11/28 12:30:23

全球每年约有1700万人死于心血管疾病,当中主要表现为心肌梗死和心力衰竭。当心脏不能泵出足够的血液来满足人体的需要时,就会发生心力衰竭,通常由糖尿病、高血压或其他心脏疾病引起。

在检测心血管疾病的早期症状时,机器学习就能派上用场了。通过患者的电子病历,可以记录患者的症状、身体特征、临床实验室测试值,从而进行生物统计分析,这能够发现那些医生无法检测到的模式和相关性。

尤其通过机器学习,根据数据就能预测患者的存活率,今天我们就教大家如何用Python写一个心血管疾病的预测模型。

文章目录

    • 技术提升
    • 研究背景和数据来源
    • 01 数据理解
    • 02 数据读入和初步处理
    • 03 探索性分析
    • 特征筛选

技术提升

本文由技术群粉丝分享,项目源码、数据、技术交流提升,均可加交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友

方式①、添加微信号:dkl88191,备注:来自CSDN
方式②、微信搜索公众号:Python学习与数据挖掘,后台回复:加群

研究背景和数据来源

我们用到的数据集来自Davide Chicco和Giuseppe Jurman发表的论文:《机器学习可以仅通过血肌酐和射血分数来预测心力衰竭患者的生存率》

他们收集整理了299名心力衰竭患者的医疗记录,这些患者数据来自2015年4月至12月间巴基斯坦费萨拉巴德心脏病研究所和费萨拉巴德联合医院。这些患者由105名女性和194名男性组成,年龄在40至95岁之间。所有299例患者均患有左心室收缩功能不全,并曾出现过心力衰竭。

Davide和Giuseppe应用了多个机器学习分类器来预测患者的生存率,并根据最重要的危险因素对特征进行排序。同时还利用传统的生物统计学测试进行了另一种特征排序分析,并将这些结果与机器学习算法提供的结果进行比较。

他们分析对比了心力衰竭患者的一系列数据,最终发现根据血肌酐和射血分数这两项数据能够很好的预测心力衰竭患者的存活率。

今天我们就教教大家,如果根据这共13个字段的299 条病人诊断记录,用Python写出预测心力衰竭患者存活率的预测模型。

下面是具体的步骤和关键代码。

01 数据理解

数据取自于kaggle平台分享的心血管疾病数据集,共有13个字段299 条病人诊断记录。具体的字段概要如下:

02 数据读入和初步处理

首先导入所需包。

# 数据整理  
import numpy as np   
import pandas as pd   
  
# 可视化  
import matplotlib.pyplot as plt  
import seaborn as sns  
import plotly as py   
import plotly.graph_objs as go  
import plotly.express as px  
import plotly.figure_factory as ff  
  
# 模型建立  
from sklearn.linear_model import LogisticRegression  
from sklearn.tree import DecisionTreeClassifier  
from sklearn.ensemble import GradientBoostingClassifier, RandomForestClassifier  
import lightgbm  
  
# 前处理  
from sklearn.preprocessing import StandardScaler  
  
# 模型评估  
from sklearn.model_selection import train_test_split, GridSearchCV  
from sklearn.metrics import plot_confusion_matrix, confusion_matrix, f1_score  

加载并预览数据集:

# 读入数据  
df = pd.read_csv('./data/heart_failure.csv')  
df.head() 

03 探索性分析

1. 描述性分析

df.describe().T  

从上述描述性分析结果简单总结如下:

  • 是否死亡:平均的死亡率为32%;

  • 年龄分布:平均年龄60岁,最小40岁,最大95岁

  • 是否有糖尿病:有41.8%患有糖尿病

  • 是否有高血压:有35.1%患有高血压

  • 是否抽烟:有32.1%有抽烟

2. 目标变量

# 产生数据  
death_num = df['DEATH_EVENT'].value_counts()   
death_num = death_num.reset_index()  
  
# 饼图  
fig = px.pie(death_num, names='index', values='DEATH_EVENT')  
fig.update_layout(title_text='目标变量DEATH_EVENT的分布')    
py.offline.plot(fig, filename='./html/目标变量DEATH_EVENT的分布.html')  

总共有299人,其中随访期未存活人数96人,占总人数的32.1%

3. 贫血

从图中可以看出,有贫血症状的患者死亡概率较高,为35.66%。

bar1 = draw_categorical_graph(df['anaemia'], df['DEATH_EVENT'], title='红细胞、血红蛋白减少和是否存活')  
bar1.render('./html/红细胞血红蛋白减少和是否存活.html')  

4. 年龄

从直方图可以看出,在患心血管疾病的病人中年龄分布差异较大,表现趋势为年龄越大,生存比例越低、死亡的比例越高。

# 产生数据  
surv = df[df['DEATH_EVENT'] == 0]['age']  
not_surv = df[df['DEATH_EVENT'] == 1]['age']  
  
hist_data = [surv, not_surv]  
group_labels = ['Survived', 'Not Survived']  
  
# 直方图  
fig = ff.create_distplot(hist_data, group_labels, bin_size=0.5)   
fig.update_layout(title_text='年龄和生存状态关系')   
py.offline.plot(fig, filename='./html/年龄和生存状态关系.html')  

5. 年龄/性别

从分组统计和图形可以看出,不同性别之间生存状态没有显著性差异。在死亡的病例中,男性的平均年龄相对较高。

6. 年龄/抽烟

数据显示,整体来看,是否抽烟与生存与否没有显著相关性。但是当我们关注抽烟的人群中,年龄在50岁以下生存概率较高。

7. 磷酸肌酸激酶(CPK)

从直方图可以看出,血液中CPK酶的水平较高的人群死亡的概率较高。

8. 射血分数

射血分数代表了心脏的泵血功能,过高和过低水平下,生存的概率较低。

9. 血小板

血液中血小板(100~300)×10^9个/L,较高或较低的水平则代表不正常,存活的概率较低。

10. 血肌酐水平

血肌酐是检测肾功能的最常用指标,较高的指数代表肾功能不全、肾衰竭,有较高的概率死亡。

11. 血清钠水平

图形显示,血清钠较高或较低往往伴随着风险。

12. 相关性分析

从数值型属性的相关性图可以看出,变量之间没有显著的共线性关系。

num_df = df[['age', 'creatinine_phosphokinase', 'ejection_fraction', 'platelets',  
                  'serum_creatinine', 'serum_sodium']]  
  
plt.figure(figsize=(12, 12))  
sns.heatmap(num_df.corr(), vmin=-1, cmap='coolwarm', linewidths=0.1, annot=True)  
plt.title('Pearson correlation coefficient between numeric variables', fontdict={'fontsize': 15})  
plt.show() 

特征筛选

我们使用统计方法进行特征筛选,目标变量DEATH_EVENT是分类变量时,当自变量是分类变量,使用卡方鉴定,自变量是数值型变量,使用方差分析。

# 划分X和y  
X = df.drop('DEATH_EVENT', axis=1)  
y = df['DEATH_EVENT'] 
from feature_selection import Feature_select  
  
fs = Feature_select(num_method='anova', cate_method='kf')   
X_selected = fs.fit_transform(X, y)   
X_selected.head() 
2020 17:19:49 INFO attr select success!  
After select attr: ['serum_creatinine', 'serum_sodium', 'ejection_fraction', 'age', 'time']  

05 数据建模

首先划分训练集和测试集。

# 划分训练集和测试集  
Features = X_selected.columns  
X = df[Features]   
y = df["DEATH_EVENT"]   
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y,   
                                                    random_state=2020)  
# 标准化  
scaler = StandardScaler()  
scaler_Xtrain = scaler.fit_transform(X_train)   
scaler_Xtest = scaler.fit_transform(X_test)   
  
lr = LogisticRegression()  
lr.fit(scaler_Xtrain, y_train)  
test_pred = lr.predict(scaler_Xtest)  
  
# F1-score  
print("F1_score of LogisticRegression is : ", round(f1_score(y_true=y_test, y_pred=test_pred),2)) 

我们使用决策树进行建模,设置特征选择标准为gini,树的深度为5。输出混淆矩阵图:在这个案例中,1类是我们关注的对象。

# DecisionTreeClassifier  
clf = DecisionTreeClassifier(criterion='gini', max_depth=5, random_state=1)  
clf.fit(X_train, y_train)  
test_pred = clf.predict(X_test)    
  
# F1-score  
print("F1_score of DecisionTreeClassifier is : ", round(f1_score(y_true=y_test, y_pred=test_pred),2))   
  
# 绘图  
plt.figure(figsize=(10, 7))  
plot_confusion_matrix(clf, X_test, y_test, cmap='Blues')   
plt.title("DecisionTreeClassifier - Confusion Matrix", fontsize=15)  
plt.xticks(range(2), ["Heart Not Failed","Heart Fail"], fontsize=12)  
plt.yticks(range(2), ["Heart Not Failed","Heart Fail"], fontsize=12)  
plt.show()  
F1_score of DecisionTreeClassifier is :  0.61  
<Figure size 720x504 with 0 Axes>  

使用网格搜索进行参数调优,优化标准为f1。

parameters = {'splitter':('best','random'),  
              'criterion':("gini","entropy"),  
              "max_depth":[*range(1, 20)],  
             }  
  
clf = DecisionTreeClassifier(random_state=1)   
GS = GridSearchCV(clf, param_grid=parameters, cv=10, scoring='f1', n_jobs=-1)   
GS.fit(X_train, y_train)  
  
print(GS.best_params_)   
print(GS.best_score_) 
{'criterion': 'entropy', 'max_depth': 3, 'splitter': 'best'}  
0.7638956305132776  

使用最优的模型重新评估测试集效果:

test_pred = GS.best_estimator_.predict(X_test)  
  
# F1-score  
print("F1_score of DecisionTreeClassifier is : ", round(f1_score(y_true=y_test, y_pred=test_pred),2))   
  
# 绘图  
plt.figure(figsize=(10, 7))  
plot_confusion_matrix(GS, X_test, y_test, cmap='Blues')   
plt.title("DecisionTreeClassifier - Confusion Matrix", fontsize=15)  
plt.xticks(range(2), ["Heart Not Failed","Heart Fail"], fontsize=12)  
plt.yticks(range(2), ["Heart Not Failed","Heart Fail"], fontsize=12)  
plt.show() 

使用随机森林

# RandomForestClassifier  
rfc = RandomForestClassifier(n_estimators=1000, random_state=1)  
  
parameters = {'max_depth': np.arange(2, 20, 1) }  
GS = GridSearchCV(rfc, param_grid=parameters, cv=10, scoring='f1', n_jobs=-1)    
GS.fit(X_train, y_train)    
  
print(GS.best_params_)   
print(GS.best_score_)   
  
test_pred = GS.best_estimator_.predict(X_test)  
  
# F1-score  
print("F1_score of RandomForestClassifier is : ", round(f1_score(y_true=y_test, y_pred=test_pred),2)) 
{'max_depth': 3}  
0.791157747481277  
F1_score of RandomForestClassifier is :  0.53  

使用Boosting

gbl = GradientBoostingClassifier(n_estimators=1000, random_state=1)  
  
parameters = {'max_depth': np.arange(2, 20, 1) }  
GS = GridSearchCV(gbl, param_grid=parameters, cv=10, scoring='f1', n_jobs=-1)    
GS.fit(X_train, y_train)    
  
print(GS.best_params_)   
print(GS.best_score_)   
  
# 测试集  
test_pred = GS.best_estimator_.predict(X_test)  
  
# F1-score  
print("F1_score of GradientBoostingClassifier is : ", round(f1_score(y_true=y_test, y_pred=test_pred),2))  
{'max_depth': 3}  
0.7288420428900305  
F1_score of GradientBoostingClassifier is :  0.65  

使用LGBMClassifier

lgb_clf = lightgbm.LGBMClassifier(boosting_type='gbdt', random_state=1)  
  
parameters = {'max_depth': np.arange(2, 20, 1) }  
GS = GridSearchCV(lgb_clf, param_grid=parameters, cv=10, scoring='f1', n_jobs=-1)    
GS.fit(X_train, y_train)    
  
print(GS.best_params_)   
print(GS.best_score_)   
  
# 测试集  
test_pred = GS.best_estimator_.predict(X_test)  
  
# F1-score  
print("F1_score of LGBMClassifier is : ", round(f1_score(y_true=y_test, y_pred=test_pred),2)) 
{'max_depth': 2}  
0.780378102289867  
F1_score of LGBMClassifier is :  0.74  

以下为各模型在测试集上的表现效果对比:

LogisticRegression:0.63

DecisionTree Classifier:0.73

Random Forest Classifier: 0.53

GradientBoosting Classifier: 0.65

LGBM Classifier: 0.74

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

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

相关文章

nodejs+vue企业固定资产管理系统-vscode

目 录 摘 要 I 目 录 III 第一章 概述 1.1研究背景 1.2 开发意义 1.3 研究现状 1.4 研究内容 1.5 论文结构 第二章 开发技术介绍 2.5 B/S架构 3.1 可行性分析 3.1.1技术可行性 3.1.2操作可行性 3.1.3 经济可行性 3.1.4 运行可行性 3.2性能需求分析 3.4功能分析 第四章 系统设计…

轻量级的架构决策记录机制

作者&#xff1a;倪新明 ADR是一种性价比非常高的架构决策文档化实践&#xff0c;团队引入和实践成本很低&#xff0c;却能为团队带来极大收益&#xff01; 1 团队研发面临的问题 不论是在传统的IT行业&#xff0c;还是互联网行业&#xff0c;研发团队在架构决策层面或多或少…

在Arduino IDE上开发ESP32(离线安装SDK)

用过Arduino的朋友都知道&#xff0c;Arduino的整个生态强大得让你不能不服。大家所贡献出来的各种库让基于Arduino的开发虽然还没有变得无所不能&#xff0c;但也算是相当得心应手了。你所能想到的功能大体都能在网上找到对应的库和文章。可能是因为这个原因吧&#xff0c;所以…

Redis整理-未完成

目录 1. Redis安装 1.1 单机 1.2 主从 1.3 哨兵 1.4 集群 1.4.1 方式一 redis-cli --cluster命令 1.4.2 方式二 cluster meet/addslots/replicate 2. Redis配置 2.1 基本参数配置 2.2 持久化配置 2.3 内存策略设置 2.4 主从配置 2.5 哨兵配置 2.6 集群配置 2.6.…

吃透这份 “ 自动化测试 ” 核心技术栈,月薪30K还不是随便叫

为了帮助大家快速回顾学习自动化测试中的知识点&#xff0c;分享一下这些年来&#xff0c;我对于技术一些归纳和总结&#xff0c;和自己对作为一名 高级测试工程师需要掌握那些技能的笔记分享&#xff0c;希望能帮助到有心在技术这条道路上一路走到黑的朋友&#xff01; 一、L…

[附源码]Python计算机毕业设计SSM基于JAVA快递配送平台(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

语音怎么转换成文字?这几个实用方法分享给你

当我们在听一些流行的英文歌曲时&#xff0c;发现它没有附带翻译的时候&#xff0c;是不是常常听不懂歌曲的意思内容呢&#xff1f;面对这种情况应该怎么办呢&#xff1f;其实也不难&#xff0c;我们只需要利用软件来将歌曲转换成文字的格式就可以了&#xff0c;那你们知道如何…

分布式系统(交互、协作)

文章目录进程组织进程交互传染病协议反熵&#xff08;Anti-Entropy&#xff09;闲聊&#xff08;Gossiping&#xff09;P2P 路由Circular routingPastry应用层多播ESMScribe中间件通信协议RPCMOM进程协作有序组播基本组播FIFO 组播全排序组播定序者分布式协商因果序组播分布式互…

基于SSM框架的酒店管理系统

基于SSM框架的酒店管理系统开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 看每个等级模块&#xff1a;客白模块&#xff0c;屋工模垫&#xff0c;反怠管理员模垫 客户可…

如何实现采购管理流程的优化?

采购管理流程优化指的是一种整体方法&#xff0c;而不是个人主义的方法。它指的是利用人员、流程和技术来实现最佳价值创造的过程。采购优化的方法可以是&#xff1a;最初的范围界定&#xff0c;数据收集和分析&#xff0c;改进和实施以及跟进和监控。 理解采购管理流程优化 …

oracle学习篇(二)

oracle学习篇(二) 1添加约束 1.1 添加主键约束 1.1.1 语法 alter table 表名 add constraint 约束名 约束关键字 key(添加约束的字段);1.1.2 示例代码 alter table infos add constraint pk_stuid primary key(stuid);1.2 添加检查约束 1.2.1 语法 alter table 表名 ad…

[附源码]Node.js计算机毕业设计高校学生心理健康信息咨询系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

numpy.pad()函数详解

目录 函数定义&#xff1a; 示例讲解&#xff1a; 示例1.1 constant&#xff1a; 示例1.2 maximum 示例1.3 constant: 示例2.1 constant&#xff1a; 示例2.2 constant&#xff1a; 函数定义&#xff1a; numpy.pad()函数用于对Numpy数组进行填充。有时需要对Numpy数组进…

Docker 项目快速部署Flask项目

前言 打造 flask gunicron nginx Mysql 环境 nginx Mysql 使用docker 快速部署 使用 supervisor 对 gunicron 做监控 环境&#xff1a;centos7 &#xff0c;python3.7 flask 篇 flask 项目就不多赘述了。这里贴一下项目的目录&#xff0c;便于解释下面的命令参数。 运行…

​Word怎么转换成PDF格式?这三种方法教你如何转换

怎么把Word文档转换成PDF文件格式呢&#xff1f;相信小伙伴们在办公过程中会习惯使用Word文档来编辑文件&#xff0c;编辑好后如果需要发送文件的话会将文档转换成PDF格式来发送&#xff0c;原因就是PDF格式独有的兼容性和稳定性能够让我们的文件格式不会错乱&#xff0c;这也是…

深入理解Maven的全部配置

深入理解Maven的全部配置1. Introduction1.1 Big Data -- Postgres2. Install2.1 Maven Install2.2 Config Setting.xml2.3 Local Package Install Maven3. Project4.AwakeningMaven Document: https://maven.apache.org/. Maven Download: https://maven.apache.org/download.…

前端富文本设置的表格样式无法展示解决方案

当我们在富文本编辑器里编辑好文本后&#xff0c;发布一看&#xff0c;为什么编辑器预览的内容和实际保存后展示的内容不一致呢。这是因为&#xff0c;大部分编辑器本身会自带一些样式属性&#xff0c;而当获取富文本内容的时候往往是不带这些样式属性的&#xff0c;所以才导致…

【Java_GUI编程】--基本操作你要知道

文章目录一、组件和容器1、JFrame2、面板JPanel3、布局管理器流式布局&#xff08;从左到右&#xff09;东南西北中网格布局4、事件监听输入框事件监听键盘监听5、JDialog弹窗6、Icon、ImageIcon标签IconImageIcon7、按钮单选按钮复选按钮8、列表下拉框列表框9、文本框密码框文…

醉三皇酒特别的爱:孙子15年买酒送爷爷,爷爷90箱好酒赠重孙

小强没有万万没有想到&#xff0c;自己不仅会被裁员&#xff0c;而且还妻离子散&#xff0c;最敬爱的爷爷又意外去世。 一、惨遭裁员&#xff0c;一蹶不振 都说程序员是吃年轻饭的&#xff0c;以前不以为然&#xff0c;现在看着手里的裁员告知单&#xff0c;小强也不得不信了。…

Mybatis源码分析(三)SqlSessionFactoryl的初始化

目录一 解析配置文件入口二 解析properties文件三 解析settings文件四 解析typeAliases文件五 解析 Plugin文件六 解析 Environments 文件七 解析Mapper 文件官网&#xff1a; mybatis – MyBatis 3 | 简介参考书籍&#xff1a;《通用源码阅读指导书&#xff1a;MyBatis源码详解…