关于泰坦尼克号生存率的数据分析

首先通过观察数据,可以了解到每位旅客的详细数据:

  • Survived:是否存活(0代表否,1代表是)
  • Pclass:舱位(一等舱,二等舱,三等舱)
  • Name:船上乘客的名字
  • Sex:船上乘客的性别
  • Age:船上乘客的年龄(可能存在 NaN)
  • SibSp:乘客在船上的兄弟姐妹和配偶的数量
  • Parch:乘客在船上的父母以及小孩的数量
  • Ticket:乘客船票的编号
  • Fare:乘客为船票支付的费用
  • Cabin:乘客所在船舱的编号(可能存在 NaN)
  • Embarked:乘客上船的港口(C 代表从 Cherbourg 登船,Q 代表从 Queenstown 登船,S 代表从 Southampton 登船)

通过对原始数据的初步观察可以发现存活率和社会等级,性别,年龄,在船上的兄弟姐妹和配偶数量,在船上的父母以及小孩的数量有着某种联系。因此根据初步推测可以提出以下几个问题并进行分析:

  • 乘客的存活率和其社会等级是否有关系?是否社会等级越高存活率就越高?
  • 乘客的存活率和其性别,年龄又有什么关系?
  • 乘客的存活率和其在船上的兄弟姐妹和配偶数量,父母以及小孩的数量又有什么联系?

In [2]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pylab as pl
%matplotlib inline
filename = './titanic-data.csv'
titanic_df = pd.read_csv(filename)
titanic_df.describe()


Out[2]:
PassengerId Survived Pclass Age SibSp Parch Fare
count 891.000000 891.000000 891.000000 714.000000 891.000000 891.000000 891.000000
mean 446.000000 0.383838 2.308642 29.699118 0.523008 0.381594 32.204208
std 257.353842 0.486592 0.836071 14.526497 1.102743 0.806057 49.693429
min 1.000000 0.000000 1.000000 0.420000 0.000000 0.000000 0.000000
25% 223.500000 0.000000 2.000000 20.125000 0.000000 0.000000 7.910400
50% 446.000000 0.000000 3.000000 28.000000 0.000000 0.000000 14.454200
75% 668.500000 1.000000 3.000000 38.000000 1.000000 0.000000 31.000000
max 891.000000 1.000000 3.000000 80.000000 8.000000 6.000000 512.329200
  • 首先,我们观察一下几个比较重要的数值,初步得出一些结论,比如只有‘Age’这一列存在缺失值,整体的存活率只有0.383838。所以首先应该对年龄的缺失值进行填充。

In [26]:
titanic_df = titanic_df.fillna(method='pad')#用前一个数值填充

titanic_df.describe()


Out[26]:
PassengerId Survived Pclass Age SibSp Parch Fare
count 891.000000 891.000000 891.000000 891.00000 891.000000 891.000000 891.000000
mean 446.000000 0.383838 2.308642 29.58156 0.523008 0.381594 32.204208
std 257.353842 0.486592 0.836071 14.55459 1.102743 0.806057 49.693429
min 1.000000 0.000000 1.000000 0.42000 0.000000 0.000000 0.000000
25% 223.500000 0.000000 2.000000 20.00000 0.000000 0.000000 7.910400
50% 446.000000 0.000000 3.000000 28.00000 0.000000 0.000000 14.454200
75% 668.500000 1.000000 3.000000 38.00000 1.000000 0.000000 31.000000
max 891.000000 1.000000 3.000000 80.00000 8.000000 6.000000 512.329200
  • 可以看出年龄这一列数据的总数正常了,为891,接下来可以进一步分析生存率了。

In [36]:
sort_pclass = titanic_df.groupby('Pclass').count()['PassengerId']
print sort_pclass
titanic_df.groupby('Pclass')['PassengerId'].count().plot(kind = 'pie',autopct = '%.0f%%')
plt.title('Pclass VS Count')
plt.show()


Pclass
1    216
2    184
3    491
Name: PassengerId, dtype: int64

In [37]:
Pclass_survived = titanic_df.groupby('Pclass').mean()['Survived']
print Pclass_survived.plot.bar()


Axes(0.125,0.125;0.775x0.755)
  • 根据以上不同舱位人数所占比例和关于生存率的直方图可以看出头等舱的生存率最高,经济舱的生存率最低。虽然头等舱的人数占总人数的比例很少,生存率却极高,三等舱的人数超过一半,而生存率确只有20%,间接的说明了一个现实问题:社会地位越高生存机率越高。或者说头等舱的安全措施很高

In [46]:
sort_sex = titanic_df.groupby('Sex').count()['PassengerId']
print sort_sex
Sex_survived = titanic_df.groupby('Sex').mean()['Survived']
print Sex_survived
print Sex_survived.plot.bar()


Sex
female    314
male      577
Name: PassengerId, dtype: int64
Sex
female    0.742038
male      0.188908
Name: Survived, dtype: float64
Axes(0.125,0.125;0.775x0.755)
  • 我们可以清晰的看到虽然船上的男性人数显著多于女性人数,但是女性的存活率高达74%,而男性的存活率只有19%。这说明在逃生的时候会有男性保护女性的情况。一般是女先男后。

In [47]:
titanic_df['Age_bins'] = pd.cut(titanic_df['Age'],range(0,80,10))
Age_survived = titanic_df.groupby('Age_bins').mean()['Survived']
Sort_survived = titanic_df.groupby('Age_bins').count()['Survived']
print Age_survived
print Sort_survived


Age_bins
(0, 10]     0.564706
(10, 20]    0.361702
(20, 30]    0.334520
(30, 40]    0.424242
(40, 50]    0.357798
(50, 60]    0.358491
(60, 70]    0.315789
Name: Survived, dtype: float64
Age_bins
(0, 10]      85
(10, 20]    141
(20, 30]    281
(30, 40]    198
(40, 50]    109
(50, 60]     53
(60, 70]     19
Name: Survived, dtype: int64

In [48]:
Age_survived.plot(kind='bar', stacked=True)


Out[48]:
<matplotlib.axes._subplots.AxesSubplot at 0x114a77450>
  • 可见0~10岁的儿童成活率是最高的,也说明了在家长陪同下的婴幼儿受到了很好的保护,超过60岁的老年人成活率非常低,由此我们可以推测老年人可能会因为年迈行动不便而导致在灾难中无法及时脱身。在10~60各个年龄阶段的生存率几本相等。

In [42]:
sort_SibSp = titanic_df.groupby('SibSp').count()['PassengerId']
print sort_SibSp
titanic_df.groupby('SibSp')['PassengerId'].count().plot(kind = 'pie',autopct = '%.0f%%')
plt.title('SibSp VS Count')
plt.show()


SibSp
0    608
1    209
2     28
3     16
4     18
5      5
8      7
Name: PassengerId, dtype: int64

In [52]:
SibSp_survived = titanic_df.groupby('SibSp').mean()['Survived']
print SibSp_survived
SibSp_survived.plot.bar()


SibSp
0    0.345395
1    0.535885
2    0.464286
3    0.250000
4    0.166667
5    0.000000
8    0.000000
Name: Survived, dtype: float64
Out[52]:
<matplotlib.axes._subplots.AxesSubplot at 0x114bf2110>

In [49]:
sort_Parch = titanic_df.groupby('Parch').count()['PassengerId']
print sort_Parch
titanic_df.groupby('Parch')['PassengerId'].count().plot(kind = 'pie',autopct = '%.0f%%')
plt.title('Parch VS Count')
plt.show()


Parch
0    678
1    118
2     80
3      5
4      4
5      5
6      1
Name: PassengerId, dtype: int64

In [53]:
Parch_survived = titanic_df.groupby('Parch').mean()['Survived']
print Parch_survived
Parch_survived.plot.bar()


Parch
0    0.343658
1    0.550847
2    0.500000
3    0.600000
4    0.000000
5    0.200000
6    0.000000
Name: Survived, dtype: float64
Out[53]:
<matplotlib.axes._subplots.AxesSubplot at 0x1140b7750>
  • 通过乘客在船上的家庭成员数量与生存率的折线图可以推测:家庭成员数在1~3之间的时候生存率是比较高的,在船上没有家庭成员的相对有1~3个的生存率就比较低了,当家庭成员的数量超过4的时候就更低了,甚至到6~8个的生存率直接为零.

综合以上分析可以得出结论

根据对数据的一些分析得到的结果基本和猜测的一致,女性生存率比男性的3倍还要多,对舱位的大体分析可以看出头等舱二等舱的生存率是比较高的,这也客观的反映了当时对富人阶级的优待,可猜测在头等舱和二等舱放的救生艇会更多,关于年龄,只能明确得出0~10岁的生存率最高,老年人最低,符合常理。

局限性

  • 可能会存在数据的缺失,也就是说这个样本数据不能代表整体数据,例如有的时候会存在一票多用的情况,这个时候计算结果会有偏差。
  • 在分析年龄这一列的时候,使用的是前面的一个数填充缺失值,并不能代表真是数据,因此对年龄和生存率的分析也会存在一些偏差。
  • 在分析单变量与生存率的关系的时候,可能会有其他不确定性因素的影响。

In [ ]: