Python 数据分析微专业课程--项目实战14 泰坦尼克号获救问题

1.项目说明

对泰坦尼克号乘客数据进行分析,挖掘获救乘客和遇难乘客的数据特点以及与其他因素的相关性

2.项目具体要求

1、整体来看,存活比例如何?
要求:
① 读取已知生存数据train.csv
② 查看已知存活数据中,存活比例如何?

2、结合性别和年龄数据,分析幸存下来的人是哪些人?
要求:
① 年龄数据的分布情况
② 男性和女性存活情况
③ 老人和小孩存活情况

3、结合 SibSp、Parch字段,研究亲人多少与存活的关系
要求:
① 有无兄弟姐妹/父母子女和存活与否的关系
② 亲戚多少与存活与否的关系

4、结合票的费用情况,研究票价和存活与否的关系
要求:
① 票价分布和存活与否的关系
② 比较研究生还者和未生还者的票价情况

5、利用KNN分类模型,对结果进行预测
要求:
① 模型训练字段:'Survived','Pclass','Sex','Age','Fare','Family_Size'
② 模型预测test.csv样本数据的生还情况 

3.实现思路:

1.先计算整体的存活率,查看男女的存活率有什么差异,然后深入分析男性和女性的不同年龄段的存活人数和占比,
来分析性别和年龄和存活率有什么联系。通过分析不同等级舱和年龄存活率,来分析等级舱和年龄和存活率的关系。
单独分析不同年龄存活率的分布来查看老人和儿童存活率是怎么样。

2.基础数据中有乘客小孩即家庭成员的数据,因此可以使用饼图来直观展示有小孩和没有小孩乘客的存活率有何差异,
有家人的乘客和没有家人的乘客存活率有和差异。如果有明显差异,可以深入分析小孩和家庭成员的数量对存活率是否有联系。

3.分析票价和存活是否有关可以先分析所有乘客的票价分布情况,以及不同等级舱的票价分布情况,然后通过分析幸存者和
遇难者的票价的平均值即标准差来分析票价与存活率的联系。

4.通过已有的乘客的数据来预测乘客是否可以生还,这里可使用KNN分类模型来对已有数据进行机器学习,根据以上分析我们可以
与生还有关的一些数据,可以用这些数据进行学习,生成预测模型来对测试数据中的乘客的生还情况进行预测

4.实现过程:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
import time
# 导入时间模块

sns.set_style('darkgrid')

import warnings
warnings.filterwarnings('ignore') 
# 不发出警告

os.chdir(r'D:\IT\python数据分析师\项目15\项目15泰坦尼克号获救问题')

#1、整体来看,存活比例如何?
#要求:
#① 读取已知生存数据train.csv
#② 查看已知存活数据中,存活比例如何?

#读取数据
train_data=pd.read_csv('train.csv')
test_data=pd.read_csv('test.csv')

sns.set()
sns.set_style("ticks")
plt.axis('equal')
train_data['Survived'].value_counts().plot.pie(autopct = '%.2f%%')
print('存活比例为38.38%')


'''
2、结合性别和年龄数据,分析幸存下来的人是哪些人?
要求:
① 年龄数据的分布情况
② 男性和女性存活情况
③ 老人和小孩存活情况
'''
#筛选年龄和性别数据,并去掉空值
age_data = train_data[['Survived','Age','Sex']].dropna()

#绘制年龄分布直方图
plt.figure(figsize=(12,5))
plt.subplot(121)
age_data['Age'].hist(bins=70,color = 'gray',edgecolor = 'white')
plt.xlim([0,90])
plt.xlabel('Age')
plt.ylabel('Num')

#绘制年龄分布箱型图
plt.subplot(122)
age_data.boxplot(column='Age',showfliers=False)

plt.savefig('age_hist_box.png')
age_data['Age'].describe()
print('总体年龄分布: 去掉缺失值后样本有714,平均年龄约为30岁,标准差14岁,最小年龄0.42,最大年龄80.')

#筛选性别数据
sex_count = train_data[['Survived','Sex']]
#根据性别分组求均值,即不同性别的存活率
sex_sur = sex_count.groupby('Sex').mean().reset_index() 

#绘制男性和女性的生存率柱状图
sex_sur.plot(kind = 'bar',x = 'Sex',y = 'Survived',color = 'blue',alpha = 0.7,label = 'Survived',figsize = (8,6))
plt.grid(linestyle = '--')

plt.savefig('sex_survived.png')
print(sex_sur)
print('女性存活率为%.2f%%,男性存活率为%.2f%%' % (sex_sur.iloc[0,1]*100,sex_sur.iloc[1,1]*100))

#计算不同年龄段,不同性别的生存率,并绘制柱状图和折线图
#按10岁为间隔划分成不同年龄段
s = np.arange(0,81,10)
age_data['cut'] = pd.cut(age_data['Age'],bins =s )

#根据性别,年龄段,是否存活分组
age_cut_data = age_data.groupby(['Survived','Sex','cut']).size().reset_index()
#根据是否存活,将数据分成两部分
age_sur = age_cut_data[age_cut_data['Survived']==1]
age_non = age_cut_data[age_cut_data['Survived']==0]

#根据性别和年龄段连接数据
age_cut_data1 = pd.merge(age_sur,age_non,on = ['Sex','cut'],how = 'outer',suffixes=('_s','_n'))
age_cut_data1 = age_cut_data1[['cut','Sex','0_s','0_n']]
#重命名字段,填充空值
age_cut_data1.columns = ['age_cut','sex','survived','non_survived']
age_cut_data1[['survived','non_survived']] = age_cut_data1[['survived','non_survived']].fillna(0)
#添加各年龄段总人数字段
age_cut_data1['total'] = age_cut_data1['survived']+age_cut_data1['non_survived']
#计算各年龄段存活率字段
age_cut_data1['sur_per'] = age_cut_data1['survived']/age_cut_data1['total']

#创建子图对象
f, axs = plt.subplots(2,1,figsize=(12, 12))

# 绘制各年龄段男性和女性人数柱状图
sns.barplot(x="age_cut", y="total",hue = 'sex', data=age_cut_data1,
        palette='Blues',edgecolor = 'w',ax = axs[0])


#绘制各年龄段幸存者男性和女性人数柱状图
sns.barplot(x="age_cut", y="survived",hue = 'sex', data=age_cut_data1,
        palette='Reds',edgecolor = 'w',ax = axs[0])

axs[0].grid(linestyle = '--')
axs[0].legend(loc="top right")

#绘制各年龄段不同性别的生存率折线图
sns.pointplot(x = 'age_cut',y = 'sur_per',data = age_cut_data1,hue = 'sex',ax = axs[1])
axs[1].grid(linestyle = '--')
axs[1].legend(loc = 'top left')

plt.savefig('sex_sur.png')

print('女性各个年龄段存活率指标:\n',age_cut_data1.loc[age_cut_data1['sex']=='female','sur_per'].describe())
print('男性各个年龄段存活率指标:\n',age_cut_data1.loc[age_cut_data1['sex']=='male','sur_per'].describe())
print('女性存活率整体都在60%以上,男性整体在20%以下,0-10岁男性和女性存活率相当')
print('按幸存者个数来看,20-40岁的男性和女性幸存人数相对较多')

#筛选等级舱,年龄,性别数据
class_data = train_data.loc[train_data['Age'].notnull(),['Survived','Pclass','Sex','Age']]

#按照等级舱划分绘制琴图,查看年龄分布
fig,axs = plt.subplots(1,2,figsize = (15,6))
sns.violinplot(x = 'Pclass',y= 'Age',hue = 'Survived',data = class_data,split = True,ax = axs[0])
axs[0].grid(linestyle = '--')
axs[0].set_yticks(np.arange(0,100,10))

#按照性别划分绘制琴图,查看年龄分布
sns.violinplot(x = 'Sex',y= 'Age',hue = 'Survived',data = class_data,split = True,ax = axs[1])
axs[1].grid(linestyle = '--')
axs[1].set_yticks(np.arange(0,100,10))

plt.savefig('pclass.png')
print('按照等级舱划分:1等舱幸存者人数相比2,3等级要多,等级越高幸存者整体年龄越大,等级2,3中有较多10岁以下儿童幸存')
print('按照性别划分:女性幸存者明显多于男性,幸存者主要分布在20至40岁,10岁以下有较多幸存者,其中男孩更多')

#筛选年龄数据,对小数求整
class_data['Age'] = class_data['Age'].apply(lambda x:int(x))
#根据年龄分组求均值,即不同年龄的生存率
age_sur = class_data.groupby('Age')[['Survived']].mean().reset_index()

#绘制不同年龄的生存率柱状图
fig,ax = plt.subplots(figsize = (16,4))
sns.barplot(x = 'Age',y ='Survived',data = age_sur,palette='Blues',edgecolor ='black',ax = ax)
ax.grid(linestyle = '--')

plt.savefig('age_bar.png')
print('从年龄上来看,老人和小孩生存比例较高')

说明:
1.查看整体的存活率状况只需要根据’Survived’字段进行分组计数,然后根据数据绘制饼图就可以知道全部乘客中获救和遇难的比例。
2.分析年龄和性别于存活率的联系,首先需要查看年龄的分布情况和不同性别存活率情况,这里使用直方图和箱型图来查看分布情况,使用柱状图来比较不同性别的存活率。可知年龄主要分布在20~40岁,同时0-5岁的小孩子数量也比较多,女性存活率达到74%,远远高于男性18%。
3.进一步分布不同性别在不同年龄段上的存活率情况,首先使用pandas.cut()以10岁为间隔将年龄分段,然后筛选计算出不同性别,不同年龄段的幸存人数和遇难人数,然后计算存活率。
4.使用seaborn来绘制男性和女性不同年龄段遇难与幸存的人数的堆叠柱状图,根据存活率数据来绘制男性和女性在不同年龄段的存活率折线图。
5.不同等级舱遇难者和幸存者年龄分布有什么特点,这里使用seaborn绘制琴图来分析。
6.根据分析可得以下结论:
a.在这场事故中乘客存活率是38.38%,获救的乘客占总人数的小部分。
b.女性存活率为74.20%,男性存活率为18.89%,大部分女性获救,绝大部分男性乘客都遇难了,遇难最多的男性是20~30岁的青年男性。
c.男性乘客中除了0-10岁年龄段的存活率与女性相近以外,其他年龄段都远远低于女性,女性乘客中存活率最高的是60~70年龄段的。
说明当时现场救援是按照女士,老人和小孩优先的原则进行的。
d.1等舱幸存者人数相比2,3等级要多,等级越高幸存者整体年龄越大,等级2,3中有较多10岁以下儿童幸存

'''3、结合 SibSp、Parch字段,研究亲人多少与存活的关系
要求:
① 有无兄弟姐妹/父母子女和存活与否的关系
② 亲戚多少与存活与否的关系'''

#筛选SibSp、Parch数据
sp_data = train_data[['Survived','SibSp','Parch']]

#筛选计算SibSp,NO_SibSp,No_Parch,Parch生存和死亡人数
nosib_sur = sp_data.loc[sp_data['SibSp']==0,'Survived'].value_counts()
sib_sur = sp_data.loc[sp_data['SibSp']!=0,'Survived'].value_counts()
nopar_sur = sp_data.loc[sp_data['Parch']==0,'Survived'].value_counts()
par_sur = sp_data.loc[sp_data['Parch']!=0,'Survived'].value_counts()
label = ['No Survived','Survived']

#绘制SibSp,NO_SibSp,No_Parch,Parch生存和死亡人数饼图
fig,axs = plt.subplots(1,4,figsize = (18,4))
sib_sur.plot.pie(labels = label,colormap= 'Blues',autopct = '%.2f%%',ax = axs[0],title = 'sibsp')
nosib_sur.plot.pie(labels = label,colormap= 'Blues',autopct = '%.2f%%',ax = axs[1],title = 'no_sibsp')
par_sur.plot.pie(labels = label,colormap= 'Reds',autopct = '%.2f%%',ax = axs[2],title = 'parch')
nopar_sur.plot.pie(labels = label,colormap= 'Reds',autopct = '%.2f%%',ax = axs[3],title = 'no_parch')
plt.savefig('sp_pie.png')

print('有亲人的乘客存活率更大')

sp_data['family_size'] = sp_data['SibSp']+sp_data['Parch']
sibsp_sur = sp_data.groupby('SibSp')[['Survived']].mean().reset_index()
parch_sur=sp_data.groupby('Parch')[['Survived']].mean().reset_index()
family_sur = sp_data.groupby('family_size')[['Survived']].mean().reset_index()

sns.barplot(x = 'SibSp',y = 'Survived',data = sibsp_sur,color = 'skyblue',ax = axs[0])
axs[0].grid(linestyle = '--')
axs[0].set_title('SibSp and Survived')


sns.barplot(x = 'Parch',y = 'Survived',data = parch_sur,color = 'olive',ax = axs[1])
axs[1].grid(linestyle = '--')
axs[1].set_title('Parch and Survived')


plt.figure(figsize = (16,4))
sns.barplot(x = 'family_size',y = 'Survived',data = family_sur,color = 'firebrick')
plt.grid(linestyle = '--')
plt.title('Family_size and Survived')

print('家庭成员有2~4人的人的生存率相比单身一人或者家庭成员超过4人的明显要高,\n其中有1~3个小孩的人生存率要都超过50%')

说明:
1.先计算有小孩,无小孩,有亲戚,无亲戚乘客的遇难和死亡的数量,然后分别绘制饼图,根据饼图可直观的看到有小孩和亲戚的乘客的存活率更高。因此接下来可以进一步分析有小孩的数量和亲戚的数量和生存率的关系。
2.计算出拥有小孩或亲戚不同数量下的存活率数据,然后绘制柱状图,则可以分析出不同数量下生存率的变化情况,然后合并数据,计算不同家庭成员数量下的乘客的生存率数据,绘制柱状图。
3.根据分析可得以下结论:
a.家庭成员在1-3人的乘客的存活率相比单生一人和家庭成员人数超过3人的乘客更高。
b.有1-2个小孩的乘客的存活率更高。
c.说明在救援中对有小孩的乘客会优先照顾,但是小孩太多则可能会因为公平原则无法优先考虑。

'''
4、结合票的费用情况,研究票价和存活与否的关系
要求:
① 票价分布和存活与否的关系
② 比较研究生还者和未生还者的票价情况
'''
fare_data = train_data[['Survived','Pclass','Fare']]

fig,axs = plt.subplots(1,2,figsize = (16,4))
fare_data['Fare'].hist(bins = 40,edgecolor = 'black',ax = axs[0])
axs[0].set_xlim([0,600])
axs[0].grid(linestyle = '--')

fare_data.boxplot(column ='Fare',by = 'Pclass',showfliers=False,ax = axs[1])
axs[1].set_ylim([0,180])
axs[1].grid(linestyle = '--')


fare_average = fare_data.groupby('Survived').mean()
fare_std = fare_data.groupby('Survived')[['Fare']].std()
fare_average[['Fare']].plot(kind = 'bar',figsize = (16,6),ylim = [-20,120],yerr=fare_std,rot =0)
plt.grid(linestyle = '--')

print('获救者的平均票价大于未生还者的平均票价')

说明:
1.这里主要分析票价与存活率的关系,首先需要了解票价的整体分布情况和在不同等级舱的分布情况,这里绘制票价整体分布直方图和等级舱箱型图来分析。然后计算幸存者和遇难者的平均票价并绘制柱状图。
2.根据分析可得以下结论:
a.票价整体呈现指数下降,绝大部分乘客的票价都比较低。从等级舱票价箱型图可知,不同等级舱的票价相差很大,3等舱的大部分票价都不超过20.
b.幸存者的平均票价高于遇难者,幸存车票价票价分布差异较大,遇难者票价分布差距较小。
c.说明在救援中票价高的人存活率更高,在救援中按等级舱分为不同的优先等级。

'''5、利用KNN分类模型,对结果进行预测
要求:
① 模型训练字段:'Survived','Pclass','Sex','Age','Fare','Family_Size'
② 模型预测test.csv样本数据的生还率'''
from sklearn import neighbors

train_data['family_size'] = train_data['SibSp']+train_data['Parch']
train_data1 = train_data[['Pclass','Sex','Age','family_size','Fare','Survived']].dropna()
train_data1.loc[train_data1['Sex']=='male','Sex'] =1
train_data1.loc[train_data1['Sex']=='female','Sex'] =0


test_data['family_size'] = test_data['SibSp']+test_data['Parch']
pre_data = test_data[['Pclass','Sex','Age','family_size','Fare']].dropna()
pre_data.loc[pre_data['Sex']=='male','Sex'] =1
pre_data.loc[pre_data['Sex']=='female','Sex'] =0

knn = neighbors.KNeighborsClassifier()
knn.fit(train_data1.iloc[:,:-1],train_data1['Survived']) 
predict_result = knn.predict(pre_data)
pre_data['Survived'] = predict_result

说明:根据之前的分析一个乘客的存活率和其性别、年龄、小孩数量、亲戚数量、票价,等级舱有关。因此可以用这些数据来进行构建KNN分类模型
进行机器学习,一次来预测一个乘客的是否幸存。

5.总结

  • 该项目是一个经典的数据分析练习项目,可分析挖掘的地方还有很多,这里从几个主要的相关字段进行分析,分析其和乘客的存活率有
  • 什么联系。分析的点还算是比较全面,对数据的挖掘深度上还可以更加深入,例如可以分析不同等级舱不同性别各个年龄段的存活率。
  • 深入的分析需要更加多的数理统计方面的指示,做好数据分析需要对统计学,线性代数,微积分等基础数学知识一定的学习,以了解
    数据分析背后的原理。

猜你喜欢

转载自blog.csdn.net/zongzi009/article/details/82391034