Kaggle獲得了一份泰坦尼克號乘客的數(shù)據(jù)分析哪些因素會讓乘客的生還率更高
影響乘客生還的因素很多卒煞,這里只對乘客的性別狸驳、年齡藕咏、乘客等級再层、這三個因素感興趣贸铜,
看看這四個因素是否會影響乘客的生還率。
- 1.性別是否會影響生還率
- 2.年齡是否會影響生還率
- 3.乘客等級會否會影響生還率
- 4.性別和乘客等級共同對生還率的影響
- 5.性別和年紀共同對生還率的影響
- 6.年紀和等級共同對生還率的影響
這里乘客的性別聂受、年齡蒿秦、等級、是三個自變量蛋济,生還率是因變量
數(shù)據(jù)加工
導入包
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
from __future__ import division
from scipy import stats
import seaborn as sns
###首先導入各種模塊
###讓圖片在ipython notebook上直接顯示
%matplotlib inline
加載數(shù)據(jù)
/Users/zhongyaode/anaconda/envs/py/lib/python2.7/site-packages/IPython/html.py:14: ShimWarning: The `IPython.html` package has been deprecated since IPython 4.0. You should import from `notebook` instead. `IPython.html.widgets` has moved to `ipywidgets`.
"`IPython.html.widgets` has moved to `ipywidgets`.", ShimWarning)
path='/Users/zhongyaode/Desktop/udacity—data/'
df1=pd.read_csv(path+'titanic-data.csv')
熟悉數(shù)據(jù)
先看看數(shù)據(jù)里有哪些信息棍鳖,這些信息是怎樣的格式
- PassengerId:乘客ID
- Survived:是否獲救,用1和Rescued表示獲救,用0或者not saved表示沒有獲救
- Pclass:乘客等級瘫俊,“1”表示Upper鹊杖,“2”表示Middle,“3”表示Lower
- Name:乘客姓名
- Sex:性別
- Age:年齡
- SibSp:乘客在船上的配偶數(shù)量或兄弟姐妹數(shù)量)
- Parch:乘客在船上的父母或子女數(shù)量
- Ticket:船票信息
- Fare:票價
Cabin:是否住在獨立的房間扛芽,“1”表示是骂蓖,“0”為否
embarked:表示乘客上船的碼頭距離泰坦尼克出發(fā)碼頭的距離,數(shù)值越大表示距離越遠
查看前五行數(shù)據(jù)川尖。了解數(shù)據(jù)包含的信息登下,
df1.head()
查看各字段的數(shù)據(jù)類型
df1.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId 891 non-null int64
Survived 891 non-null int64
Pclass 891 non-null int64
Name 891 non-null object
Sex 891 non-null object
Age 714 non-null float64
SibSp 891 non-null int64
Parch 891 non-null int64
Ticket 891 non-null object
Fare 891 non-null float64
Cabin 204 non-null object
Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.6+ KB
查看數(shù)據(jù)的摘要信息
df1.describe()
從數(shù)據(jù)摘要中可以看出。乘客的生還率大約在38%叮喳,超越50的乘客在3等級被芳,乘客的平均年齡在30歲左右,普遍比較年輕
數(shù)據(jù)清洗
Embarked有兩個缺失值馍悟,這里用眾數(shù)'S'填充畔濒,因為這里缺失的值相比而言非常的少,
所以對分析結(jié)果產(chǎn)生不了多大的影響
df1['Embarked']=df1['Embarked'].fillna('S')
處理Age的缺失值锣咒,Age是連續(xù)數(shù)據(jù)侵状,這里用平均值填充缺失值
這里用平均值填充赞弥,這會造成縮小年齡之間的差異性
age_mean=df1['Age'].mean()
df1['Age']=df1['Age'].fillna(age_mean)
Cabin 值有缺失值,不需要Cabin列刪除掉
df=df1.copy()
del df['Cabin']
- 數(shù)據(jù)探索
獲取生還乘客的數(shù)據(jù)
survives_passenger_df=df[df['Survived']==1]
定義幾個常用的方法
按照name對乘客進行分組趣兄,計算每組的人數(shù)
def group_passenger_count(data,name):
#按照xx對乘客進行分組后 绽左,每個組的人數(shù)
return data.groupby(name)['PassengerId'].count()
計算每個組的生還率
def group_passenger_survived_rate(xx):
#按xx對乘客進行分組后每個組的人數(shù)
group_all=group_passenger_count(df,xx)
對乘客進行分組后每個組生還者的人數(shù)
group_survived_value=group_passenger_count(survives_passenger_df,xx)
對乘客進行分組后,每組生還者的概率
return group_survived_value/group_all
輸出餅圖
def print_pie(group_data,title):
group_data.plot.pie(title=title,figsize=(6,6),autopct='%.2f%%'\
,startangle=90,legend=True)
輸出柱狀圖顯示百分比
def print_bar(data,title):
bar=data.plot.bar(title=title)
for p in bar.patches:
bar.annotate('%.1f%%'%(p.get_height()*100),(p.get_x()*1.005\
,p.get_height()*1.005))
輸出柱狀圖顯示總計
def print_bar_count(data,title):
bar=data.plot.bar(title=title)
for p in bar.patches:
bar.annotate('%.f'%(p.get_height()), (p.get_x()*1.005\
,p.get_height()*1.005))
性別對生還率的影響
# #不同性別對生還率的影響
# df_sex1=df['Sex'][df['Survived']==1]
# df_sex0=df['Sex'][df['Survived']==0]
# plt.hist([df_sex1,df_sex0],
# stacked=True,
# label=['Rescued','not saved'])
# plt.xticks([-1,0,1,2],[-1,'F','M',2])
# plt.legend()
# plt.title('Sex_Survived')
by_Survived=df.groupby('Sex')['Sex'].count()
by_Survived
Sex
female 314
male 577
Name: Sex, dtype: int64
#全體乘客的性別比例圖
by_Sex=df.groupby('Sex')['Sex'].count()
plt.pie(by_Sex,labels=['femal','male'],autopct='%.2f%%')
([<matplotlib.patches.Wedge at 0x10d786f50>,
<matplotlib.patches.Wedge at 0x10d798e10>],
[<matplotlib.text.Text at 0x10d7985d0>,
<matplotlib.text.Text at 0x10d798710>],
[<matplotlib.text.Text at 0x10d7989d0>,
<matplotlib.text.Text at 0x10d7a77d0>])
生還乘客的性別比例圖
by_Survived_Sex=df[df['Survived']==1]
by_Survived_sex_rate=by_Survived_Sex.groupby('Sex')['Sex'].count()
plt.pie(by_Survived_sex_rate,labels=['femal','male'],autopct='%.2f%%')
看出全體乘客中男性占了大部分艇潭,但是生還乘客中女性占了大部分拼窥;
- 得出結(jié)論:女性的生還概率比男性的更高
驗證女性在顯著性在0.05的情況下 生還率是否是在存在顯著性
顯示Series的方法查看生還比例
df.groupby('Sex')['Survived'].mean()
Sex
female 0.742038
male 0.188908
Name: Survived, dtype: float64
可視化不同性別的生還率
print_bar(df.groupby('Sex')['Survived'].mean(),'Sex_survived')
#這是直接顯示柱狀圖的方法
#df.groupby('Sex')['Survived'].mean().plot(kind='bar')
- 可知女性的生還概率p_female=74%
#由于全體乘客的生還率為0.3838,所以認為女性的生還概率為p=0.3838,這里N等于女性總數(shù)
#標準差:SD=sqrt(p*(1-p)/N)
import math
p=0.3838
sd=math.sqrt(p*(1-p)/891)
print 'sd:',sd
sd: 0.0162920029545
取置信區(qū)間為95%的誤差范圍
m=sd*1.96
m=df.1.96
取顯著性為0.05
#阿爾法為95%蹋凝,查T表得的t臨界值為1.96
#m=sd*1.96
m=sd*1.96
print 'm:',m
m: 0.0319323257908
#女性的置信區(qū)間的95%的誤差范圍是ci
ci=(p-m,p+m)
print 'ci',ci
ci (0.3518676742091846, 0.41573232579081537)
p_female超出了ci的范圍鲁纠,所以我們可以說,女性的生還率有顯著性
- 得出結(jié)論:性別對生還率有影響
年齡對生還率的影響
乘客年齡分布和生還乘客年齡的分布
df_sex1=df['Age'][df['Survived']==1]
df_sex0=df['Age'][df['Survived']==0]
plt.hist([df_sex1,df_sex0],
stacked=True,
label=['Rescued','not saved'])
#plt.xticks([1,2,3],['Upper','Middle','lower'])
plt.legend()
plt.title('title')
plt.title('Age_Survived')
<matplotlib.text.Text at 0x110094990>
定義函數(shù)
def describe_value(data,label):
print '全體乘客的:'+label
print '最大值:' ,df[data].max()
print '最小值:',df[data].min()
print '平均值:',df[data].mean()
print ' '
print '生還乘客的:'+label
print '最大值:' ,survives_passenger_df[data].max()
print '最小值:' ,survives_passenger_df[data]. min()
print '平均值:' ,survives_passenger_df[data].mean()
describe_value('Age','年紀')
全體乘客的:年紀
最大值: 80.0
最小值: 0.42
平均值: 29.6991176471
生還乘客的:年紀
最大值: 80.0
最小值: 0.42
平均值: 28.5497781218
可以看出兩者的你年齡均值非常接近
從直方圖中看鳍寂,兩者的分布也非常接近
兩者中間都有一個柱子凸起房交,是因為年齡的缺失值是用均值填充的
#對年齡進行均勻分組,按照10歲一組進行劃分
bins=np.arange(0,90,10)
df['Age_group']=pd.cut(df['Age'],bins)
#每個年齡段里面伐割,男、女的人數(shù)
by_age_count=df.groupby(['Age_group','Survived'])['Survived'].count()
#每個年齡段的生還率
by_age_rate=df.groupby('Age_group')['Survived'].mean()
ci
(0.3518676742091846, 0.41573232579081537)
by_age_rate.plot.bar(title='Survived rate by age')
plt.ylabel('Survival rate')
plt.axhline(y=0.415,color='r',linestyle='--')
plt.axhline(y=0.351,color='g',linestyle='--')
<matplotlib.lines.Line2D at 0x1102eda10>
這里可以看出有幾個年齡段對是生還率有明顯的影響如0-10歲和30-40歲
#可視化每個年齡段里面的男刃唤、女人數(shù)
by_age_count.unstack().plot(kind='bar',stacked=True)
plt.title('Survived count by age')
plt.ylabel('Survived count')
plt.axhline(y=0.351,color='g',linestyle='--')
<matplotlib.lines.Line2D at 0x1103dded0>
每個年齡段的總?cè)藬?shù)
print_bar_count(df.groupby(['Age_group'])['Survived'].count(),'Age_count')
plt.axhline(y=15,color='r',linestyle='--')
按年齡分組求每組的生還概率
print_bar(df.groupby('Age_group')['Survived'].mean(),'Age_group')
plt.axhline(y=0.415,color='r',linestyle='--')
plt.axhline(y=0.351,color='g',linestyle='--')
<matplotlib.lines.Line2D at 0x111a5bfd0>
ci =(0.3518676742091846, 0.41573232579081537)
生還概率在次ci范圍內(nèi)說明在顯著性在0.05的情況下沒有顯著性
可以看出10-20隔心、40-50,50-60歲沒有顯著性尚胞,再 由于70-80歲的人數(shù)只有5個硬霍,可以認為沒有統(tǒng)計意義
可以看出,在0-10和30-40歲年齡段的生還率高于平均水平笼裳,而20-30和60-70歲年齡段的生還率率低于平均水平
得出結(jié)論:0-10歲和30-40歲的生還率高于平均值唯卖,20-30歲和60-70歲的生還率低于平均值
0-10歲的生還率最高,用均值填充缺失的年齡值可能造成躬柬,年齡差異的縮小
探索乘客船票等級是否會影響生還率
乘客等級分布
print_bar_count(df.groupby(['Pclass'])['Survived'].count(),'Pclass_count')
輸出所有乘客等級比例圖
print_pie(group_passenger_count(df,'Pclass'),'All Passenger Pclass')
- 可以看出三等級的人數(shù)占了總體人數(shù)的一半多
生還乘客的船票登記分布
#survives_passenger_df.groupby('Pclass')['Survived'].count().plot(kind='bar')
#by_age_count.unstack().plot(kind='bar',stacked='Ttue')
#b=survives_passenger_df.groupby('Pclass')['Survived'].count()
#plt.xticks([0,1,2],['Upper_rate','Middle_rate','lower_rate'])
#plt.legend()
print_bar_count(survives_passenger_df.groupby('Pclass')['Survived'].count(),'rate_Pclass')
#輸出生還乘客的等級比例圖
print_pie(group_passenger_count(survives_passenger_df,'Pclass'),'All Passenger Pclass')
全體乘客中三等級人數(shù)占了一半多拜轨,但是生還乘客中,三等級的比例還有沒有1等級的多
- 得出結(jié)論:等級對生還率有較大影響
這里數(shù)據(jù)是離散數(shù)據(jù)允青,不能用直方圖橄碾,應(yīng)該使用條形圖,kind=bar,
不同等級對生還率的影響
df_sex1=df['Pclass'][df['Survived']==1]
df_sex0=df['Pclass'][df['Survived']==0]
plt.hist([df_sex1,df_sex0],
stacked=True,
label=['Rescued','not saved'])
plt.xticks([1,2,3],['Upper','Middle','lower'])
plt.legend()
plt.title('Pclass_Survived'
等級對生還率的影響
df.groupby(['Pclass','Survived'])['Survived'].count().unstack().plot(kind='bar',stacked=True)
plt.axhline(y=15,color='r',linestyle='--')
<matplotlib.lines.Line2D at 0x110ae0d50>
各等級的生還率
print_bar(group_passenger_survived_rate(df['Pclass']),'Pclass_Survived')
plt.axhline(y=0.415,color='r',linestyle='--')
plt.axhline(y=0.351,color='g',linestyle='--')
<matplotlib.lines.Line2D at 0x110ecbf10>
可以看出1等級的生還率明顯大于2颠锉、3等級法牲,
結(jié)論:"1"等級的生還率>“2”等級>"3"等級
"1"等級的生還率最高
性別和乘客等級共同對生還率的影響
#按性別和等級分組計算人數(shù)
print_bar_count(df.groupby(['Pclass','Sex'])['Survived'].count().unstack(),'dd')
#按性別和等級分組計算人數(shù)
print_bar_count(df.groupby(['Sex','Pclass'])['Survived'].count(),'Sex_Pclass_count')
#df.groupby(['Sex','Pclass'])['Survived'].count().plot(kind='bar')
按性別和等級分組計算生還率
print_bar(group_passenger_survived_rate(['Pclass','Sex']).unstack(),'Sex_Pclass_Survived')
plt.ylabel('rate_probability')
plt.axhline(y=0.415,color='r',linestyle='--')
plt.axhline(y=0.351,color='g',linestyle='--')
<matplotlib.lines.Line2D at 0x1113322d0>
可以看出性別對生還率的影響>等級的影響,各組的人數(shù)都大于50人具有統(tǒng)計意義
- 得出結(jié)論:性別對生還率的影響大于等級的影響
性別和年紀共同對生還率的影響
#性別和年紀分組統(tǒng)計人數(shù)
print_bar_count(df.groupby(['Age_group','Sex'])['Survived'].count().unstack(),'Sex_Age_count')
plt.axhline(y=15,color='r',linestyle='--')
<matplotlib.lines.Line2D at 0x1109aa4d0>
按性別和年齡分組琼掠,顯示生還率
Sex_Age_rate=df.groupby(['Age_group','Sex'])['Survived'].mean()
print_bar(Sex_Age_rate.unstack(),'fd')
plt.axhline(y=0.415,color='r',linestyle='--')
plt.axhline(y=0.351,color='g',linestyle='--')
Sex_Age_ra=df.groupby(['Age_group','Sex'])['Survived'].count()
print_bar(Sex_Age_ra.unstack(),'fd')
plt.axhline(y=15,color='r',linestyle='--')
<matplotlib.lines.Line2D at 0x110861750>
這里人數(shù)不足15的組統(tǒng)計量太少認為沒有統(tǒng)計意義拒垃,所以,female-(50,60),female-(60,70)
和male-(60,70),male-(70,80)沒有統(tǒng)計意義,
顯著性為0.05瓷蛙,生還概率不在ci范圍內(nèi)的才有具有顯著性
- 結(jié)論:
1.性別的影響比年齡的影響大(這里可能跟年齡缺失值是用平均值年齡填充的有關(guān))
2.生還率大于均值的有:0-40歲的女性和0-10歲的男性
3.生還率小于均值的有:10-60歲的男性
探索年紀和等級共同對生還率的影響
#按年紀和等級分組求各組人數(shù)
print_bar_count(df.groupby(['Age_group','Pclass'])['Survived'].count().unstack(),'Age_Pclass_count')
# 畫一條y=15的紅色虛線
plt.axhline(y=15,color='r',linestyle='--')
<matplotlib.lines.Line2D at 0x110d05c10>
這里顯著性為0.05求是否有顯著性
認為人數(shù)不足15的不具有統(tǒng)計意義
沒有統(tǒng)計意義的有:(1,[0,10]),(1,[60,80]),(2,[50,70]),(3,[50,80])
ci
(0.3518676742091846, 0.41573232579081537)
#按年紀和等級分組求各組生還率
print_bar(df.groupby(['Age_group','Pclass'])['Survived'].mean().unstack(),'Age_Pclass_mean')
#顯示各組具有顯著性的紅線
plt.axhline(y=0.415,color='r',linestyle='--')
plt.axhline(y=0.351,color='g',linestyle='--')
<matplotlib.lines.Line2D at 0x111176dd0>
可以看出等級的影響比年紀的影響大悼瓮,可能造成的原因是用年齡的均值填充的缺失值
結(jié)論:等級的影響比年紀的大
#過濾人數(shù)不足15的組
age_Pclass=df.groupby(['Age_group','Pclass'])[['Survived']].count()
Age_Pclass=age_Pclass.loc[age_Pclass['Survived']>15]
#求過濾后的每組人數(shù)
print_bar_count(Age_Pclass.unstack(),'Age_Pclass')
ci ,#沒有統(tǒng)計意義的有:(1,[0,10]),(1,[60,80]),(2,[50,70]),(3,[50,80])
((0.3518676742091846, 0.41573232579081537),)
#按年齡和等級分組生還率在0.415以上組
#顯著性為0.05戈毒,生還率在0.415以上的具有顯著性
Pclass_Age_group_rate=df.groupby(['Age_group','Pclass'])[['Survived']].mean()
bar_Pclass_Age_group=Pclass_Age_group_rate.loc[Pclass_Age_group_rate['Survived']>0.415]
print_bar(bar_Pclass_Age_group.unstack(),'rate_Age_group_Pclass')
#顯示顯著性為0.05的置信區(qū)間
plt.axhline(y=0.415,color='r',linestyle='--')
plt.axhline(y=0.351,color='r',linestyle='--')
<matplotlib.lines.Line2D at 0x1117be0d0>
在具有統(tǒng)計意義并顯著性為0.05的情況下
上圖中除了(1,[0,10]),(1,[60,70])外
生還率都高于均值且具有顯著性
#按年齡和等級分組求生還率在0.415以下的組
Pclass_Age_group_rate=df.groupby(['Age_group','Pclass'])[['Survived']].mean()
bar_Pclass_Age_group=Pclass_Age_group_rate.loc[Pclass_Age_group_rate['Survived']<0.351]
print_bar(bar_Pclass_Age_group.unstack(),'rate_Age_group_Pclass')
在具有統(tǒng)計意義并顯著性為0.05的情況下
上圖中除了(1,[60,80])谤牡,(2,[60,70])副硅,3,[50,80])外
生還率都低于平均值且具有顯著性
#最后兩個圖怎么只顯示具有統(tǒng)計意義,還有組數(shù)15才具有統(tǒng)計以及是我拍腦袋得出來的翅萤,
#根據(jù)38.38%的概率怎么來計算最小具有統(tǒng)計意義的數(shù)
#
# vvvv=df.groupby('Sex')['Sex'].count()
# plt.pie(vvvv,labels=['sf','df'],autopct='%.2f%%')這里性別的賓餅圖能出來
# vvvv=df.groupby('Sex')['Sex'].count()
# plt.pie(vvvv,labels=['sf','df'],autopct='%.2f%%')為什么這里的等級餅圖出不來
結(jié)論
通過分析恐疲,可以看出對生還率影響最大的因素是乘客性別,其次是等級套么,最后年齡段也對生還率有影響
分析的局限性
- 這里并沒有從統(tǒng)計上分析得出這些結(jié)果的偶然性培己,所以并不知道這里的結(jié)果是真正的差異造成的還是噪音造成的
- 年齡字段有一些缺失值,因為是連續(xù)數(shù)據(jù)這里用的是全體乘客年齡的均值填充缺失值胚泌,這樣會縮小年齡之間的差異省咨,也會影響分析結(jié)果
可能影響生還率的其他因素
- 還有一些因素可能會影響生還率谎僻,不如乘客的職業(yè)鸣剪、身體素質(zhì)、求生意志等大刊,但是數(shù)據(jù)中并沒有個給出
結(jié)果的相關(guān)性
- 這里的數(shù)據(jù)并非通過試驗得出穷缤,所以無法說自變量之間的因果性敌蜂,只能說她們之間有相關(guān)性
參考文章![Microsoft Dynamics AX 技術(shù)博
]http://www.cnblogs.com/msdynax/p/6099814.html