泰坦尼克號生還率影響因素分析
學了一段時間Python,找來Kaggle競賽很火熱的泰坦尼克號數據進行分析來作為這段時間學習的總結。本文將用圖表逐個分析各個欄位對生還率的影響。
代碼所需數據下載地址:https://www.kaggle.com/c/titanic/data
一、載入分析要用到的庫
import pandas as pdimport numpy as npfrom pandas import Series,DataFrameimport seaborn as sns
二、獲取數據
data_train=pd.read_csv("/Users/Administrator/pandas/train.csv")data_train
查看具體欄位信息
data_train.info()<class pandas.core.frame.DataFrame>RangeIndex: 891 entries, 0 to 890Data columns (total 12 columns):PassengerId 891 non-null int64Survived 891 non-null int64Pclass 891 non-null int64Name 891 non-null objectSex 891 non-null objectAge 714 non-null float64SibSp 891 non-null int64Parch 891 non-null int64Ticket 891 non-null objectFare 891 non-null float64Cabin 204 non-null objectEmbarked 889 non-null objectdtypes: float64(2), int64(5), object(5)memory usage: 66.2+ KB
其中各個欄位代表的含義如下:
PassengerId:乘客序號;
Survived:最終是否存活(1表示存活,0表示未存活);
Pclass:艙位,1是頭等艙,3是最低等;
Name:乘客姓名;
Sex:性別;
Age:年齡;
SibSp:一同上船的兄弟姐妹或配偶;
Parch:一同上船的父母或子女;
Ticket:船票信息;
Fare:乘客票價,決定了Pclass的等級;
Cabin:客艙編號,不同的編號對應不同的位置;
Embarked:上船地點,主要是S(南安普頓)、C(瑟堡)、Q(皇后鎮)。
三、數據清洗
3.1 Passengerid,Name,Ticket這幾個變數和是否生還無關,捨棄
data_train.drop(["PassengerId","Name","Ticket"],axis=1)
3.2 填充年齡缺失值
求年齡的平均值,標準差以及缺失值的數量
average_age=data_train["Age"].mean()std_age=data_train["Age"].std()count_nan_age=data_train["Age"].isnull().sum()
求年齡的隨機數,範圍在(mean-std,mean+std)
rand_age=np.random.randint(average_age-std_age,average_age+std_age,size=count_nan_age)
將隨機數填充進Age的缺失值中
data_train["Age"][np.isnan(data_train["Age"])]=rand_agedata_train["Age"].describe()count 891.000000mean 29.675836std 13.605008min 0.42000025% 21.00000050% 29.00000075% 38.000000max 80.000000Name: Age, dtype: float64
樣本的891人中,平均年齡約為30歲,標準差約為14歲,最小年齡為0.42歲,最大年齡為80歲。
3.3 填充登船口岸缺失值
Embarked 有兩個缺失值,用眾數填充
data_train["Embarked"]=data_train["Embarked"].fillna("S")
3.4 數據重構
SibSp和Parch表示的都是家人,可劃歸為一個變數。將SibSp、Parch特徵構建一個新特徵:家庭人口總數familysize
data_train.loc[:,"SibSp"]data_train.loc[:,"Parch"]data_train["familysize"]=data_train.loc[:,"SibSp"]+data_train.loc[:,"Parch"]+1data_train.head()
四、數據分析
4.1 數據的基本情況
891人當中,有多少人生還,多少人未生還
total_survived_num=data_train["Survived"].sum()total_notsurvived_num=891-total_survived_numprint ("生還者 %d 人。%d人未生還。"%(total_survived_num,total_notsurvived_num))
生還者 342 人。549人未生還。
survived_rate=float(data_train[Survived].sum())/data_train[Survived].count()print("生還率為:",survived_rate)
生還率為: 0.383838383838
我們用圖來看一下生還情況。
import matplotlib.pyplot as plt%matplotlib inlinefig=plt.figure()plt.figure(figsize=(10,5),dpi=80)fig.set(alpha=0.2)plt.subplot(121)data_train.Survived.value_counts().plot(kind=bar)plt.title("生還情況(1為生還)")plt.ylabel("人數")ax=plt.gca()ax.set_xticklabels(["未生還","生還"])plt.subplot(122)plt.pie([total_notsurvived_num,total_survived_num],labels=["未生還","生還"],autopct="%1.0f%%")plt.title("生還比率")plt.show()
由圖可知,這891名乘客中,生還和未生還的比例為38%和62%。
下面分別分析Pclass、Sex、Age、Familysize、Fare、Cabin和Embarked與是否生還的關係。
4.2 船艙等級與生還的關係
災難發生前各等艙的人數
data_train[["Pclass","Survived"]].groupby(["Pclass"]).count()
Survived
Pclass1:216
Pclass2:184
Pclass3:491
我們畫圖看一下
fig=plt.figure()plt.figure(figsize=(10,5),dpi=80)fig.set(alpha=0.2)plt.subplot(121)data_train.Pclass.value_counts().plot(kind=bar)plt.title("各等艙位乘客分布")plt.ylabel("人數")ax=plt.gca()ax.set_xticklabels([三等艙,一等艙,二等艙])plt.subplot(122)plt.pie(data_train[["Pclass","Survived"]].groupby(["Pclass"]).count(),labels=[一等艙,二等艙,三等艙],autopct="%1.0f%%")plt.title("各等艙位乘客比例")plt.show()
由以上可知,災難發生前,一等艙、二等艙、三等艙乘客人數分別為216人、184人、491人,分別佔總人數的24%、21%、55%.
災難發生後生還的人數
survived_1=data_train[data_train["Survived"]==1]survived_1[["Pclass","Survived"]].groupby(["Pclass"]).count()
Survived
Pclass1:136
Pclass2:87
Pclass3:119
我們繼續畫圖看一下
plt.figure(figsize=(10,5),dpi=80)plt.subplot(121)sns.countplot(x="Pclass",data=survived_1)plt.title("各等艙位生還人數")plt.ylabel("生還人數")ax=plt.gca()ax.set_xticklabels([一等艙,二等艙,三等艙])plt.subplot(122)plt.pie(survived_1[["Pclass","Survived"]].groupby(["Pclass"]).count(),labels=[一等艙,二等艙,三等艙],autopct="%1.0f%%")plt.title("各等艙位生還比例")plt.show()
災難發生後,一等艙、二等艙、三等艙的生還人數分別為136、87、119,分別佔總人數的40%、25%、35%。
接下來,我們看一看不同等級艙位生還和未生還人數及生還率
pclass1=data_train[data_train["Pclass"]==1]pclass2=data_train[data_train["Pclass"]==2]pclass3=data_train[data_train["Pclass"]==3]plt.figure(figsize=(10,20))plt.subplot(421)sns.countplot(x="Survived",data=pclass1)plt.title("一等艙")plt.ylabel("人數")ax=plt.gca()ax.set_xticklabels(["未生還","生還"])plt.subplot(422)plt.pie([pclass1["Survived"][pclass1["Survived"]==0].count(),pclass1["Survived"][pclass1["Survived"]==1].count()], labels=["未生還","生還"],autopct="%1.0f%%")plt.subplot(423)sns.countplot(x="Survived",data=pclass2)plt.title("二等艙")plt.ylabel("人數")ax=plt.gca()ax.set_xticklabels(["未生還","生還"])plt.subplot(424)plt.pie([pclass2["Survived"][pclass2["Survived"]==0].count(),pclass2["Survived"][pclass2["Survived"]==1].count()], labels=["未生還","生還"],autopct="%1.0f%%")plt.subplot(425)sns.countplot(x="Survived",data=pclass3)plt.title("三等艙")plt.ylabel("人數")ax=plt.gca()ax.set_xticklabels(["未生還","生還"])plt.subplot(426)plt.pie([pclass3["Survived"][pclass3["Survived"]==0].count(),pclass3["Survived"][pclass3["Survived"]==1].count()], labels=["未生還","生還"],autopct="%1.0f%%")plt.subplot(427)survived_by_pclass=data_train.groupby("Pclass")["Survived"].mean()survived_by_pclass.plot(kind="bar")ax=plt.gca()ax.set_xticklabels(["一等艙","二等艙","三等艙"])plt.ylabel("生還率")plt.savefig(3.png,dpi=90)plt.show()
由以上圖表可見,一等艙生還率為63%,二等艙生還率為47%,三等艙生還率為24%。由此可見,客艙等級越高,生還率越高。
我們用一個堆積直方圖更直觀的看一下各個等級艙位的生還情況
fig=plt.figure()fig.set(alpha=0.2)Survived_0=data_train.Pclass[data_train.Survived==0].value_counts()Survived_1=data_train.Pclass[data_train.Survived==1].value_counts()df=pd.DataFrame({"生還":Survived_1,"未生還":Survived_0})df.plot(kind="bar",stacked=True)plt.title("各乘客等級的生還情況")plt.xlabel("乘客等級")plt.ylabel("人數")plt.show()
4.3 性別與生還的關係
船上男女人數及比例
male_sum=data_train["Sex"][data_train["Sex"]=="male"].count()female_sum=data_train["Sex"][data_train["Sex"]=="female"].count()print ("男士: %d人。女士: %d人。"%(male_sum,female_sum))
男士: 577人。女士: 314人。
Sex_survived_rate=(data_train.groupby([Sex]).sum()/data_train.groupby([Sex]).count())[Survived]print ("生還率",Sex_survived_rate)
生還率 Sex
female 0.742038
male 0.188908Name: Survived, dtype: float64畫圖看一下
plt.figure(figsize=(10,5))plt.subplot(121)sns.countplot(x="Sex",data=data_train)plt.subplot(122)plt.pie([male_sum,female_sum],labels=["男士","女士"],autopct="%1.0f%%")plt.show()
災難發生前,891人中,男士有577人,女士314人,男女比例為65%和35%。
接下來我們畫一下男女的生還率
Sex_survived_rate=(data_train.groupby([Sex]).sum()/data_train.groupby([Sex]).count())[Survived]Sex_survived_rate.plot(kind=bar)
由圖可知女士的生還率要高出男士很多。
接下來我們看一下詳細的數據。
災難發生後生還的男女數量及比例
survived_male_sum=survived_1["Sex"][survived_1["Sex"]=="male"].count()survived_female_sum=survived_1["Sex"][survived_1["Sex"]=="female"].count()print ("生還的男士: %d人。生還的女士: %d人。"%(survived_male_sum,survived_female_sum))
生還的男士: 109人。生還的女士: 233人。
用圖形表達
plt.figure(figsize=(10,5))plt.subplot(121)sns.countplot(x="Sex",data=survived_1)plt.subplot(122)plt.pie([survived_male_sum,survived_female_sum],labels=["生還的男士","生還的女士"],autopct="%1.0f%%")plt.show()
由圖可見,災難發生後,男士生還109人,女士生還233人,男女比例變為32%和68%。
災難發生前後男女的生還率
data_man=data_train[data_train["Sex"]=="male"]data_female=data_train[data_train["Sex"]=="female"]plt.figure(figsize=(10,10))plt.subplot(221)sns.countplot(x="Survived",data=data_man)plt.title("生還的男士數量")plt.subplot(222)plt.pie([data_man["Survived"][data_man["Survived"]==0].count(),data_man["Survived"][data_man["Survived"]==1].count()],labels=["生還的男士","生還的男士"],autopct="%1.0f%%")plt.subplot(223)sns.countplot(x="Survived",data=data_female)plt.title("生還的女士數量")plt.subplot(224)plt.pie([data_female["Survived"][data_female["Survived"]==0].count(),data_female["Survived"][data_female["Survived"]==1].count()],labels=["生還的女士","生還的女士"], autopct="%1.0f%%")plt.show()
由圖可見,災難發生後女士的生還率為74%,男士的生還率僅為19%,說明災難發生時踐行了女士優先的原則。
最後我們用一個堆積直方圖更直觀的看一下男性與女性的生還情況
fig=plt.figure()fig.set(alpha=0.2)Survived_m=data_train.Sex[data_train.Survived==0].value_counts()Survived_f=data_train.Sex[data_train.Survived==1].value_counts()df=pd.DataFrame({"生還":Survived_f,"未生還":Survived_m})df.plot(kind=bar,stacked=True)plt.title("各性別的生還情況")plt.xlabel("性別")plt.ylabel("人數")plt.savefig("24.png",dpa=75)plt.show()
4.4 年齡與生還的關係
首先我們看一下年齡分布
plt.figure(figsize=(12,5))plt.subplot(121)data_train["Age"].hist(bins=70)plt.xlabel("年齡分布")plt.ylabel("數量")plt.subplot(122)data_train.boxplot(column="Age",showfliers=False)plt.show()
接下來我們看一下不同年齡的生還率
Sex_survived_rate=(data_train.groupby([Age]).sum()/data_train.groupby([Age]).count())[Survived]Sex_survived_rate.plot()
貌似老人和兒童的生還率要高一些,為了驗證這個想法,我們按照年齡,將乘客劃分為兒童、少年、成年人和老年人,分析四個群體生還情況。
children_data=data_train[data_train["Age"]<=12]junior_data=data_train[(data_train["Age"]>12) & (data_train["Age"]<=18)]adult_data=data_train[(data_train["Age"]>18)& (data_train["Age"]<=65)]old_data=data_train[data_train["Age"]>65]
各年齡段生還率
children_survived_rate=children_data["Survived"].mean()junior_survived_rate=junior_data["Survived"].mean()adult_survived_rate=adult_data["Survived"].mean()old_survived_rate=old_data["Survived"].mean()print ("兒童生還率為:%f ,少年生還率為:%f ,成年人生還率為:%f ,老年人生還率為:%f " %(children_survived_rate,junior_survived_rate,adult_survived_rate,old_survived_rate))兒童生還率為:0.579710 ,少年生還率為:0.369565 ,成年人生還率為:0.369806 ,老年人生還率為:0.125000
用直方圖表示
bins=[0,12,18,65,100]data_train["Age_group"]=pd.cut(data_train["Age"],bins)by_age=data_train.groupby("Age_group")["Survived"].mean()by_age.plot(kind="bar")plt.title("各年齡段的生還率")
由圖可知,兒童的生還率最高,老年人的生還率最低。
4.5 家人與生還的關係
#把數據劃分為有家人和沒家人兩組family_1=data_train[data_train["familysize"]!=1]family_0=data_train[data_train["familysize"]==1]plt.figure(figsize=(10,10))#有家人的生還人數和生還率plt.subplot(221)sns.countplot(x="Survived",data=family_1)plt.title("有家人的乘客的生還人數")plt.subplot(222)plt.pie([family_1["Survived"][family_1["Survived"]==0].count(),family_1["Survived"].sum()],labels=["未生還的比例","生還的比例"],autopct="%1.0f%%")#無家人的生還人數和生還率plt.subplot(223)sns.countplot(x="Survived",data=family_0)plt.title("無家人的乘客的生還人數")plt.subplot(224)plt.pie([family_0["Survived"][family_0["Survived"]==0].count(),family_0["Survived"].sum()],labels=["未生還的比例","生還的比例"],autopct="%1.0f%%")plt.show()
由圖可知,有家人的生還比例為51%,沒家人的生還比例為30%,影響還是蠻大的。
接下來看一下家人數量的多少與生還率之間的關係
familysize_rate=((data_train.groupby([familysize]).sum())/(data_train.groupby([familysize]).count()))[Survived]familysize_rate.plot(kind=bar)
由圖可以看出家人數量在2、3、4的時候生還率比較高。
4.6 票價與生還的關係
票價分布
plt.figure(figsize=(10,5))data_train["Fare"].hist(bins=70)data_train.boxplot(column="Fare",by="Pclass",showfliers=False)plt.savefig("13.png",dpa=90)plt.show()
fare_not_survived = data_train["Fare"][data_train["Survived"] == 0]fare_survived= data_train["Fare"][data_train["Survived"] == 1]avgerage_fare= pd.DataFrame([fare_not_survived.mean(), fare_survived.mean()])std_fare= pd.DataFrame([fare_not_survived.std(), fare_survived.std()])avgerage_fare.plot(yerr=std_fare,kind=bar,legend=False)plt.show()
可見,票價與生還有一定相關性,生還者的平均票價要比未生還的高。
4.7 客艙號與生還的關係
由於Cabin缺失值較多,無法分析具體的客艙號和生還的關係,我們可以分析客艙號的有無與生還的關係。
首先把Cabin中所有空值填充為0
data_train["Cabin"]=data_train["Cabin"].fillna("0")
我們直接用圖觀察客艙號的有無與生還的關係
cabin_1=data_train[data_train["Cabin"]!="0"]cabin_0=data_train[data_train["Cabin"]=="0"]plt.figure(figsize=(10,5))plt.subplot(121)sns.countplot(x="Survived",data=cabin_1)plt.title("有客艙號的生還情況")plt.subplot(122)sns.countplot(x="Survived",data=cabin_0)plt.title("無客艙號的生還情況")plt.show()
由圖可以得知有客艙號的生還人數較多,無客艙號的生還人數較少,我們可以猜測一般情況客艙號保留完整的說明災難發生時的損害較小,乘客的生還率就會更高。
4.8 登船口岸與生還的關係
我們先看一下各個登船口岸的生還率
embarked_rate=((data_train.groupby([Embarked]).sum())/(data_train.groupby([Embarked]).count()))[Survived]embarked_rate.plot(kind=bar)plt.title("各登船口岸的生還率")
由圖可知,從C港口上船的存活率最高,Q次之,S最低。
接下來我們詳細的看一下各港口上船人數、生還人數及生還率
plt.figure(figsize=(15,10))plt.subplot(221)sns.countplot(x="Embarked",data=data_train)plt.subplot(222)sns.countplot(x="Survived",hue="Embarked",data=data_train,order=[1,0])plt.subplot(223)embark_1=data_train[["Embarked","Survived"]].groupby(["Embarked"],as_index=False).mean()sns.barplot(x="Embarked",y="Survived",data=embark_1,order=["S","C","Q"])plt.show
由圖可知,S 港口生還人數最多,C 次之,Q 最少。從生還率來看, C 港上船的生還率最高, Q 次之, S 生還率最低。其實生還率高低與在哪個港口上船影響不大,有影響的應該是船艙等級與票價。
五、 總結
綜上所述:
1、泰坦尼克號整體的生還率約為39%。
2、生還率與客艙等級的關係:客艙等級越高,生還率越高。
3、生還率與性別的關係:女性的生還率是男性的3倍還要多。說明西方人很好的做到了「女士優先」這一紳士精神。
4、把年齡按照兒童、青年、成年人、老人分組後看齣兒童的生還率要明顯高於其他群體,說明大家對兒童比較重視。
5、生還率與家人的關係:當同行2-4個親人朋友時的生還率更高。所以我們盡量不要單獨出遊。
6、生還率與票價的關係:票價越高生還率越高,這跟客艙等級一致。
7、生還率與客艙號的關係:有客艙號數據的旅客生還率較高,無客艙號數據的旅客生還率較低,說明有客艙號數據的損害較輕。
8、生還率與登船口岸的關係:C、Q、S三地的生還率依次下降,不過應該和登陸地本身是沒啥關係的,登陸地可能最終體現在性別、艙位等級等方面。
推薦閱讀:
※泰坦尼克號沉沒的真正原因是什麼?是由於鋼材不純導致冰山造成的六個3-4米的洞,還是因為白星輪船公司為騙保而有意撞冰山?
※如果《泰坦尼克號》發生在現代,世界上有哪些救援手段?
※泰坦尼克的結尾,為什麼導演讓傑克和露絲在所有人的注視下,相聚,接吻?
※預測泰坦尼克號客戶的生存率
※尼可的戰艦打造:工藝戰艦泰坦尼克?
TAG:数据分析 | 「泰坦尼克号」沉没事故 | Python |