数据分析学习之路——(三)从泰坦尼克号撞击冰山后开始说起
????????1912年4月14日,Titanic號在其處女航程中,不幸撞擊冰山沉沒在大西洋,超過1500名船員和乘客遇難,成為人類災難史上沉痛的一幕,而與之相關(guān)的一系列謠言猜測也為后人津津樂道。那么我們不禁會問,船上這么多人,到底有多少人活下來了,這些活下來的又是什么人呢?下面我們從一份泰坦尼克號乘客的數(shù)據(jù)集來獲取信息吧。
數(shù)據(jù)獲取
????????本數(shù)據(jù)集是kaggle網(wǎng)站上面提供的,是一份包含891名船上乘客(本文將船員和乘客統(tǒng)稱乘客)的樣本數(shù)據(jù);是一份csv格式,包含近十種乘客信息的數(shù)據(jù)集。
數(shù)據(jù)探索
????????用excel打開文件可以看到包含的乘客信息如下圖,再通過表格形式對每個字段說明一下。
? ? ? ? ????
??????????
? ? ? ? 我們從給出的信息來分析乘客的存活情況,像Ticket、Name這樣的字段并無太大意義,因此主要選擇Pclass、Sex、Age等字段信息來分析。例如我們印象深刻的救生圈優(yōu)先給女人和小孩,那么我們可以看看是否女人和小孩的存活率更高;再有,乘坐船艙的等級表示一個人的身份,那么我們可以這樣猜想:是否身份越高,生存下來的機會就越大呢?? ? ? ?
????????因此我們主要選取客艙等級、性別和年齡作為自變量,是否存活下來作為因變量,來對整個數(shù)據(jù)集做分析。同時,使用python這一工具來對數(shù)據(jù)進行清理分析,pandas庫的read_csv方法讀取數(shù)據(jù)集文件,得到DataFrame格式的數(shù)據(jù)進行操作,非常便捷。????? ?
數(shù)據(jù)處理
????????根據(jù)觀察,以及用代碼檢測,發(fā)現(xiàn)數(shù)據(jù)集比較規(guī)整,不存在完全重復的數(shù)據(jù)項。此外,年齡是分析中的一個重要維度,但是數(shù)據(jù)集中該信息卻有很多缺失值,因此我將缺失的年齡默認賦值為整個數(shù)據(jù)集年齡的平均值,這樣就做到每一個乘客都有一個年齡值。
# 乘客年齡存在空值,使用整體年齡的平均值代替 titanic_data['Age']=titanic_data['Age'].fillna(titanic_data['Age'].mean())????????年齡空值填充后的數(shù)據(jù)集信息:
????????????
????????可以知道,整個數(shù)據(jù)集有891條數(shù)據(jù),也就是有891名乘客的信息,其中有2名乘客登船港口未知。此外我們只知道204名乘客所在的客艙號,比例不到25%,但是我們不需要從這個維度去分析,因此影響不大。
數(shù)據(jù)分析過程
1.? 選取存活下來的乘客作為分析對象。
# 選取存活下來的乘客數(shù)據(jù) survived_titanic_data = titanic_data[titanic_data['Survived']==1]給出的數(shù)據(jù)集一共有342名乘客活下來占比38.38%。我們從以下幾個維度來分析。
def surviveddata_groupby_feature(feature,list):if feature == 'Sex':_feature='乘客性別'elif feature == 'Pclass':_feature = '客艙等級'# 按feature分組計算乘客人數(shù)print survived_titanic_data.groupby([feature])['PassengerId'].count()survived_titanic_groupby_feature = survived_titanic_data.groupby([feature])['PassengerId'].count() # 將分組得到的人數(shù)組成一個數(shù)組fig = plt.figure(figsize=(10, 5)) # 設(shè)置繪圖區(qū)域大小及子圖 ax_1 = fig.add_subplot(121)survived_titanic_data.groupby([feature])['PassengerId'].count().plot(kind='bar') # 根據(jù)feature分組,計算人數(shù)并繪制柱狀圖for index, feature_num in enumerate(survived_titanic_groupby_feature):ax_1.text(index, feature_num, feature_num, ha='center', va='bottom', rotation=0) # 柱狀圖增加對應(yīng)的數(shù)據(jù)顯示,前面三個參數(shù)分別為橫、縱坐標和數(shù)據(jù)ax_1.set_xticklabels(['male', 'famale'], rotation=0) # 重新命名柱狀圖橫坐標刻度ax_1.set_xlabel(_feature)ax_1.set_ylabel('乘客人數(shù)')ax_1.set_title('按'+_feature+'存活人數(shù)')ax_2 = fig.add_subplot(122)ax_2.set_title('按'+_feature+'乘客存活占比(%)')plt.pie(survived_titanic_groupby_feature, labels=list, autopct='%1.1f%%') # 餅圖plt.show()1)乘客性別
surviveddata_groupby_feature('Sex',['male', 'famale']) # 根據(jù)乘客性別分析存活下來的乘客????????
????????活下來的乘客中男性233名,女性109名。通過餅圖可以直觀看到,存活下來的乘客中男性明顯多于女性乘客。
2)乘客所在客艙等級
surviveddata_groupby_feature('Pclass',['P1','P2','P3']) # 根據(jù)客艙等級分析存活下來的乘客?????
????????活下來的乘客中在最高級船艙的乘客136名,占比大約40%;次等船艙87名,占比約25%,最末等級船艙119名,占比約35%。同樣通過餅圖可以很直觀看到,存活下來的乘客中在最高級船艙所占比例最大。
3)乘客年齡
def surviveddata_groupby_age():survived_titanic_data['Age'].hist(bins=12) # 根據(jù)乘客年齡繪制直方圖plt.xlabel('年齡')plt.ylabel('乘客人數(shù)')plt.title('乘客存活人數(shù)年齡分布')plt.show() surviveddata_groupby_age() # 根據(jù)乘客年齡分析存活下來的乘客????????
????????通過直方圖,可以看到在活下來的乘客當中,青壯年(30歲左右的乘客)占到了絕對比例,相對來講,上了年紀的乘客不多,可能是由于本身歲數(shù)較大的乘客就不多,乘客以中青年為主。
2.? 將全部乘客作為分析對象。
?????同樣按照下面的維度對比分析。
def data_groupby_feature(feature,dic): if feature == 'Sex':_feature='乘客性別'elif feature == 'Pclass':_feature = '客艙等級'titanic_data_feature = titanic_data.groupby([feature, 'Survived'])['PassengerId'].count().unstack()feature_percent = titanic_data_feature.apply(lambda x: x / x.sum() * 100, axis=1) # 計算百分比feature_percent.rename(columns={1: 'yes', 0: 'no'}, index=dic, inplace=True) # 坐標刻度、圖例修改#print titanic_data_feature, feature_percentfeature_percent.plot(kind='bar', stacked=True) # 累計百分比柱狀圖plt.xticks(rotation=0)plt.xlabel(_feature)plt.ylabel('百分比(%)')plt.title(_feature+'存活率對比')plt.show()1)乘客所在客艙等級
data_groupby_feature('Pclass',{1:'P1', 2:'P2', 3:'P3'}) # 根據(jù)客艙等級分析乘客生存情況????????
???????不難發(fā)現(xiàn),通過將整體數(shù)據(jù)進行對比,在P1船艙的乘客明顯活下來的機率大得多,概率超過了60%;而P3船艙的乘客活下來的機率只有大概25%。也印證了上面提出的猜想:身份越高貴,活下來的機會就越大。
2)乘客性別
data_groupby_feature('Sex',{}) # 根據(jù)乘客性別分析乘客生存情況????????
????????同樣,我們會發(fā)現(xiàn),性別也是一個非常有影響因子,女性乘客活下來的概率高達75%+,而男性乘客只有區(qū)區(qū)20%。
3)乘客年齡
# 將年齡分成幾組,計算各組人數(shù)和比例。新增一列,不改變原數(shù)據(jù) bins = [0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90] level = ['0~9', '9~18', '18~27', '27~36', '36~45', '45~54', '54~63', '63~72', '72~81', '81+'] titanic_data['Age_Group'] = pd.cut(titanic_data['Age'], bins=bins, labels=level) def data_groupby_age(): titanic_data_bucket = titanic_data.groupby(['Age_Group', 'Survived'])['PassengerId'].count().unstack().fillna(0)titanic_data_bucket.rename(columns={1:'yes', 0:'no'}, inplace=True)fig = plt.figure(figsize=(10, 5))ax_1 = fig.add_subplot(121)titanic_data_bucket['yes'].plot(kind='bar',alpha=0.5) # 各年齡段乘客存活/未存活數(shù)分布,通過柱狀圖展示titanic_data_bucket['no'].plot(kind='bar',alpha=0.5)ax_1.set_xlabel('年齡')ax_1.set_ylabel('乘客存活數(shù)/總乘客數(shù)')ax_1.set_title('乘客存活人數(shù)年齡分布')plt.xticks(rotation=0)ax_2 = fig.add_subplot(122)titanic_data_bucket[['no_percent','yes_percent']] \= titanic_data_bucket.apply(lambda x: x / x.sum()*100, axis=1)print titanic_data_buckettitanic_data_bucket['yes_percent'].plot(kind='bar', stacked=True) # 各年齡段乘客存活百分比ax_2.set_xlabel('年齡')ax_2.set_ylabel('存活人數(shù)百分比(%)')ax_2.set_title('乘客存活百分比分布')plt.xticks(rotation=0)plt.show() data_groupby_age() # 根據(jù)乘客年齡分析乘客生存情況????????
????????通過左邊累積圖我們可以看到,船上確實是中青年人最多,活下來的人當中也是中青年人占了大多數(shù),很容易就會讓人得出中青年人存活率較高的結(jié)論。但是右邊的存活比率分布卻告訴我們并不是這樣,小孩才是存活率最高的一批人,18歲以下的人活下來的概率超過了50%。此外,72~81歲這個區(qū)間存活概率50%,是因為樣本數(shù)據(jù)中2人當中活了一個,并不具有代表性不多做討論;63~72歲大概10多個人居然一個也沒活下來,很異常的數(shù)據(jù),可能是由于數(shù)據(jù)集的不全,也可能本身就是因為老人抵抗力差,在海水和恐懼中不能堅持太長時間,即使個別人有救生設(shè)備,最終也沒能夠抵御死亡。
????????到這里,我們就比較明晰了,上面兩個維度的分析給了我們很深刻的印象,女人和小孩,對!就是這兩個群體存活下來的機率遠遠高于其他群體,那么,傳言了近一個世紀的言論我們就有理由相信了:在泰坦尼克撞擊冰山快要沉沒時,大多數(shù)船上的人自發(fā)的將救生圈留給了女人和小孩。
4)乘客性別&乘客所在船艙
????????我們同時從乘客的性別和所在船艙,也許更能接近一些真相。
def data_groupby_pclass_and_sex(): titanic_data_sex_and_pclass = titanic_data.groupby(['Sex', 'Survived', 'Pclass'])['PassengerId'].count().unstack('Survived') # 根據(jù)性別和乘客所在船艙等級分組,分析對存活的影響titanic_data_sex_and_pclass.rename(columns={0:'no', 1:'yes'}, inplace=True)titanic_data_sex_and_pclass['yes_percent(%)'] = titanic_data_sex_and_pclass['yes']/\(titanic_data_sex_and_pclass['no']+titanic_data_sex_and_pclass['yes'])*100 # 計算活下來的人占各自群體的百分比print titanic_data_sex_and_pclasstitanic_data.groupby(['Pclass', 'Sex'])['Survived'].mean().unstack().plot(kind='bar')plt.xticks(rotation=0)plt.xlabel('船艙等級')plt.ylabel('比例')plt.title('存活比例對比')plt.show() data_groupby_pclass_and_sex() # 根據(jù)乘客性別和乘客所在船艙等級分析乘客生存情況????????
????
????????不出所料,活下來機會最大的是在高等船艙的女性(超過了90%),而留在大洋深處的就是那些在低等船艙的男性乘客(最高還不到20%)。更印證了身份越高貴越有機會活下來的結(jié)論。
3.? 最后來看下船票票價的情況。
def fare(): print titanic_data['Fare'].describe() # 船票價格描述性統(tǒng)計titanic_data['Fare'].hist(bins=60, normed=True, alpha=0.8)titanic_data['Fare'].plot(kind='kde')plt.show() fare() # 查看船票價格????????????
????
????????根據(jù)第一四分位數(shù),中位數(shù)和平均數(shù)可以看到,絕大部分票價是很低的只有極個別票價很高,最高的價格超過了500。通過直方圖更直觀,除了一少部分,船票價格都在200以下,而絕大多數(shù)沒有超過100。
總結(jié)
????????根據(jù)上面的分析,可以得出:泰坦尼克撞擊冰山即將沉沒時,女人和小孩被安排優(yōu)先使用救生圈,活下來的機會更大;并且,身份地位比較高的人更在意自己的生死,會想盡方法使自己找機會活下來,一般人在這種絕境下更可能犧牲自己,優(yōu)先幫助救助弱小的人。
思考
????????但是,這樣分析有沒有什么問題呢?有,只要是基于不完全的數(shù)據(jù)進行分析都有局限性。本次分析是建立在這891個篩選出來的乘客數(shù)據(jù)基礎(chǔ)上的,只是樣本數(shù)據(jù),而且例如像年齡這樣的還有很多缺失信息,盡管我們用均值代替了空值,終究是有誤差的,假如那幾個年齡缺失值大部分是大于60并且都活了下來,那么我們可能得出另外相反的結(jié)論,即老人的存活率也比較高。因此只有我們得到的數(shù)據(jù)越接近總體數(shù)據(jù),我們得到的結(jié)論才越可靠。從本次分析來看,乘客所在的船艙、年齡以及性別是乘客存活的最大影響因素,那還有那些其他因素會產(chǎn)生一定的影響呢,我們可以再探索一下:1、船上乘客類別,是普通乘客還是船上的工作人員,猜想船上工作人員要組織營救和自救,活下來的概率小一些;2、乘客是否有親人在船上,這應(yīng)該可以通過其中SibSp和Parch兩個字段來挖掘分析,也許在面對困難時,一個家庭或者親人間互相幫扶互相鼓勵,活下來的機會也大;3、乘客所在的樓層,應(yīng)該是樓層越高,自救時間越長,乘客活下來機會越大,這個因素應(yīng)該與船艙等級有相關(guān)性的,從這個維度分析也許會佐證船艙等級對乘客存活率的影響。
????? ? 題外話:在kaggle上面,這其實是一個入門比賽的數(shù)據(jù)集之一,目標是基于機器學習,通過測試數(shù)據(jù)集構(gòu)建特征,預測乘客的生存概率,不再是單純的簡單相關(guān)性分析。所以這里先挖個坑,在之后的學習過程中學習了機器學習相關(guān)知識,一定要回來填坑!
轉(zhuǎn)載于:https://my.oschina.net/nekyo/blog/1545133
總結(jié)
以上是生活随笔為你收集整理的数据分析学习之路——(三)从泰坦尼克号撞击冰山后开始说起的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 爱说分手 吹了9个男朋友
 - 下一篇: 开源 LighterWebGameEng