数据分析实战:利用python对心脏病数据集进行分析

↑ 关注 + 星标 ~ 有趣的不像个技术号

每晚九点,我们准时相约  

我们都很害怕生病,但感冒发烧这种从小到大的疾病我们已经麻木了,因为一星期他就会好,但是随着长大,各种发炎、三高、心脏病、冠心病响应而生。

心脏病作为一种发作起来让人看了就觉得恐怖的疾病,每年不知道夺走多少生命。而那些患病健在的人们也必须在自己后续的生命里割舍太多东西,以防止心脏病发作。

没有得病的时候,我们永远觉得它离自己很远。我对心脏病的认知就是这样,我不知道它患病的原因,也不知哪些原因会引起心脏病。而患病后如何保持正常生活等等,一概不知。

今天在kaggle上看到一个心脏病数据(数据集下载地址和源码见文末),那么借此深入分析一下。

数据集读取与简单描述

首先导入library和设置好超参数,方便后续分析。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

通过对数据集读取和描述可以得到这两个表格:

可以看到有303行14列数据,每列的标题是age、sex、cp、……、target。他们就像每次去医院的化验单,非专业人士很多都不认识。所以利用官方的解释翻译后含义如下:

  • age: 该朋友的年龄

  • sex: 该朋友的性别 (1 = 男性, 0 = 女性)

  • cp: 经历过的胸痛类型(值1:典型心绞痛,值2:非典型性心绞痛,值3:非心绞痛,值4:无症状)

  • trestbps: 该朋友的静息血压(入院时的毫米汞柱)

  • chol: 该朋友的胆固醇测量值,单位 :mg/dl

  • fbs: 人的空腹血糖(> 120 mg/dl,1=真;0=假)

  • restecg: 静息心电图测量(0=正常,1=患有ST-T波异常,2=根据Estes的标准显示可能或确定的左心室肥大)

  • thalach: 这朋友达到的最大心率

  • exang: 运动引起的心绞痛(1=有过;0=没有)

  • oldpeak: ST抑制,由运动引起的相对于休息引起的(“ ST”与ECG图上的位置有关。这块比较专业,可以点这个看一个解读)

  • slope: 最高运动ST段的斜率(值1:上坡,值2:平坦,值3:下坡)

  • ca: 萤光显色的主要血管数目(0-4)

  • thal: 一种称为地中海贫血的血液疾病(3=正常;6=固定缺陷;7=可逆缺陷)

  • target: 心脏病(0=否,1=是)

所以这些信息里都是患病或者健康者的一些身体指标,并没有和他是否抽烟、是否熬夜、是否遗传、是否作息规律那些东西,因此找不到指导现在我们生活的点,比如说明要戒烟戒酒那些东西。

顺手送上一篇知乎链接 此外上边只是我通过原版数据集给的解读翻译的,如有出错误,欢迎纠正

拿到一套数据首先是要看看这个数据大概面貌~

男女比例

先看看患病比率,男女比例这些常规的

countNoDisease = len(data[data.target == 0])
countHaveDisease = len(data[data.target == 1])
countfemale = len(data[data.sex == 0])
countmale = len(data[data.sex == 1])
print(f'没患病人数:{countNoDisease }',end=' ,')
print("没有得心脏病比率: {:.2f}%".format((countNoDisease / (len(data.target))*100)))
print(f'有患病人数:{countHaveDisease }',end=' ,')
print("患有心脏病比率: {:.2f}%".format((countHaveDisease / (len(data.target))*100)))
print(f'女性人数:{countfemale }',end=' ,')
print("女性比例: {:.2f}%".format((countfemale / (len(data.sex))*100)))
print(f'男性人数:{countmale }',end=' ,')
print("男性比例: {:.2f}%".format((countmale   / (len(data.sex))*100)))

上边代码得到的答案如下,乍看上去男的多于女的,但前提是这个数据只是这个300人的样本展示,不代表全人类

没患病人数:138 ,没有得心脏病比率: 45.54%
有患病人数:165 ,患有心脏病比率: 54.46%
女性人数:96 ,女性比例: 31.68%
男性人数:207 ,男性比例: 68.32%

除了用饼图看这个面貌,还可以同时看一下

fig, ax =plt.subplots(1,3)  #2个子区域
fig.set_size_inches(w=15,h=5)   # 设置画布大小
sns.countplot(x="sex", data=data,ax=ax[0])
plt.xlabel("性别 (0 = female, 1= male)")
sns.countplot(x="target", data=data,ax=ax[1])
plt.xlabel("是否患病 (0 = 未患病, 1= 患病)")
sns.swarmplot(x='sex',y='age',hue='target',data=data,ax=ax[2])
plt.xlabel("性别 (0 = female, 1= male)")
plt.show()

从这三联图可以看到男性1多余女性0,患病target1多于未患病0,在年龄分布提琴图里可以看到女性患者比例多于男性患者比例。

其中比列详细拆解一下,见下方代码和图示:

pd.crosstab(data.sex,data.target).plot(kind="bar",figsize=(15,6),color=['#30A9DE','#EFDC05' ])
plt.title('各性别下患病图示')
plt.xlabel('性别 (0 = 女性, 1 = 男性)')
plt.xticks(rotation=0)
plt.legend(["未患病", "患有心脏病"])
plt.ylabel('人数')
plt.show()

可以看到这个数据集中女性患者数是健康数的3倍多。留下一个疑问,心脏病女性更容易得嘛?百度了一下,发现这个问题提问的人不少,但没有具体很科学的回答。google也同样如此。可能要找到这个答案需要再去找一找文献,但不是本文目的,因此没有去寻找这个真实比例。

在这个数据集中,男性多于女性一倍,分别207和96人;患病患者稍微多余未患病患者,患病165,138人。因为年龄可能是连续的,因此在第三幅图做年龄、性别、患病关系图,单从颜色观察可发现在这个数据集中,女性患病率大于男性。通过第四图和统计可以计算得到,男性患病率44.9% ,女性患病率75%。

需要注意,本文得到的患病率只是这个数据集的。

年龄和患病关系

通过以下代码来看一看:随着年龄增长患病比率有没有变化

(现在写这个文章的时候我才想到,可能即使有变化也没有意义,还是样本有限,如果这个样本空间覆盖再提升1000倍才能说明一些问题吧——即年龄和患有心脏病的关系)

pd.crosstab(data.age,data.target).plot(kind="bar",figsize=(25,8))
plt.title('患病变化随年龄分布图')
plt.xlabel('岁数')
plt.ylabel('比率')
plt.savefig('heartDiseaseAndAges.png')
plt.show()

输出的图像如下:就这张图来说37-54岁患病人数多于未患病人数,年龄再继续升高后有没有这个规律了,在70+岁后患病人数又增加,这条仅能作为数据展示,不能作为结论。

数据集中还有很多维度可以组合分析,下边开始进行组合式探索分析

年龄-心率-患病三者关系

在这个数据集中,心率的词是‘thalach’,所以看年龄、心率、是否患病的关系。

# 散点图
plt.scatter(x=data.age[data.target==1], y=data.thalach[(data.target==1)], c="red")
plt.scatter(x=data.age[data.target==0], y=data.thalach[(data.target==0)], c='#41D3BD')
plt.legend(["患病", "未患病"])
plt.xlabel("年龄")
plt.ylabel("最大心率")
plt.show()
# 再画个提琴图
sns.violinplot(x=data.target,y=data.trestbps,data=data)
plt.show()

看到30岁心跳200那个点,吓我一跳,如果心脏病不是病,那200这个速度太让人膜拜了。

可以看到的是心跳速度患病的大概集中在140-200bpm之间。这个数据比未患病的人普遍高一些,从提琴图上也可以看到这个值分布比健康人高一些且更集中。

年龄和血压(trestbps)分布关系

大家都知道体检的时候血压是常规测试项目,那么我想血压和年龄有什么关系吗?有没有心脏病和年龄有关系吗?

来做个图看一下。并尝试用不同的颜色区分。

plt.scatter(x=data.age[data.target==1], y=data.trestbps[data.target==1], c="#FFA773")
plt.scatter(x=data.age[data.target==0], y=data.trestbps[data.target==0], c="#8DE0FF")
plt.legend(["患病",'未患病'])
plt.xlabel("年龄")
plt.ylabel("血压")
plt.show()

看上去随着年龄增长,血压更飘了?从这个结果可以看到的是,静息血压患病人和未患病的人在血压方面都是均匀分布的,随着年龄增长也没有明显的分层变化。所以并不能直接从静息血压很好的判断出是否患心脏病。

那么血压与其他什么有关呢?

比如心率?好,来看看。

血压(trestbps)和心率(thalach)关系

血压、心率这两个都来自于心脏的动能,相当于发动机力量和发动机转速。我猜这俩有点关系,一起看看

plt.scatter(x=data.thalach[data.target==1], y=data.trestbps[data.target==1], c="#FFA773")
plt.scatter(x=data.thalach[data.target==0], y=data.trestbps[data.target==0], c="#8DE0FF")
plt.legend(["患病",'未患病'])
plt.xlabel("心率")
plt.ylabel("血压")
plt.show()

现实情况是,这个样本集中,除了能显示出患病新率高这个已有结果外,血压和心率没有相关性。

胸痛类型和心脏病、血压三者关系

表中有个数据是胸痛类型四个,分别是0123,他们和心脏病有关系吗,作图看看。

此外这块我要说的是,我上边的翻译是1 典型、2非典型、3非心绞痛、4无症状。

但是数据集中是0123 ,我再kaggle里看了很多人的作品,没有合理解释这个的,所以这个数据我只可视化展示,不分析。

sns.swarmplot(x='target',y='trestbps',hue='cp',data=data, size=6)
plt.xlabel('是否患病')
plt.show()

fig,ax=plt.subplots(1,2,figsize=(14,5))
sns.countplot(x='cp',data=data,hue='target',palette='Set3',ax=ax[0])
ax[0].set_xlabel("胸痛类型")
data.cp.value_counts().plot.pie(ax=ax[1],autopct='%1.1f%%',explode=[0.01,0.01,0.01,0.01],shadow=True, cmap='Blues')
ax[1].set_title("胸痛类型")

结论是:从上图可以看到的是0类疼痛的人在非患病群体中占大多数,而在患病群体中,123三种胸痛的人占了大部分。

运动引起的心绞痛与患病、心率关系

承接胸痛类型,运动引起心绞痛与是否患病有没有关系呢?与心率有没有关系呢?作图看一下

PS:运动引起心绞痛(exang: 1=有过;0=没有)

sns.swarmplot(x='exang',y='thalach',hue='target',data=data, size=6)
plt.xlabel('有没有过运动引起心绞痛')
plt.ylabel('最大心率')
plt.show()

得到的这个图像很有意思!

虽然最大心率是入院时候测的,但是在没有运动引起心绞痛的人中,最大心率集中度比较高,在160-180之间,而他们都患有心脏病。

我推测是:他们有心脏病,运动就难受,所以就不运动,所以根本不会有“运动时产生胸痛”这种问题。

而在运动中产生胸痛的人中(右边为1的)他们有很多产生过胸痛,这种人心率比较高,在120-150之间集中着,而其中很多人并没有心脏病,只是心率比较高。

大血管数量(ca)和血压(trestbps)、患病关系

plt.figure(figsize=(15,5))
sns.swarmplot(y='trestbps',data=data,x='ca',hue='target',palette='RdBu_r',size=7)
plt.xlabel('大血管数量')
plt.ylabel('静息血压')
plt.show()

plt.figure(figsize=(15,5))
sns.catplot(x="ca", y="age", hue="target", kind="swarm", data=data, palette='RdBu_r')
plt.xlabel('大血管显色数量')
plt.ylabel('年龄'

这个血管数量指银光显色。具体医学含义没搜到,所以不分析。只是为0的和患病有很大的相关性

年龄(age)和胆固醇(chol)关系

在我初高中的时候,我妈妈告诉我说,每天鸡蛋黄不要超过两个,不然会引起胆固醇高,那时候身体健康,从来不信这些话。我后来上大学了连每天一个都没保证住,但我记住了这句话,所以看到胆固醇三个字会想起这个家庭教育哈哈。

胆固醇侧面反映了血脂,那么下边生成一下胆固醇、年龄、患病三者关系散点图。为了区分,这次我又换了个颜色。

plt.scatter(x=data.age[data.target==1], y=data.chol[data.target==1], c="orange")
plt.scatter(x=data.age[data.target==0], y=data.chol[data.target==0], c="green")
plt.legend(["患病",'未患病'])
plt.xlabel("年龄")
plt.ylabel("胆固醇")
plt.show()
# 箱型图
sns.boxplot(x=data.target,y=data.chol,data=data)

在这个样本集中,患病者和非患病者胆固醇含量分布没有明显的分层现象,箱型图显示结果是合理上下限是一样的,只是25%、50%、75%三条线患病的人稍微稍微低一些。

结论就是胆固醇并不能直接反映有没有心脏病这件事。

相关性分析

分析了很多,那么哪些和患病相关的,而数据间又有啥关系呢?做个图看看,颜色越绿越相关,越红越负相关

plt.figure(figsize=(15,10))
ax= sns.heatmap(data.corr(),cmap=plt.cm.RdYlBu_r , annot=True ,fmt='.2f')
a,b =ax.get_ylim()
ax.set_ylim(a+0.5,b-0.5)

图像很好看对不对,只看最后一行,是否患病和cp、thalach、slope正相关,和exang、oldpeak、ca、thal等负相关。

本篇分析了心脏病数据集中的部分内容,14列其实有非常多的组合方式去分析。此外本文没有用到模型,只是数据可视化的方式进行简要分析。

本文中由于图片过大,在手机浏览可能看不清楚,故开源了代码,欢迎大家自己动手可视化试试。

如果有什么建议意见,欢迎留言。

获取本文涉及的源码和数据集:后台回复“心脏病

后台回复关键词「进群」,即刻加入读者交流群~

在看”和“转发”是对文章最好的支持

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python毕业设计 医学大数据分析 - 心血管疾病分析

# 1 前言 🚩 基于大数据的心血管疾病分析 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:4分 选题指导,项目分享: https://gitee.com/yaa-dc/warehouse-1/blob…

Python数据分析—基于机器学习的UCI心脏病数据分析(源码+数据+分析设计)

本设计源码、数据和设计已经开源,点击链接下载,喜欢的话就点赞加收藏吧! 下载链接:https://pan.baidu.com/s/1ys2F6ZH4EgnFdVP2mkTcsA?pwdLCFZ 提取码:LCFZ 研究基础 心脏病是一类比较常见的循环系统疾病。循环系统…

【毕业设计】大数据心血管疾病数据分析(医学大数据分析)

文章目录 0 前言1 课题背景2 数据处理3 数据可视化4 最后 0 前言 🔥 Hi,大家好,这里是丹成学长的毕设系列文章! 🔥 对毕设有任何疑问都可以问学长哦! 这两年开始,各个学校对毕设的要求越来越高&#xff…

【毕业设计】医学大数据分析 - 心血管疾病分析

1 前言 🚩 基于大数据的心血管疾病分析 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:4分 🧿 选题指导, 项目分享: https://gitee.com/dancheng-senior/proje…

大厂开源之殇

‍ 本轮开源之风吹起迄今数年,最大的影响还是越来越多的商业公司开始探索开源方法能够如何改变自己的经营策略。 开源策略循序渐进分成使用、参与和发起。 在发起开源项目实践一线的,一个是打着开源旗号的创业公司,另一个就是大型企业尤其互联…

Zerobot僵尸网络出现了新的漏洞利用和功能

©网络研究院 Zerobot DDoS僵尸网络已经获得了重大更新,扩展了其针对更多互联网连接设备和扩展网络的能力。 微软威胁情报中心 (MSTIC)正在以DEV-1061的名称跟踪持续的威胁,名称为未知、新兴或发展中的活动群集。 本月早些时候,Fort…

github action 基于个人项目实践

前言: DevOps 和 Jenkins 作为一名开发,虽然也没有经常听到 Devops (研发和运维一体化)这个概念,但日常工作中已经无处不在地用着 DevOps 工具。自研也好,基于开源项目改造也好,互联网公司基本都会有自已的…

张晴晴:对话数据推动AIGC——大模型底层数据探索

“Training data is technology” . 数据即科技,OpenAI的联合创始人IlyaSutskever在与知名科技媒体The Verge访谈中提到。ChatGPT自发布以来热度席卷全球,一周前惊艳亮相的GPT-4更是让人感叹我们迎来了AI发展的历史性时刻。 然而我们也困惑,O…

通过CSIG—走进合合信息探讨生成式AI及文档图像处理的前景和价值

一、前言 最近有幸参加了由中国图象图形学学会(CSIG)主办,合合信息、CSIG文档图像分析与识别专业委员会联合承办的“CSIG企业行——走进合合信息”的分享会,这次活动以“图文智能处理与多场景应用技术展望”为主题,聚…

期权专题2:备兑期权

组合期权在四种基本期权的基础上,进行组合,构建出对应的策略。我们先回顾一下基本期权的定价代码。 def option_price(type, dir, S, K None, cost None):获取期权的价值,权利金默认为50Parameters----------type:期权类型,put表示看跌,call表示看涨,…

期权 证券 股票(沪深300ETF)等数据获取

Python 使用tushare模块,这些需要积分,临时使用推荐在闲鱼上买一个月/半年的账号(期权需要5000积分,普通的股票只需要2000积分),不要选择淘宝的单次代下载(又贵又不方便)&#xff0c…

[QMT]05-获取基础行情信息

函数:获取合约基础信息 get_instrument_detail(stock_code) 1 释义 获取合约基础信息 参数 stock_code - string 合约代码 返回 dict 数据字典,{ field1 : value1, field2 : value2, ... },找不到指定合约时返回None ExchangeID - string 合约…

50ETF期权历史数据获取

文章目录 前言一、期权历史数据二、步骤1.安装Choice终端1.1 注册用户 2.导出数据3.表格检索 EOF 前言 在量化交易时需要50ETF(510050)期权历史数据进行回测支持,正常情况下,到期的期权日线数据已经被关闭无法获取。 本文主要讲解如何使用choice数据终端…

技术流薅支付宝羊毛,日入上万不是梦!

阅读文本大概需要 6.66 分钟。 这篇文章发出去不久,就有读者用文章所说的方法赚了 5473 元,还特意给我发了一大红包。 只有当你懂得感恩时,你才能走的更远。 在之前的文章里说过薅羊毛是有分等级,初级的玩法就是在微信群&#xff…

【项目】关于汇付宝支付对接

文章目录 前言引入maven项目结构常量类requestreponseutils签约效果官网文档问题 前言 本文是结合第三方demo提供,然后整理的代码,主要涉及的接口有,签约,支付,流程是,用户输入身份证、银行卡等信息&#…

网赚渠道,付费项目和免费项目,你会选择哪种网赚方式

大家好,我是蝶衣王的小编 在我的理解里呢,网赚分为付费和免费两种。那我也就这两种跟各位分享一下吧。 免费项目 时间财富网 国内的一个任务网站的代表之一,门槛比较低。只要有一技之长,就可以在上面找到让你赚钱的一个任务&am…

免费使用的支付宝,到底是怎么一年赚1206亿的?

全世界只有3.14 % 的人关注了 爆炸吧知识 眨眼间,马云居然退休已经一年了,真可谓白驹过隙,恍惚而逝啊! 不过,你以为马云退休了,就清风明月,万事不管了。 太年轻! 其实马云依旧掌控者…

支付宝赚赏金的四种玩法(引流+变现日入200+)

各大网赚公众号,都推了支付包赏金的玩法,我也来跟跟热度。 以下是收集到的目前市面上常见的玩法。 一:群发好友或者朋友圈。 群发好友或者朋友圈的目的,都是为了让别人来扫描我们的赏金二维码,直接得到赏金。 而好…

在团购网上空手赚钱项目,你敢做就敢赚!

【项目介绍】: 利用团购网销售一款网络热销的静脉曲张袜。 【市场前景】: 团购网站2011年开始火爆起来,到现在团购也都一直还行,毕竟属于概念性行业,只是对于商家来说有时候并不是好事,我对待团购的看法是…