数据分析实战:利用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列其实有非常多的组合方式去分析。此外本文没有用到模型,只是数据可视化的方式进行简要分析。

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

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

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

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

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

已标记关键词 清除标记
本套课程系大喵在**2020年****录制课程,大喵将带着大家使用vscode这款轻量级编辑器神器,快速上手Python高效开发、调试及单元测试的插件扩展和 VSCode IDE环境配置; 什么是 vscode 编辑器? Visual Studio Code(以下简称vscode)是一个轻量且强大的跨平台开源代码编辑器(IDE),支持Windows,Mac OS X和Linux。内置JavaScript、TypeScript和Node.js支持,而且拥有丰富的插件生态系统,可通过插件面板来方便快捷的安装插件来支持javascript、C++、C#、Python、PHP等其他语言。 什么是 python ? Python,它是一门编程语言,截止到目前python已经广泛应用在:无人驾驶、个人助理、金融、电商、医疗、教育等各大领域。尤其是在 Web开发、自动化运维与测试、游戏服务器开发方面有着先天的优势。目前许多大型网站就是用Python开发的,例如YouTube、Instagram,还有国内的豆瓣。很多大公司,包括Google、Yahoo等,甚至NASA(美国航空航天局)都大量地使用Python。 VSCode + Python VSCode毫无疑问是一款非常优秀的IDE,而Python则无疑是一门使用领域相当广泛,非常强大的高级语言;那我们如何把这两者结合起来,用**美的IDE编写最棒的语言,优雅与**,强强结合,气冲入虹,势不可挡。 课程内容主要包括: 01. 课程内容介绍 02. VSCode IDE 介绍 03. 为什么推荐使用 VSCode IDE  04. Python 语言基础介绍  05. 为什么选择 Python 语言 06. VSCode和Python 强强联手 07. 课程插件扩展介绍 08. Python扩展安装及介绍 09. Python扩展代码测试 10. AREPL安装和介绍 11. AREPL for Python 特点介绍 12. AREPL 代码功能测试 13. autoDocstring 安装和介绍 14. autoDocstring 代码测试使用 15. python test explorer 安装和介绍 16. Python pytest 测试和使用
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页