zoukankan      html  css  js  c++  java
  • Titanic(python)

    数据集中共有12个字段,PassengerId:乘客编号,Survived:乘客是否存活,Pclass:乘客所在的船舱等级;Name:乘客姓名,Sex:乘客性别,Age:乘客年龄,SibSp:乘客的兄弟姐妹和配偶数量,Parch:乘客的父母与子女数量,Ticket:票的编号,Fare:票价,Cabin:座位号,Embarked:乘客登船码头,共有891位乘客的数据信息。其中277位乘客的年龄数据缺失,2位乘客的登船码头数据缺失,687位乘客的船舱数据缺失。

    1.1 数据加载与描述性统计

    加载所需数据与所需的python库。

    import statsmodels.api as sm
    import statsmodels.formula.api as smf
    import statsmodels.graphics.api as smg
    import patsy
    %matplotlib inline
    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    from pandas import Series,DataFrame
    from scipy import stats
    import seaborn as sns
    
    #导入CSV数据
    train=pd.read_csv('F:/python/titanic_data.csv')

     描述性统计

    train.info()
    train.describe()
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 891 entries, 0 to 890
    Data columns (total 12 columns):
     #   Column       Non-Null Count  Dtype  
    ---  ------       --------------  -----  
     0   PassengerId  891 non-null    int64  
     1   Survived     891 non-null    int64  
     2   Pclass       891 non-null    int64  
     3   Name         891 non-null    object 
     4   Sex          891 non-null    object 
     5   Age          714 non-null    float64
     6   SibSp        891 non-null    int64  
     7   Parch        891 non-null    int64  
     8   Ticket       891 non-null    object 
     9   Fare         891 non-null    float64
     10  Cabin        204 non-null    object 
     11  Embarked     889 non-null    object 
    dtypes: float64(2), int64(5), object(5)
    memory usage: 83.7+ KB
    
     
     PassengerIdSurvivedPclassAgeSibSpParchFare
    count 891.000000 891.000000 891.000000 714.000000 891.000000 891.000000 891.000000
    mean 446.000000 0.383838 2.308642 29.699118 0.523008 0.381594 32.204208
    std 257.353842 0.486592 0.836071 14.526497 1.102743 0.806057 49.693429
    min 1.000000 0.000000 1.000000 0.420000 0.000000 0.000000 0.000000
    25% 223.500000 0.000000 2.000000 20.125000 0.000000 0.000000 7.910400
    50% 446.000000 0.000000 3.000000 28.000000 0.000000 0.000000 14.454200
    75% 668.500000 1.000000 3.000000 38.000000 1.000000 0.000000 31.000000
    max 891.000000 1.000000 3.000000 80.000000 8.000000 6.000000 512.329200

    描述性统计分析结果显示,共有38.3%的乘客存活,乘客船舱等级的平均值介于2和3之间,大部分乘客等级较低。乘客年龄的平均值为29.7岁,最小值为0.42岁,最大值为80岁。乘客的兄弟姐妹和配偶数目平均值为0.52,最小值为0,最大值为8个。乘客的父母和子女数目平均值为0.38,最小值为0,最大值为6个。乘客票价的平均值为32,最小值为0,最大值为512,75%分位数为31,表明大部分乘客的消费能力较低

    1.2单变量探索

    1.2.1 年龄与费用

    画出训练集中乘客年龄和费用的分布直方图,如下所示。可以发现,大部分乘客的年龄位于20-40岁之间,总体上呈正态分布。大部分乘客的票价很低,位于0-100之间,其他少部分乘客的票价较高

    fig,ax = plt.subplots(nrows=1,ncols=2,figsize=(15,5))
    train["Age"].hist(ax=ax[0])
    ax[0].set_title("Hist plot of Age")
    train["Fare"].hist(ax=ax[1])
    ax[1].set_title("Hist plot of Fare")

     

    1.2.2 乘客是否获救

    画出乘客获救与没有获救的条形图,如下所示。可以发现,大部分乘客没有获救

    fig,ax = plt.subplots(figsize=(7,5))
    train["Survived"].value_counts().plot(kind="bar")
    ax.set_xticklabels(("Not Survived","Survived"),  rotation= "horizontal" )
    ax.set_title("Bar plot of Survived ")

     

    1.2.3 性别

    画出乘客性别条形分布图,如下所示。可以发现,大部分乘客为男性

    fig,ax = plt.subplots(figsize=(7,5))
    train["Sex"].value_counts().plot(kind="bar")
    ax.set_xticklabels(("male","female"),rotation= "horizontal"  )
    ax.set_title("Bar plot of Sex ")

     

    1.2.4 乘客所在的船舱等级

    画出乘客的Pclass条形分布图,如下所示。可以发现,大部分乘客位于第三等级,第一等级和第二等级的乘客各有200个左右

    fig,ax = plt.subplots(figsize=(7,5))
    train["Pclass"].value_counts().plot(kind="bar")
    ax.set_xticklabels(("Class3","Class1","Class2"),rotation= "horizontal"  )
    ax.set_title("Bar plot of Pclass ")

     

    1.2.5 乘客座位号

    对乘客座位号数据进行处理,将缺失值赋值为Unknown。从乘客座位号数据可以发现,第一个字母可能代表了船舱号码,将该字符提取出来,赋值给Cabin,视为船舱号

    train.Cabin.fillna("Unknown",inplace=True)
    for i in range(0, 891):
        train.Cabin[i]= train.Cabin[i][0]

     画出乘客的船舱号的条形分布图,如下所示。可以发现,大部分乘客的船舱号为未知。

    fig,ax = plt.subplots(figsize=(7,5))
    train.Cabin.value_counts().plot(kind="bar")
    ax.set_title("Bar plot of Cabin ")

     

    1.2.6 兄弟姐妹与配偶数目

    画出乘客兄弟姐妹与配偶数目的条形分布图,如下所示。可以发现,大部分乘客在船上没有兄弟姐妹或配偶,大约200位乘客在船上有1个兄弟姐妹或配偶

    fig,ax = plt.subplots(figsize=(7,5))
    train["SibSp"].value_counts().plot(kind="bar")
    ax.set_title("Bar plot of SibSp ")

     

    1.2.7 父母与子女数目

    画出乘客父母与子女数目的条形分布图,如下所示。可以发现,大部分乘客在船上没有父母或子女,100多位乘客在船上有1个兄弟姐妹或配偶,大约90位乘客在船上有2个兄弟姐妹或配偶

    fig,ax = plt.subplots(figsize=(7,5))
    train["Parch"].value_counts().plot(kind="bar")
    ax.set_title("Bar plot of Parch ")

     

    1.2.8 乘客出发港口

    画出乘客出发港口的分布条形图,如下所示。可以发现,大部分乘客从Southampton港口出发,不到200位乘客从Cherburge出发,不到100位乘客从Queentown出发

    fig,ax = plt.subplots(figsize=(7,5))
    train["Embarked"].value_counts().plot(kind="bar")
    ax.set_xticklabels(("Southampton","Cherbourg","Queenstown"),rotation= "horizontal"  )
    ax.set_title("Bar plot of Embarked ")

     

    1.3 多变量探索

    1.3.1 性别与是否获救

    画出性别与是否获救的交叉表和条形图,如下所示。可以发现,女性获救的可能性更高,而男性获救的比例很低

    pd.crosstab(train["Sex"],train["Survived"])
    Survived01
    Sex  
    female 81 233
    male 468 109
    pd.crosstab(train["Sex"],train["Survived"]).plot(kind="bar")

     

    1.3.2 船舱等级与是否获救

    画出船舱等级与是否获救的交叉表与条形图,如下所示。可以发现,第一等级的乘客获救的可能性更高,超过50%,第二等级的乘客获救可能性在50%左右,而第三等级的乘客获救可能性很低

    pd.crosstab(train["Pclass"],train["Survived"])
    Survived01
    Pclass  
    1 80 136
    2 97 87
    3 372 119
    pd.crosstab(train["Pclass"],train["Survived"]).plot(kind="bar")

     

    1.3.3 兄弟姐妹或配偶数量与是否获救

    画出兄弟姐妹与配偶数目与是否获救的交叉表与条形图,如下所示。可以发现,有数量为1或2的乘客获救的可能性更高

    pd.crosstab(train["SibSp"],train["Survived"]).plot(kind="bar")

     

    1.3.4 父母或子女数目和是否获救

    画出父母或子女数目与是否获救的交叉表与条形图,如下所示。可以发现,有数量为1或2的乘客获救的可能性更高

    pd.crosstab(train["Parch"],train["Survived"]).plot(kind="bar")

    1.3.5 登船港口与是否获救

    画出登船港口与是否获救的交叉表与条形图,如下所示。可以发现,从Cherburge出发的乘客获救的人数比例更高

    pd.crosstab(train["Embarked"],train["Survived"]).plot(kind="bar")

    1.3.6 乘客船舱与是否获救

    画出乘客所在船舱与是否获救的交叉表与条形图,如下所示。可以发现,船舱后没有缺失的乘客获救的人数比例更高

    pd.crosstab(train["Cabin"],train["Survived"]).plot(kind="bar")

    1.3.7 乘客年龄与是否获救

    画出乘客是否获救与年龄的箱线图,如下所示。从箱线图上来看,两者关系并不明显

    fig,ay = plt.subplots()
    Age1 = train.Age[train.Survived == 1].dropna()
    Age0 = train.Age[train.Survived == 0].dropna()
    plt.boxplot((Age1,Age0),labels=('Survived','Not Survived'))
    ay.set_ylim([-5,70])
    ay.set_title("Boxplot of Age")

    1.3.8 票价与是否获救

    画出乘客是否获救与票价的箱线图,如下所示。可以发现,总体而言,获救的乘客票价更高

    fig,ay = plt.subplots()
    Fare1 = train.Fare[train.Survived == 1]
    Fare0 = train.Fare[train.Survived == 0]
    plt.boxplot((Fare1,Fare0),labels=('Survived','Not Survived'))
    ay.set_ylim([-10,150])
    ay.set_title("Boxplot of Fare")

    1.3.9 票价与乘客舱位等级

    画出乘客票价与舱位等级的箱线图,如下所示。可以明显的发现,舱位等级越高的乘客,票价越高。这两个变量之间存在非常明显的线性相关关系

    fig,ay = plt.subplots()
    Farec1 = train.Fare[train.Pclass == 1]
    Farec2 = train.Fare[train.Pclass == 2]
    Farec3 = train.Fare[train.Pclass == 3]
    plt.boxplot((Farec1,Farec2,Farec3),labels=("Pclass1","Pclass2","Pclass3"))
    ay.set_ylim([-10,180])
    ay.set_title("Boxplot of Fare and Pclass")

    1.4 数据处理

    1.4.1 缺失值处理

    用年龄的均值填充年龄的缺失值,用出发港口的众数填补出发港口的缺失值

    train.Age.mean()
    train.Age.fillna(29.7,inplace=True)
    train.Embarked.fillna("S",inplace=True)

    1.4.2 数据分箱

    根据以上分析结果和变量间的关系,将年龄数据分段为0-5岁、5-15岁、15-20岁、20-35岁、35-50岁、50-60岁、60-100岁7段。将Parch变量分成数目为0、数目为1或2、数目为大于2三段。将SibSp变量分成数目为0、数目为1或2、数目为大于2三段。将Cabin变量分为缺失和没有缺失两段

    train.age=pd.cut(train.Age,[0,5,15,20,35,50,60,100])
    pd.crosstab(train.age,train.Survived).plot(kind="bar")

    train.Parch[(train.Parch>0) & (train.Parch<=2)]=1
    train.Parch[train.Parch>2]=2
    train.SibSp[(train.SibSp>0) & (train.SibSp<=2)]=1
    train.SibSp[train.SibSp>2]=2
    train.Cabin[train.Cabin!="U"]="K"

    1.4.3 创建虚拟变量

    为Pclass、Sex、Embarked、Parch、SibSp、Cabin变量创建虚拟变量

    dummy_Pclass = pd.get_dummies(train.Pclass, prefix='Pclass')
    dummy_Sex = pd.get_dummies(train.Sex, prefix='Sex')
    dummy_Embarked = pd.get_dummies(train.Embarked, prefix='Embarked')
    dummy_Parch = pd.get_dummies(train.Parch, prefix='Parch')
    dummy_SibSp = pd.get_dummies(train.SibSp, prefix='SibSp')
    dummy_Age = pd.get_dummies(train.age, prefix='Age')
    dummy_Cabin = pd.get_dummies(train.Cabin, prefix='Cabin')

    1.5 模型建立

    1.5.1 创建训练集

    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import confusion_matrix, roc_curve,roc_auc_score,classification_report 

    划分训练集,将编号为0-623的乘客作为训练集。去除PassengerId和Name变量,添加常数项intercept.

    因变量为乘客是否获救,自变量为乘客的票价、性别、登船码头、父母与子女数目、兄弟姐妹与配偶数目、年龄、船舱。除票价外,都为虚拟变量。考虑到Fare和Pclass之间的线性相关性,剔除Pclass变量

    train_y = train[:623]["Survived"]
    cols_to_keep = ["Fare"]
    train_x = train[:623][cols_to_keep].join(dummy_Sex.loc[:, "Sex_male":]).join(dummy_Embarked.loc[:,"Embarked_Q":]).join(dummy_Parch.loc[:,"Parch_1":]).join(dummy_SibSp.loc[:,"SibSp_1":]).join(dummy_Age.loc[:,"Age_(5, 15]":]).join(dummy_Cabin.loc[:,"Cabin_U" :])
    train_x['intercept'] = 1.0
    train_x.tail()

    1.5.2 模型构建

    对训练集构建逻辑斯蒂模型。

    clf = LogisticRegression()
    clf.fit(train_x,train_y)

    1.5.3 模型检验

    划分测试集,将编号为624-890的乘客作为测试集

    test_y = train[623:]["Survived"]
    cols_to_keep = ["Fare"]
    test_x = train[623:][cols_to_keep].join(dummy_Sex.loc[:, "Sex_male":]).join(dummy_Embarked.loc[:,"Embarked_Q":]).join(dummy_Parch.loc[:,"Parch_1":]).join(dummy_SibSp.loc[:,"SibSp_1":]).join(dummy_Age.loc[:,"Age_(5, 15]":]).join(dummy_Cabin.loc[:,"Cabin_U" :])
    test_x['intercept'] = 1.0
    test_x.head()

    利用测试集对模型进行测试

    clf.predict(test_x)
    clf.predict_proba(test_x)
    preds = clf.predict(test_x)
    #计算模型的混淆矩阵如下所示
    confusion_matrix(test_y,preds)

    计算模型的ROC/AUC得分,并画出ROC曲线。模型的ROC/AUC得分为0.88,表明预测准确的概率为88%左右。模型预测结果较好。

    pre = clf.predict_proba(test_x)
    roc_auc_score(test_y,pre[:,1])  #0.88114704457364346
    
    fpr,tpr,thresholds = roc_curve(test_y,pre[:,1])
    fig,ax = plt.subplots(figsize=(8,5))
    plt.plot(fpr,tpr)
    ax.set_title("Roc of Logistic Regression")

     模型预测结果分类报告如下所示

    print(classification_report(test_y,preds))
                  precision    recall  f1-score   support
    
               0       0.82      0.91      0.86       172
               1       0.79      0.64      0.71        96
    
        accuracy                           0.81       268
       macro avg       0.80      0.77      0.78       268
    weighted avg       0.81      0.81      0.80       268

    总体而言,模型的拟合结果较好

  • 相关阅读:
    MVC中使用EF(2):实现基本的CRUD功能
    ibatis学习之道:ibatis的<[CDATA]>dynamic属性跟#$的应用
    css-选择器
    postman进行http接口测试
    使用HttpClient测试SpringMVC的接口
    http接口测试—自动化测试框架设计
    接口测试自动化框架搭建
    JAVA利用HttpClient进行POST请求(HTTPS)
    java.io.IOException: Attempted read from closed stream. 异常,解决
    java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得
  • 原文地址:https://www.cnblogs.com/cgmcoding/p/13725026.html
Copyright © 2011-2022 走看看