美文网首页解密大数据
用python对泰坦尼克数据进行分析 | 一步一步跟我学Pyth

用python对泰坦尼克数据进行分析 | 一步一步跟我学Pyth

作者: 肚财神 | 来源:发表于2017-09-21 19:43 被阅读313次
    • 1.本系列基于新生大学课程《Python编程&数据科学入门》和公开的参考资料;
    • 2.文章例子基于python3.6,使用Windows系统(除了安装,其余基本没有影响);
    • 3.我是纯小白,所以,错误在所难免,体系会逐渐成熟;如果您发现了错误,也烦请帮我指出来,在此先谢过了。
    泰坦尼克号沉没

    这次课主要是通过一个案例来学习数据分析的流程和方法。主要有学习三个内容:

    • 数据分析的流程
    • 数据清洗(缺失值的处理)
    • 数据探索的方法

    数据分析的流程

    python最强大的是数据分析。下面是数据分析的流程图:

    数据分析流程图

    数据分析的核心是问题,为了解决这个问题,开始采集数据,而我们采集的数据经常出现不完整,内容不全等情况,所以要对数据进行清洗,让数据变的方便使用。

    数据完整之后,就可以开始对数据的探索了,期待从中发现规律,解决问题,在探索的过程中通常会发现新的问题,继续往下探索就需要新的数据,这时通常会再次重复上面的过程。

    当数据探索的差不多了,就可以把结论变成一个模型进一步来分析和验证(这不是python的工作了),最后将结果发布出来,用于决策。

    这个流程不论在哪个行业都是通用的。下面我们就以泰坦尼克的数据来走一遍这个流程。

    我们想要解决的问题是:船只沉没后,哪些因素能够影响生还的概率?

    泰坦尼克的数据是公开的,我们不需要单独采集数据了。

    先导入这个数据:

    #读取常用的包,并进行常规设置 
    import pandas as pd
    import numpy as np
    import seaborn as sns
    import matplotlib.pyplot as plt
    %matplotlib inline
    %config InlineBackend.figure_format = 'retina'
    
    # 读取数据
    titanic_df = pd.read_csv('lesson/titanic.csv')
    titanic_df.head()
    

    导入后,我们可以看一看都有哪些字段:

    PassengerId: 乘客的id
    Survival: 是否幸存 0 = No, 1 = Yes
    Pclass: 舱位 class 1 = 1st, 2 = 2nd, 3 = 3rd
    Name: 姓名
    Sex: 性别
    Age: 年龄
    SibSp: 船上兄弟姐妹以及配偶的个数
    Parch: 船上父母以及者子女的个数
    Ticket: 船票号码
    Fare: 票价
    Cabin: 船舱号码
    Embarked: 登船码头 C = Cherbourg, Q = Queenstown, S = Southampton

    这13个字段可以分为三类:字符串、数值变量、分类变量。

    字符串不需要讲解,分类变量的内容可以分为有限的几类,比如Survived有0和1两类,Pclass有1、2、、3三类,Sex有male、female两类,SibSp、Parch、Embarked等是分类变量;而数值变量就是其内容是一个数字,比如PassengerId、Ticket、Fare等等。

    导入数据后,我们可以观察一下这个数据:

    titanic_df.describe(include = [np.object])#列出分类变量
    # top代表最高频的一个值,freq代表最高频值对应的频率
    

    看看各个舱位的占比情况:

    # 使用group_by函数
    (titanic_df.groupby('Pclass').agg('size')/len(titanic_df)).sort_values(ascending = True)
    
    Pclass
    2    0.206510
    1    0.242424
    3    0.551066
    dtype: float64
    

    查看登船码头人数分布的百分比:

    # 方法1:使用 value_counts
    titanic_df.Embarked.value_counts()/ len(titanic_df)
    
    S    0.722783
    C    0.188552
    Q    0.086420
    Name: Embarked, dtype: float64
    
    # 方法2:使用 group_by
    (titanic_df.groupby('Embarked').agg('size')/len(titanic_df)).sort_values(ascending = True)
    
    Embarked
    Q    0.086420
    C    0.188552
    S    0.722783
    dtype: float64
    

    数据清洗(缺失值的处理)

    我们再观察一下这个数据的整体情况:

    Age、Cabib、Embarked这3列的值都是不全的,它们被赋予了NaN值,也就是Not a Number的意思。

    为了不影响分析数据,我们要把这些值填满,这就叫缺失值处理。

    处理起来主要有三种方法:

    • 直接丢掉这个变量。 -- 删除某一列数据
    • 用平均值或中位数填补缺失值。像Age这样的重要变量,有20%左右的缺失值,我们可以考虑用中位值来填补。-- 填补缺失值
    • 删除带缺失值的行。因为其他非缺失的变量可能提供有用的信息,删除行有时影响不会太大。

    第一和第三种方法比较简单,直接输入命令就可以。下面我们来看如何填补年龄字段的缺失值。

    填补通常用中位数。

    # 重新载入数据,防止数据改变.
    titanic_df = pd.read_csv('lesson/titanic.csv')
    # 获取数据的平均值
    age_med1 = titanic_df.Age.median()
    # 使用fillna函数填充缺失值,inplace表示在原数据上直接修改
    titanic_df.Age.fillna(age_med1, inplace=True)
    

    可以看到,Age已经有891个,说明已经被填补好了。

    如果考虑到男女可能差异较大的因素,也可以尝试用男女乘客各自年龄的中位数来填补。

    # 重新载入数据,防止数据被改变了
    titanic_df = pd.read_csv('lesson/titanic.csv')
    # 分组计算男女乘客的中位数
    age_med2 = titanic_df.groupby('Sex').Age.median()
    age_med2
    
    # 重新设置索引,将Sex为索引
    titanic_df.set_index('Sex', inplace=True)
    
    # 使用fillna填充
    titanic_df.Age.fillna(age_med2, inplace = True)
    #恢复索引
    titanic_df.reset_index(inplace= True)
    titanic_df.Age.describe()
    

    下面同时考虑姓名和仓位的因素进行填充。

    # 重新导入原始数据
    titanic_df = pd.read_csv('lesson/titanic.csv')
    # 分组计算不同仓位男女年龄的中位数,得到一个Serics数据,索引为Pclass、Sex
    age_med3 = titanic_df.groupby(['Pclass',"Sex"]).Age.median()
    age_med3
    
    # 设置Pclass、Sex为索引,按照两列进行索引inplace=True表示直接替换原来的索引
    titanic_df.set_index(['Pclass','Sex'],inplace=True)
    # 用fillna填充
    titanic_df.Age.fillna(age_med3, inplace=True)
    
    #恢复索引
    titanic_df.reset_index(inplace=True)
    
    #查看填充结果
    titanic_df.Age.describe()
    

    数据探索和分析

    1.计算舱位和生还概率的关系

    Survived 是0-1,所以均值就代表其生还概率。

    #用groupby方法来实现
    titanic_df[['Pclass','Survived']].groupby('Pclass').mean()
    

    用透视表pivot_talbe函数(透视表)可以实现同样的功能。

    # values代表聚合后被施加计算的值,这里施加的是mean函数
    # index:是分组用的变量
    # aggfunc是定义施加的函数
    titanic_df.pivot_table(values='Survived', index='Pclass',aggfunc=np.mean)
    
    # 还可以画出条形图
    sns.barplot(data = titanic_df, x='Pclass', y= 'Survived',ci=None)
    

    所以,头等舱的生还概率最高,二等舱次之,三等舱最低。

    2.再来看性别与生还的关系

    #使用groupby函数
    titanic_df[['Sex','Survived']].groupby('Sex').mean()
    
    # 使用pivot_talbe函数
    titanic_df.pivot_table(values = 'Survived', index = 'Sex', aggfunc = np.mean)
    
    
    # 绘制条形图
    sns.barplot(data= titanic_df, x= 'Sex', y ='Survived', ci = None)
    plt.show()
    

    结论:女性的生还率远远大于男性

    3.综合考虑女性和舱位于生还的概率

    titanic_df[["Pclass",'Sex','Survived']].groupby(['Pclass','Sex']).mean()
    
    # 使用pivot_table方法
    titanic_df.pivot_table(values='Survived', index=['Pclass', 'Sex'],aggfunc=np.mean )
    
    # 方法3:同样用pivot_table方法,将其中一个索引作为列
    # columns指定另一个分类变量
    
    # 绘制条形图
    sns.barplot(data=titanic_df, x='Pclass', y = 'Survived', hue='Sex', ci=None)
    
    # 绘制折线图
    sns.pointplot(data=titanic_df, x='Pclass', y = 'Survived', hue='Sex', ci=None)
    

    4.分别使用groupby和pivot_talbe,计算在不同舱位中男女乘客的人数。

    # 方法1 groupby
    titanic_df.groupby(['Pclass','Sex']).Sex.count()
    
    Pclass  Sex   
    1       female     94
            male      122
    2       female     76
            male      108
    3       female    144
            male      347
    Name: Sex, dtype: int64
    
    # 方法2 groupby
    titanic_df[['Pclass','Sex','Ticket']].groupby(['Pclass','Sex']).count()
    
    # 方法3 pivot_talbe
    titanic_df.pivot_table(values='Ticket', index=['Pclass','Sex'], aggfunc='count')
    
    # 方法4
    titanic_df.pivot_table(values= 'Ticket',index='Pclass',columns='Sex',aggfunc='count')
    

    5.绘制生还组和罹难组的年龄分布直方图

    # 用seaborn包里的FacetGrid().mpa来快速生成。
    # bins代表横轴取值的单位大小
    # normed表示纵轴的值按总数进行了比例换算
    sns.FacetGrid(titanic_df).map(plt.hist, 'Age', bins = 30, normed = True)
    
    # col是列的意思,可以指定在一行中显示显示区分。
    sns.FacetGrid(titanic_df, col = 'Survived').map(plt.hist, 'Age', bins = 30, normed = True)
    
    
    <seaborn.axisgrid.FacetGrid at 0xb37c74b7f0>
    

    结论:
    1.儿童的生还率最高,而其他的年龄层次都不明显。

    6.考虑舱位因素,绘制生还组和罹难组的年龄分布直方图(作业 8-3)。

    提示:FacetGrid参数中同时设置col和row

    sns.FacetGrid(titanic_df,col = 'Survived', row = 'Pclass').map(plt.hist, 'Age', bins=30, normed=True)
    
    

    7.查看落在不同年龄区间的人数

    • 将连续型的变量零散化

    将连续变化的值划分为几个区间,落在同一个区间的就有些同一个符号来表示。这种方法能够增加数据分析的便利性。

    #用pandas中的cut函数来表示。
    titanic_df['Ageband'] = pd.cut(titanic_df.Age, 4)
    titanic_df.head()
    

    增加了一列Ageband。

    # 方法一:用value_counts函数
    titanic_df.Ageband.value_counts(sort=False)
    
    (0.34, 20.315]     179
    (20.315, 40.21]    562
    (40.21, 60.105]    128
    (60.105, 80.0]      22
    Name: Ageband, dtype: int64
    
    # 方法二:用pivot_table
    titanic_df.pivot_table(values='Survived', index='Ageband',aggfunc='count')
    
    # 查看各个年龄区间的生还概率
    # 方法1:
    titanic_df[['Survived','Ageband']].groupby('Ageband').mean()
    
    #方法2:用pivot_table
    titanic_df.pivot_table(values='Survived',index='Ageband', aggfunc=np.mean)
    
    # 方法3:画出这样一个条形图
    sns.barplot(data=titanic_df, x='Ageband',y='Survived')
    plt.xticks(rotation= 45)
    

    8.查看年龄、性别与生还的概率。

    其实方法都是一样的。

    #第一种方法:用groupby
    titanic_df.groupby(['Ageband','Sex']).Survived.mean()
    
    Ageband          Sex   
    (0.34, 20.315]   female    0.688312
                     male      0.284314
    (20.315, 40.21]  female    0.756614
                     male      0.166220
    (40.21, 60.105]  female    0.755556
                     male      0.192771
    (60.105, 80.0]   female    1.000000
                     male      0.105263
    Name: Survived, dtype: float64
    
    #第二种方法:grouby
    titanic_df[['Ageband','Sex','Survived']].groupby(['Ageband','Sex']).mean()
    
    # 第三种方法:pivot_table
    titanic_df.pivot_table(values='Survived', index=['Ageband','Sex'], aggfunc=np.mean)
    
    # 第四种方法:pivot_table
    titanic_df.pivot_table(values='Survived',index='Ageband',columns='Sex',aggfunc=np.mean)
    
    # 方法5:用图示表示,画出条形图barplot
    
    sns.FacetGrid(titanic_df, col ='Sex', row='Ageband').map(plt.hist, 'Survived')
    
    
    # 方法5:用折线图
    sns.pointplot(data=titanic_df, x= 'Ageband', y='Survived', hue = 'Sex', ci=None)
    plt.xticks(rotation=45)
    
    (array([0, 1, 2, 3]), <a list of 4 Text xticklabel objects>)
    

    8.分析年龄、舱位、性别与生还概率的关系

    # 第一种方法
    titanic_df.pivot_table(values='Survived', index='Ageband', columns=['Sex','Pclass'],aggfunc='mean')
    
    # 第二种方法:第一步,先用sns.pointplt来绘制舱位、性别与生还概率的关系
    sns.pointplot(data=titanic_df, x='Pclass',y='Survived',hue='Sex',ci=None)
    
    <matplotlib.axes._subplots.AxesSubplot at 0xb37d2800b8>
    
    # 第二步,再用FacetGrid函数同时绘制不同年龄组的生还概率
        
    sns.FacetGrid(data=titanic_df,row='Ageband',aspect=1.5)\
        .map(sns.pointplot, 'Pclass','Survived','Sex',hue_order=['male','female'],palette='deep',ci=None)
    

    9.综合考虑性别、舱位和登船码头与生还概率的关系

    # 方法1:pivot_table
    titanic_df.pivot_table(values='Survived',index=['Sex','Pclass','Embarked'],aggfunc=np.mean)
    
    # 方法2:pivot_table
    titanic_df.pivot_table(values='Survived',index=['Embarked','Pclass'],columns='Sex',aggfunc=np.mean)
    
    # 方法3:画出折线图,我们尝试用一下上节课学到的pairplot函数,两两因素相匹配,按照年龄段来划分颜色
    sns.pairplot(titanic_df, hue='Ageband')
    
    # 方法4:用折线图体现性别、舱位和登船码头与生还概率的关系。
    # 同样的,第一步先画出三个关系的折线图,我们先考虑性别、舱位和生还概率
    sns.pointplot(data=titanic_df, x='Sex',y='Survived',hue='Pclass',ci=None)
    
    
    # 第二步,使用FacetGrid函数
    sns.FacetGrid(data = titanic_df, row='Embarked', aspect=1.5) \
       .map(sns.pointplot, 'Sex', 'Survived', 'Pclass',hueorder=['male','female'], palette='deep', ci=None)
    

    相关文章

      网友评论

        本文标题:用python对泰坦尼克数据进行分析 | 一步一步跟我学Pyth

        本文链接:https://www.haomeiwen.com/subject/bljtextx.html