Advertisement

泰坦尼克号数据_数据分析实战3:泰坦尼克号生存分析

阅读量:
a81800bf4fd32bbf557896da106445f5.png

​ 只要是数据分析师,恐怕没有人不知道泰坦尼克号这个项目吧,这是一个被简历写烂的项目,这也小白学习数据分析和建模最基础的一个项目,本文将从数据分析和数据建模两部分来介绍此项目。

数据来源:

https://www.kaggle.com/c/titanic​www.kaggle.com

数据字段:

ff473d605b7c10c57e979c0848ca024a.png

字段介绍:

  1. PassengerId:乘客编码
  2. Survived:是否幸存
  3. Pclass:船票类型
  4. Name:名字
  5. Sex:性别
  6. Age:年龄
  7. SibSp:船上该成员兄弟姐妹的数量
  8. Parch:船上该成员的父母或子女数量
  9. Ticket:船票编号
  10. Fare:乘客票价
  11. Cabin:客舱号码
  12. Embarked:起航运港

数据分析

影响乘客生还率的因素有很多,为了更好的了解数据,本文将从性别、年龄以及舱位的角度分别来查看对生还率的影响程度

数据导入:

复制代码
 import numpy as np

    
 import pandas as pd
    
 import matplotlib
    
 from matplotlib import pyplot as plt
    
 import seaborn as sns
    
 # 忽略错误
    
 import warnings
    
 warnings.filterwarnings('ignore')
    
  
    
 # 解决图表中中文显示为方格的问题
    
 plt.rcParams['font.sans-serif']=['SimHei']
    
 # 解决图表中负号显示为方格的问题
    
 plt.rcParams['axes.unicode_minus']=False
    
  
    
 # 读取数据
    
 train_data=pd.read_csv('./train.csv')
    
 test_date=pd.read_csv('./test.csv')
    
 # 测试数据集
    
 print(test_date)
    
 # 训练数据集
    
 train_data

1、性别对生还率的影响
f82503d41f0fc3ea20db615a28560b3d.png
d99332a57933cd9145ac8b4404f6e91a.png
7383356a8fd3a4bdc919f51181e87487.png

结论:
全部乘客中,只有35.24%的女性,而生还的乘客中,女性占到了68.13% 。女性的生还率达到了74.2%,而男性的生还率只有18.9% 。我们可以看出,女性的生还率更高。

代码展示:

复制代码
 # 性别对生还率的影响

    
  
    
 train_data_sex=train_data.Sex.value_counts()
    
 train_data_sex
    
 # 绘制饼图展示
    
 train_data_sex.plot(kind='pie',title='全体乘客的性别比例图',
    
                 autopct='%.2f%%',figsize=(4,4))
    
  
    
 # 绘制生还乘客的性别比例图
    
 train_data_survived=train_data[train_data['Survived']==1]
    
 train_data_survived_sex=train_data_survived.groupby(['Sex']).Sex.count()
    
 train_data_survived_sex
    
 plt.figure(figsize=(4,4))
    
 plt.pie(train_data_survived_sex,labels=['female','male'],autopct='%.2f%%')
    
 plt.title('生还乘客的性别比例图')
    
  
    
 # 绘制不同性别的生还率
    
 # 使用的是sns.barplot()显示的是某种分类变量分布的平均值
    
 sns.barplot(x='Sex',y='Survived',data=train_data)
    
 plt.title('不同性别的生还率')

2、年龄对生还率的影响
8510524ebd5472f57ba98e214250c68d.png

结论
0-10岁生还率最高,其次30-40岁。

代码展示:

复制代码
 # 按照年龄进行均匀分组,按10岁一组进行划分

    
 bins=np.arange(0,90,10)
    
 # 添加年龄区间列
    
 train_data['Age_band']=pd.cut(train_data.Age,bins)
    
 train_data['Age_band']
    
 sns.barplot(x='Age_band',y='Survived',data=train_data)

3、舱位对生还率的影响
670d3b6cc8d7716ab38ff9af07ef9304.png

结论:
"1"等级的生还率>“2”等级>"3"等级 ; "1"等级的生还率最高

代码展示:

复制代码
 # 舱位对生还率的影响

    
 fig,[ax1,ax2,ax3]=plt.subplots(1,3,figsize=(15,4))
    
  
    
 # 绘制全体乘客的舱位比例图
    
 train_data_pclass=train_data.groupby(['Pclass']).Pclass.count()
    
 train_data_pclass
    
 train_data_pclass.plot(kind='pie',autopct='%.2f%%',title='全体乘客的舱位比例图',ax=ax1)
    
  
    
 # 绘制生还乘客的舱位比例图
    
 train_data_survived_pclass=train_data[train_data['Survived']==1].groupby(['Pclass']).Pclass.count()
    
 train_data_survived_pclass
    
 train_data_survived_pclass.plot(kind='pie',autopct='%.2f%%',title='生还乘客的舱位比例图',ax=ax2)
    
  
    
 # 绘制不同舱位的生还率
    
 sns.barplot(x='Pclass',y='Survived',data=train_data,ax=ax3)
    
 plt.title('不同舱位的生还率')
    
 plt.xlabel('舱位')
    
 plt.ylabel('生还率')

4、年龄和性别共同对生还率的影响
34b0063f3afc0385d4e9d91e47f3d52b.png

结论: 从图中看出:年龄段在50-60岁之间人数最多,但这个年龄段的生还率不是最高的,而年龄较小(0~10岁)之间的生还率是最高的。

男性的人数明显多于女性,但女性的生还率明显高于男性,且女性的生还率都在40%以上。

综上可以看出,性别对生还率的影响大于年龄的影响

代码展示:

复制代码
 # 年龄和性别与生还率的关系

    
 fig,[ax1,ax2,ax3]=plt.subplots(1,3,figsize=(18,4))
    
  
    
 # 绘制全体乘客性别及年龄分布图
    
 # 构建数据透视表
    
 train_data_tsb1=train_data.pivot_table(values='Survived',index='Age_band',columns='Sex',aggfunc='count').sort_index()
    
 train_data_tsb1
    
 train_data_tsb1.plot.bar(ax=ax1,title='全体乘客的性别及年龄分布图')
    
  
    
  
    
 # 绘制生还乘客的性别及年龄分布图
    
 train_data_tsb2=train_data[train_data['Survived']==1].pivot_table(values='Survived',index='Age_band',columns='Sex',aggfunc='count').sort_index()
    
 train_data_tsb2
    
 train_data_tsb2.plot.bar(ax=ax2,title='生还乘客的性别及年龄分布图')
    
  
    
 # 绘制性别和年龄的生还率分布图
    
 sns.barplot(data=train_data,x='Age_band',y='Survived',hue='Sex',ci=None)
    
 plt.axhline(y=0.4,color='r',ls='--')
    
 plt.title('性别和年龄的生还分布图')

5、年龄和舱位共同对生还率的影响
63a8b5ccdf88e777c4f3adaaf85ca500.png

结论: 从图中看出:3舱的人数最多,但3舱的生还率最小。而在0-50岁的年龄区间,1、2舱舱的生还率都大于40%。

同一个年龄段,除了0-10岁和60-70岁区间外,1舱的生还率最高。

不同年龄段,也是生还率1舱>2舱>3舱。

代码展示:

复制代码
 # 年龄和舱位共同对生还率的影响

    
 fig,[ax1,ax2,ax3]=plt.subplots(1,3,figsize=(18,4))
    
  
    
 # 绘制全体乘客中年龄和舱位的分布图
    
 train_data_tsb3=train_data.pivot_table(values='Survived',index='Age_band',columns='Pclass',aggfunc='count').sort_index()
    
 train_data_tsb3
    
 train_data_tsb3.plot.bar(ax=ax1,title='全体乘客的舱位及年龄分布图')
    
  
    
 # 绘制生还乘客中年龄和舱位的分布图
    
 train_data_tsb4=train_data[train_data['Survived']==1].pivot_table(values='Survived',index='Age_band',columns='Pclass',aggfunc='count').sort_index()
    
 train_data_tsb4
    
 train_data_tsb4.plot.bar(ax=ax2,title='全体乘客的舱位及年龄分布图')
    
  
    
 # 绘制年龄和舱位的生还分布图
    
 sns.barplot(data=train_data,x='Age_band',y='Survived',hue='Pclass',ci=None)
    
 plt.axhline(y=0.4,color='r',ls='--')
    
 plt.title('舱位和年龄的生还分布图')

6、性别和舱位共同对生还率的影响
1d7794efb9353815ddba23fbd1ba31f6.png

结论:

从全体乘客图中可以看出,1号舱与2号舱的人数差不多,且都小于3号舱人数,且3个船舱中男性人数均多于女性人数。

从生还人数中来看,女性生还人数高于男性生还人数,且1号舱的生还人数高于2、3号舱生还人数。

从生还率来看,1、2号舱女性生还率最高,达到90%,3号舱女性生还率大约为50%。男性的生还率普遍低于40%,但男性1号舱的生还率高于男性2号、3号生还率。

所以,性别和舱位均对生还率产生影响代码展示:

复制代码
 # 性别和舱位生还图

    
 fig,[ax1,ax2,ax3]=plt.subplots(1,3,figsize=(18,4))
    
  
    
 # 绘制全体乘客中性别与舱位的分布图
    
 train_data_tsb5=train_data.pivot_table(values='Survived',index='Pclass',columns='Sex',aggfunc='count')
    
 train_data_tsb5
    
 train_data_tsb5.plot.bar(ax=ax1,title='全体乘客性别与舱位分布图')
    
  
    
 # 绘制生还乘客中性别与舱位的分布图
    
 train_data_tsb6=train_data[train_data['Survived']==1].pivot_table(values='Survived',index='Pclass',columns='Sex',aggfunc='count')
    
 train_data_tsb6
    
 train_data_tsb6.plot.bar(ax=ax2,title='全体乘客性别与舱位分布图')
    
  
    
 #  绘制性别和舱位的生还分布图
    
 sns.barplot(data=train_data,x='Pclass',y='Survived',hue='Sex',ax=ax3)
    
 plt.axhline(y=0.4,color='r',ls='--')
    
 plt.title('舱位和年龄的生还分布图')

7、年龄、性别、舱位共同对生还率的影响
1cf33ae7f662b54aad05dddcd9668bfb.png

代码展示:

复制代码
 # 年龄、性别、舱位与生还率关系

    
 fig,[ax1,ax2]=plt.subplots(1,2,figsize=(12,4))
    
  
    
 # 全体乘客中年龄,性别,舱位人数分布
    
 train_data_tsb7=train_data.pivot_table(values='Survived',index=['Age_band','Pclass'],columns='Sex',aggfunc='count').sort_index()
    
 train_data_tsb7
    
 train_data_tsb7.plot.bar(ax=ax1,title='全体乘客中年龄、性别、舱位的人群分布',fontsize=10)
    
  
    
 # 生还乘客中年龄,性别,舱位人数分布
    
 train_data_tsb8=train_data[train_data['Survived']==1].pivot_table(values='Survived',index=['Age_band','Pclass'],columns='Sex',aggfunc='count').sort_index()
    
 train_data_tsb8
    
 train_data_tsb8.plot.bar(ax=ax2,title='生还乘客中年龄、性别、舱位的人群分布',fontsize=10)

数据建模

1、查看数据信息

复制代码
    train_data.info()
c0664041a81716b6877ca5e15ebc50cc.png

可以查看到有些字段缺少信息,需要对缺失值进行处理,对于缺失值的处理有以下几种解决的方法。(1)直接删除

(2)如果是数值类型,使用平均值取代(3)如果是分类数据,使用最常见的类别取代(4)还可以使用模型来预测缺失值,例如KNN

2、数据清洗

复制代码
 # 年龄的处理

    
 train_data['Age']=train_data['Age'].fillna(train_data['Age'].mean())
    
 # 登陆港口的处理
    
 train_data['Embarked']=train_data['Embarked'].fillna('S')
    
 # 船舱号的处理
    
 train_data['Cabin']=train_data['Cabin'].fillna('None')
    
 train_data.info()

3、数据预处理

将数据进行数值化处理

复制代码
 # 1、性别处理

    
 train_data['Sex']=train_data['Sex'].map({'male':1,'female':0})
    
 train_data.head()
    
  
    
 # 2、港口处理
    
 # 存放提取后的特征
    
 D=pd.DataFrame()
    
 # 使用get_dummies进行one-hot编码,产生虚拟变量
    
 D=pd.get_dummies(train_data['Embarked'],prefix='Embarked')
    
 # 添加one-hot编码产生的虚拟变量到原始数据中
    
 train_data=pd.concat([train_data,D],axis=1)
    
 train_data.drop('Embarked',axis=1,inplace=True)
    
 train_data.head()
    
  
    
 # 3、客舱等级
    
 D1=pd.DataFrame()
    
 D1=pd.get_dummies(train_data['Pclass'],prefix='Pclass')
    
 D1.head()
    
 # 添加数据
    
 train_data=pd.concat([train_data,D1],axis=1)
    
 train_data.drop('Pclass',axis=1,inplace=True)
    
 train_data.head()
    
  
    
 # 4、乘客姓名处理
    
 def gettitle(name):
    
     str1=name.split(',')[1]
    
     str2=str1.split('.')[0]
    
     # strip()方法用于移除字符串头尾指定的字符
    
     str3=str2.strip()
    
 return str3
    
 D2=pd.DataFrame()
    
 D2['title']=train_data['Name'].map(gettitle)
    
 #姓名中头衔字符串与定义头衔类别的映射关系
    
 title_mapDict = {
    
 "Capt":       "Officer",
    
 "Col":        "Officer",
    
 "Major":      "Officer",
    
 "Jonkheer":   "Royalty",
    
 "Don":        "Royalty",
    
 "Sir" :       "Royalty",
    
 "Dr":         "Officer",
    
 "Rev":        "Officer",
    
 "the Countess":"Royalty",
    
 "Dona":       "Royalty",
    
 "Mme":        "Mrs",
    
 "Mlle":       "Miss",
    
 "Ms":         "Mrs",
    
 "Mr" :        "Mr",
    
 "Mrs" :       "Mrs",
    
 "Miss" :      "Miss",
    
 "Master" :    "Master",
    
 "Lady" :      "Royalty"
    
                 }
    
 D2['title']=D2['title'].map(title_mapDict)
    
  
    
 # 使用get_dummies进行one-hot编码
    
 D2=pd.get_dummies(D2['title'])
    
 train_data=pd.concat([train_data,D2],axis=1)
    
 # 删掉姓名这一列
    
 train_data.drop('Name',axis=1,inplace=True)
    
 train_data.head()
    
  
    
 # 5、船舱号的处理
    
 D3=pd.DataFrame()
    
 train_data['Cabin']=train_data['Cabin'].map(lambda c:c[0])
    
  
    
 D3=pd.get_dummies(train_data['Cabin'],prefix='Cabin')
    
 train_data=pd.concat([train_data,D3],axis=1)
    
 train_data.drop('Cabin',axis=1,inplace=True)
    
 train_data.head()
    
  
    
 # 家庭信息的处理
    
 D4=pd.DataFrame()
    
 # 家庭人数=同代直系亲属数+不同代直系亲属数+1(自己)
    
 D4['family']=train_data['Parch']+train_data['SibSp']+1
    
 D4['family_single']=D4['family'].apply(lambda x:1 if x==1 else 0)
    
 D4['family_small']=D4['family'].apply(lambda x:1 if 2<=x<=4 else 0)
    
 D4['family_large']=D4['family'].apply(lambda x:1 if x>=5 else 0)
    
  
    
 train_data=pd.concat([train_data,D4],axis=1)
    
 train_data.head()
    
 train_data.shape

4、特征工程

复制代码
 # 特征选择

    
 corrDf=train_data.corr()
    
 corrDf
250077c934b1368dc3241436044e2742.png
复制代码
 # 图形展示

    
 plt.figure(figsize=(40,40))
    
 train_data_cor=train_data.corr()
    
 sns.heatmap(train_data_cor,annot=True,square=True,cmap='Greens')
7c81f5c7e21f0a14743aec532c5ea3e8.png
复制代码
 # 特征选择

    
 train_data_X=pd.concat([
    
     D,
    
     D1,
    
     D2,
    
     D3,
    
     D4,
    
     train_data['Fare'],
    
     train_data['Sex']
    
 ],axis=1)
    
 train_data_X.head()

5、构建模型

复制代码
 from sklearn.model_selection import train_test_split

    
 from sklearn.linear_model import LogisticRegression
    
  
    
 # 原始数据集有891行
    
 sourcerow=891
    
 # 原始数据集:特征
    
 source_x=train_data_X.loc[0:sourcerow-1,:]
    
 # 原始数据集:标签
    
 source_y=train_data.loc[0:sourcerow-1,'Survived']
    
 # 建立模型用的训练数据集和测试数据集
    
 train_x, test_x, train_y, test_y = train_test_split(source_x,source_y,train_size=.8)
    
 print('原始数据集特征:',source_x.shape,'训练数据集特征:',train_x.shape,'测试数据集特征:',test_x.shape)
    
  
    
 # 创建模型
    
 model=LogisticRegression()
    
 # 训练模型
    
 model.fit( train_x , train_y )
    
 LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
    
       intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
    
       penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
    
       verbose=0, warm_start=False)

6、模型评估

复制代码
 # 评估模型

    
 model.score(test_x,test_y)
a927db256c51b63e3a23c188982c7893.png

随着大数据的时代的到来,数据变得越来越重要,数据可以帮助我们来看清行业的本质,也可以帮助我们更加快速的了解一个行业,关注公众号——DT学说,走进数据的时代
d5edc854340659fa5e424d5ff776ad52.png

全部评论 (0)

还没有任何评论哟~