今天要跟大家说到的一个数据集分析,是关于心脏病的。心脏病作为全球第一大杀手,是我们不得不提前防御的疾病。今天我们利用Python从一份心脏病数据集中找出一些规律,看下哪些特征对于确诊心脏病影响比较大,从而提醒我们注意平时的生活规律。
数据集介绍
数据分析之前,先得有数据集,首先先来介绍一下这份kaggle上下载的数据集。
对其中的字段进行分析:
- age:年龄。
- sex:性别(1:男,0:女)
- cp:疼痛类型(1:典型心绞痛,2:非典型心绞痛,3:非心绞痛,4:没有症状(不痛))
- trestbps:静息血压。
- chol:胆固醇。
- fbs:血糖(>120mg/dl为1,否则为0)
- restecg:心电图(0:正常,1:异常,2:严重)
- thalach:达到的最高心率。
- exang:运动诱发心绞痛(1:是的,0:不是)
- oldpeak:运动相对于休息引起的ST期抑郁
- slope:运动高峰的心电图(1:上坡,2:平和,3:下坡)
- ca:主要血管数目(0-3)
- thal:地中海贫血(3:普通。6:固定的缺陷,7:可逆的缺陷)。
- target:心脏疾病诊断(0:没有心脏病,1:有心脏病)
这份数据集,记录的都是生理的特征,但是我们可以根据这些特征,来反向关注生活习惯。比如胆固醇,蛋黄、猪肝都是引起胆固醇过高的食物,如果我们后面分析后,发现胆固醇过高会引起心脏病,那么平时就要注意少吃这些食物了。
数据分析-性别特征
接下来对这个数据集进行一波分析了,我们尽可能多的分析某些特征对于心脏病的影响。需要说一下,这里我们用到的依然是pandas+seaborn的技术栈(需要完整代码私信“心脏病”即可获取)。先来看下性别比例吧:
# 性别因素
gender_dist = df['sex'].value_counts()
plt.pie(gender_dist.values,labels=['男','女'],autopct="%.2f%%")
print(gender_dist)
>> 1 207
>> 0 96

其中男性207,女性96,男性的占到了接近70%了。但这个并不是有70%的男性得了心脏病,而是这份数据集的男女比例。那接下来再来看下,不同的性别患心脏病的分布情况。代码如下:
fig,axes = plt.subplots(1,3,figsize=(15,4))
g_target_dist = df.groupby(['sex','target']).count()['age'].unstack()
# 患病柱状图
ax1 = sns.countplot(x="sex",hue='target',data=df,ax=axes[0])
ax1.set_xlabel("性别")
ax1.set_xticklabels(['女','男'])
# 女性患病比例饼状图
ax2 = axes[1]
ax2.pie(g_target_dist.loc[0],labels=['正常','患病'],autopct="%.2f%%")
ax2.set_title("女性患病比例")
# 男性患病比例饼状图
ax3 = axes[2]
ax3.pie(g_target_dist.loc[1],labels=['正常','患病'],autopct="%.2f%%")
ax3.set_title("男性患病比例")

第一个图可以看出,女性的患病比例明显高于男性。然后具体性别来看,女性患病比例达到75%,男性患病比例只有45%。通过数据集分析发现,女性患病的概率高于男性,所以女性朋友们注意啦,要好好保护自己哦~
数据分析-年龄特征
在分析之前,按照我的常识来说,年龄对于患心脏病的概率影响是比较大的,一般年纪比较大的患心脏病的概率比较高。那事实是不是这样的呢?我们用数据说话!原来的数据集中年龄是具体的数字,为了更加方便的分析,我们将年龄分成“儿童(0-18)”、“青年(18-40)”、“中年(40-66)”、“老年(66-200)”,而经过分割后,发现属于儿童阶段的数据没有,因此我们就只取后面三个进行分析。分析的代码如下:
fig,axes = plt.subplots(2,2,figsize=(8,8))
age_dist = df[['age','target']]
age_dist['age_range'] = pd.cut(age_dist['age'],bins=[0,18,40,66,200],include_lowest=True,right=False,labels=['儿童','青年','中年','老年'])
sns.countplot(x="age_range",hue="target",data=age_dist,ax=axes[0,0])
axes[0,0].set_xlabel("年龄段")
youth = age_dist[age_dist['age_range']=='青年']['target'].value_counts()
_ = axes[0,1].pie(youth,labels=['正常','患病'],autopct="%.2f%%")
axes[0,1].set_title("青年人患病比例")
middle = age_dist[age_dist['age_range']=='中年']['target'].value_counts()
_ = axes[1,0].pie(middle,labels=['正常','患病'],autopct="%.2f%%")
axes[1,0].set_title("中年人患病比例")
old = age_dist[age_dist['age_range']=='老年']['target'].value_counts()
_ = axes[1,1].pie(old,labels=['正常','患病'],autopct="%.2f%%")
axes[1,1].set_title("老年人患病比例")
plt.tight_layout()
最终的效果图如下:
从上图中可以看出,这份数据集中年人是占了大多数。其次可以看出青年人出现心脏病的概率只有25%,而中年人和老年人的患病概率都达到了45%以上,一个46.6%,一个48.48%,所以患心脏病的风险在中年就开始变大了,随着年龄的增加还在增长。也印证了我们开头说的那句,年龄越大,患心脏病的概率确实也是越大。
数据分析-心率特征
心率是影响是否患心脏病的一个直接的因素,我们来看下心率跟心脏病之间的关系是怎样的。这里用条形图,饼图都不好展示关系,唯独用小提琴图才能最好的反应心率与是否患病的关系。代码如下:
# 心率与患病的关系
ax = sns.swarmplot(x="target",y="thalach",data=df)
ax.set_xlabel("是否患病")
ax.set_ylabel("最大心率")

可以看到,患心脏病的人的心率普遍比普通人高,所以心率比较高的,可要注意了哦!
心率高低可能是是否患病的一个直接因素,并且在之前的分析中我们知道年纪越大患心脏病的概率越大,那是不是年纪越大,他的心率也会越大呢?我们也可以通过小提琴图来进行分析。代码如下:
# 年龄与心率
df['age_range'] = pd.cut(age_dist['age'],bins=[0,18,40,66,200],include_lowest=True,right=False,labels=['儿童','青年','中年','老年'])
ax = sns.swarmplot(x="age_range",y="thalach",data=df,hue="target")
ax.set_xlabel("年龄段")

从图中我们发现,青年人的心率>中年人>老年人,所以心率是随着年龄增长而不断降低的。但是,我们还可以发现,在同年龄段中,患病的都是心率高的(看那些黄色的点),青年患者心率都在160以上,中年患者心率都在140以上,老年患者心率都在100以上。所以有另外一个结论,超过同龄人的心率,除非是身体特别好,否则建议去医院检查一下!
数据分析-血压、胆固醇特征
血压和胆固醇,是否会是引起心脏病患者的另外的因素呢?这里我们分别用小提琴图和箱线图来进行分析。先来看下血压吧。
# 心脏病与血压
ax = sns.swarmplot(x="target",y="trestbps",data=df)
ax.set_xlabel("是否患病")
ax.set_ylabel("血压")

可以看到是否患病在血压这个特征上并无明显区别,从本数据集中来看,暂时找不到血压与是否患心脏病是否存在直接影响。
我们再来看下胆固醇,胆固醇用箱线图来看下。
# 心率与患病的关系
ax = sns.boxenplot(x="target",y="chol",data=df)
ax.set_xlabel("是否患病")
ax.set_ylabel("最大心率")

患心脏病的人的胆固醇总体来说比没有患病的人低一些,但是差异并不明显,在数据不是很充足的情况下,没法下结论,因此关于胆固醇是否会影响患心脏病,并不能给出直接答案。
数据分析-年龄与血糖、胆固醇
这里我们再加一个和是否患心脏病没有关系的分析,也是我们比较关心的,就是年龄与血压、血糖、胆固醇之间的关系。先来看下血糖。
# 血糖与年龄
ax = sns.countplot(hue="fbs",x="age_range",data=df)
ax.set_xlabel("年龄段")
ax.set_ylabel("数量")
labels = ['<120mg/dl','>120mg/dl']
legend = ax.legend()
for t,label in zip(legend.texts,labels):
t.set_text(label)

可以发现,血糖随着年龄的增加,还是有一部分人会显著提高的,也就是年纪越大,患糖尿病的风险会增加。
再来看下年龄与胆固醇的关系。
# 血糖与年龄
ax = sns.swarmplot(y="chol",x="age_range",data=df)

可以发现年龄和胆固醇之间并没有明显的规律。因此他们之间没有必然的联系。
以上就是我根据一份心脏病数据集做的一些分析,因为篇幅有限,没有把全部特征都进行分析。
数据分析很强大,能从一大堆数据中找出许多有意思的规律出来。已经是每个人不可或缺的技能了!小编希望你能早点学好Python,早日成为大神哦!更多干货内容,欢迎关注公众号:知了python