项目08:Keras搭建模型预测泰坦尼克号游客信息

泰坦尼克号是当时世界上体积最庞大、内部设施最豪华的客运轮船,有“永不沉没”的美誉 。然而不幸的是,在它的处女航中,泰坦尼克号便遭厄运——它从英国南安普敦出发,途经法国瑟堡-奥克特维尔以及爱尔兰科夫(Cobh),驶向美国纽约。1912年4月14日23时40分左右,泰坦尼克号与一座冰山相撞,造成右舷船艏至船中部破裂,五间水密舱进水。4月15日凌晨2时20分左右,泰坦尼克船体断裂成两截后沉入大西洋底3700米处。2224名船员及乘客中,1517人丧生,其中仅333具罹难者遗体被寻回。泰坦尼克号沉没事故为和平时期死伤人数最为惨重的一次海难,其残骸直至1985年才被再度发现,目前受到联合国教育、科学及文化组织的保护。为了为往后船舶行业制定更好的安全计划和规约,该事件的旅客信息数据被完整的保存下来,供后人分析和使用。所以本章我们将利用Keras建立深度学习模型分析泰坦尼克号的每一位船员存活概率。

1.项目构建

在指定的磁盘路径创建存放当前项目的目录,linux或macos可使用mkdir命令创建文件夹目录,Windows直接使用图形化界面右键新建文件夹即可,例如我们的存放项目的目录名为project08:

 (dlwork) jingyudeMacBook-Pro:~ jingyuyan$ mkdir project08

创建成功后,在dlwork环境下,进入到project08目录下,创建dataset文件夹

 (dlwork) jingyudeMacBook-Pro:project08 jingyuyan$ mkdir dataset

创建成功后,在dlwork环境下,进入到project08目录下,打开jupyter notebook:

    jupyter notebook

新建一个新的ipynb文件,并且进入到文件中,初次使用该数据集需要使用以下代码下载titanic3.xls文件到dataset文件夹当中,下载需要一定的时间。

import urllib
import os
url='http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic3.xls'
filepath='./dataset/titanic3.xls'
if not os.path.isfile(filepath):
    result=urllib.request.urlretrieve(url,filepath)
    print('download:', result)

2. 数据预处理

该数据集主要记录了泰坦尼克号所有游客的信息,主要信息包括如下表格所示:

属性 说明
survival 是否生存
pclass 舱等
name 姓名
age 性别
sibsp 手足或者配偶也在船上数量
patch 双亲或者子女也在船上数量
ticket 船票号码
fare 旅客费用
cabin 仓位号码
embarked 登船港口

以上字段survival代表该对象是否得以生还,是我们主要的预测结果,也就是label,其余的特征均是特征字段。而survival在数据中,0表示未生还,1表示存活;pclass字段表示舱等,1、2、3分别可表示头等舱、二等舱和三等舱。

2.1 使用DataFrame分析数据和数据预处理

2.1.1 创建对象读取数据

使用Pandas提供的DataFrame功能和Numpy可读取xls文件,并格式化数据,可以更加方便的分析和处理数据。

导入所需要的包

import numpy
import pandas as pd
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
# 中文字体可以选择下载或从本书提供云盘下载放置项目目录中
font_zh = FontProperties(fname='./fz.ttf')

使用Pandas提供的read_excel程序读取xls文件

all_df = pd.read_excel(filepath)

查看读取到的all_df中的前5条数据

all_df[:5]
pclass survived name sex age sibsp parch ticket fare cabin embarked boat body home.dest
0 1 1 Allen, Miss. Elisabeth Walton female 29.0000 0 0 24160 211.3375 B5 S 2 NaN St Louis, MO
1 1 1 Allison, Master. Hudson Trevor male 0.9167 1 2 113781 151.5500 C22 C26 S 11 NaN Montreal, PQ / Chesterville, ON
2 1 0 Allison, Miss. Helen Loraine female 2.0000 1 2 113781 151.5500 C22 C26 S NaN NaN Montreal, PQ / Chesterville, ON
3 1 0 Allison, Mr. Hudson Joshua Creighton male 30.0000 1 2 113781 151.5500 C22 C26 S NaN 135.0 Montreal, PQ / Chesterville, ON
4 1 0 Allison, Mrs. Hudson J C (Bessie Waldo Daniels) female 25.0000 1 2 113781 151.5500 C22 C26 S NaN NaN Montreal, PQ / Chesterville, ON

2.1.2 简单的对数据进行分析

使用describe函数可以对已经建立好的数据进行变量统计,可以比较让人更方便的看出各个变量直接之间存在相互影响的关系。

all_df.describe()
pclass survived age sibsp parch fare body
count 1309.000000 1309.000000 1046.000000 1309.000000 1309.000000 1308.000000 121.000000
mean 2.294882 0.381971 29.881135 0.498854 0.385027 33.295479 160.809917
std 0.837836 0.486055 14.413500 1.041658 0.865560 51.758668 97.696922
min 1.000000 0.000000 0.166700 0.000000 0.000000 0.000000 1.000000
25% 2.000000 0.000000 21.000000 0.000000 0.000000 7.895800 72.000000
50% 3.000000 0.000000 28.000000 0.000000 0.000000 14.454200 155.000000
75% 3.000000 1.000000 39.000000 1.000000 0.000000 31.275000 256.000000
max 3.000000 1.000000 80.000000 8.000000 9.000000 512.329200 328.000000

从数据结果来看,游客中平均生还0.38,其中游客平均年龄为29岁,也有上到80岁,下到4个月的游客。

查看船上乘客的年龄和票价的整体分布情况

fig,ax = plt.subplots(nrows=1,ncols=2,figsize=(15,5))
all_df["age"].hist(ax=ax[0])
ax[0].set_title("Hist plot of Age")
all_df["fare"].hist(ax=ax[1])
ax[1].set_title("Hist plot of Fare")
Text(0.5, 1.0, 'Hist plot of Fare')

png

乘客的年龄集中在20-40岁之间,大部分乘客的票价很低,基本在0-100之间。

sex_count = all_df.sex.value_counts()
sex_count.plot(kind='pie',autopct = '%3.1f%%');

png

通过对性别进行分析,可以发现在旅客群体中,男性群体是大于女性的

# 不同性别的获救情况分布
survive_0 = all_df['survived'][all_df['sex']=='female'].value_counts()
survive_1 = all_df['survived'][all_df['sex']=='male'].value_counts()
data_sex = pd.DataFrame({'survived': survive_1,'no survived': survive_0})
data_sex.plot(kind='Bar',stacked=True)
plt.title('不同性别的获救比例', fontproperties=font_zh)
plt.show()

png

从图上可看出,船上的男性群体比女性群体来得多,但是男性获救的比例不到20%,女性获救的比例达到70%以上,说可能明船上的男士比较绅士,优先把存活的机会留给了女性。

# 不同等级舱位的获救情况
survive_0 = all_df['pclass'][all_df['survived']==0].value_counts()
survive_1 = all_df['pclass'][all_df['survived']==1].value_counts()
data_pclass = pd.DataFrame({'survived': survive_1,'no survived': survive_0})
data_pclass.plot(kind='Bar',stacked=True)
plt.title('不同等级舱位的获救比例', fontproperties=font_zh)
Text(0.5, 1.0, '不同等级舱位的获救比例')

png

从上图可以发现不同等级的舱位生还概率不一样,其中头等舱生还概率是最高的,这说明在当时可能越有钱越容易被救。

# 不同登录港口的获救情况
survive_0 = all_df['embarked'][all_df['survived']==0].value_counts()
survive_1 = all_df['embarked'][all_df['survived']==1].value_counts()
data_embarked = pd.DataFrame({'survived': survive_1,'no survived': survive_0})
data_embarked.plot(kind='bar',stacked=True)
plt.title('不同登录港口的获救比例', fontproperties=font_zh)
plt.show()

png

S港口登录的人数最多,但是获救的比例却最低,C港口获救的比例是最高的,大概60%,Q港口为35%左右。

2.1.3 对数据进行预处理

我们把需要用到的关键字选取到DataFrame中,忽略掉一些与预测结果无太多关系的数据,例如ticket(船票号码)和cabin(舱位号码)。

cols = ['survived', 'name', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare', 'embarked']
all_df = all_df[cols]

设置后随机选择显示一些字段

all_df[100:105]
survived name pclass sex age sibsp parch fare embarked
100 1 Duff Gordon, Sir. Cosmo Edmund ("Mr Morgan") 1 male 49.0 1 0 56.9292 C
101 0 Dulles, Mr. William Crothers 1 male 39.0 0 0 29.7000 C
102 1 Earnshaw, Mrs. Boulton (Olive Potter) 1 female 23.0 0 1 83.1583 C
103 1 Endres, Miss. Caroline Louise 1 female 38.0 0 0 227.5250 C
104 1 Eustis, Miss. Elizabeth Mussey 1 female 54.0 1 0 78.2667 C

为了方便机器学习,我们还需要对一些字段进行特殊处理。

字段 处理方式
name 姓名字段对预测的结果不会有任何影响,所以要先将其删除,但是在预测阶段会使用到
age 数据集中有许多age字段是为空的值,所以我们需要将这些空值转换成平均值
sex 性别我们需要将其转换成数字的形式,0表示女性,1表示男性
fare 数据集中有许多fare字段是为空的值,所以我们需要将这些空值转换成平均值
embarked 三个港口分类C、Q、S需要使用One-Hot编码的形式进行转换

下面我们开始处理训练需要使用的数据集,首先是姓名部分,我们将其删除即可。

df = all_df.drop(['name'],axis=1)

找出数据集中有空值的部分,也就是无数据的部分。

all_df.isnull().sum()
survived      0
name          0
pclass        0
sex           0
age         263
sibsp         0
parch         0
fare          1
embarked      2
dtype: int64

可以看到age字段存在较多的空值,因为后面建立深度学习模型传递的参数需要确立的数字,所以这里不允许使用空值,我们将年龄这个字段取整理平均值后填入空值的部分,其他字段例如fare以此类推,这样的做法相对比较合理,而不是直接填入0,或者随意数字,容易影响对真实结果的预测。

利用mean函数计算年龄平均值后,使用fillna对空值字段进行填入。

# 计年龄平均值
age_mean = df['age'].mean()
# 填充空的年龄值
df['age'] = df['age'].fillna(age_mean)

fare字段和age字段处理方式一样,以此类推。

fare_mean = df['fare'].mean()
df['fare'] = df['fare'].fillna(fare_mean)

原本的性别字段是字符串形式的,我们需要将其转换成0和1,方便后期有效的机器学习,使用map方式可以进行转换。男性表示1,女性表示0。

df['sex']= df['sex'].map({'female':0,'male': 1}).astype(int)

将embarked字段进行一位有效编码,使用get_dummies函数进行转换。

# 将数据转换为DataFrame
x_OneHot_df = pd.get_dummies(data=df,columns=["embarked"])
x_OneHot_df[:5]
survived pclass sex age sibsp parch fare embarked_C embarked_Q embarked_S
0 1 1 0 29.0000 0 0 211.3375 0 0 1
1 1 1 1 0.9167 1 2 151.5500 0 0 1
2 0 1 0 2.0000 1 2 151.5500 0 0 1
3 0 1 1 30.0000 1 2 151.5500 0 0 1
4 0 1 0 25.0000 1 2 151.5500 0 0 1

2.2 使用Numpy进行数据预处理

使用DataFrame处理好数据后,后续需要交由Numpy进行处理才可搭建深度学习模型进行训练预测。

2.2.1 将数据转换成Numpy的ndarray类型

DataFrame转换成ndarray

# 多维数组的转换
ndarray = x_OneHot_df.values

使用shape查看数组的形状

# 查看数组形状
ndarray.shape
(1309, 10)

可以得知以上数组中具有1309项数据,每一项数据有10个字段

随机查看几项数据

ndarray[200:202]
array([[ 0.    ,  1.    ,  1.    , 46.    ,  0.    ,  0.    , 75.2417,
         1.    ,  0.    ,  0.    ],
       [ 0.    ,  1.    ,  1.    , 54.    ,  0.    ,  0.    , 51.8625,
         0.    ,  0.    ,  1.    ]])

通过上小节数据预处理过程可得知,除了第一个字段是survived,也是我们需要使用的标签,其余字段均作为特征处理

我们将标签字段和特征字段进行单独处理。

# 标签
labels = ndarray[:,0]
# 特征
features = ndarray[:,1:]

查看labels和features随机几项数据

labels[200:203]
array([0., 0., 1.])
features[200:203]
array([[ 1.    ,  1.    , 46.    ,  0.    ,  0.    , 75.2417,  1.    ,
         0.    ,  0.    ],
       [ 1.    ,  1.    , 54.    ,  0.    ,  0.    , 51.8625,  0.    ,
         0.    ,  1.    ],
       [ 1.    ,  1.    , 36.    ,  0.    ,  0.    , 26.2875,  0.    ,
         0.    ,  1.    ]])

可以看到第从200到203三项中,只有第三个游客是生还的,三名游客年龄分别是46、54和36岁,其中票价分别是75、51、26元。可以看出,类似年龄和票价这样的数据是没有统一标准的,数字差异相对比较明显,为了方便后面的机器学习过程,我们可以将数值标准化处理,让这些数字都浮动在0和1之间,使数值的特征字段又共同的标准,这样处理可以提升模型的准确率。

2.2.2 将特征字段进行标准化

使用sklearn提供的preprocessing模块进行标准化的处理,若没有sklearn这个库可以执行以下命令进行下载。

pip install scikit-learn

建立标准化刻度,区间在0到1之间

from sklearn import preprocessing
# 建立MinMaxScaler标准化刻度minmax_scale
minmax_scale = preprocessing.MinMaxScaler(feature_range=(0,1))

将需要标准化的字段传入,并设置标准化区间为0到1之间

# 传入特征数进行标准化
scaledFeatures = minmax_scale.fit_transform(features)

随机查看标准化后的几项数据,可以发现刚才我们所查看的一些字段已经完成标准化设置

scaledFeatures[100:102]
array([[0.        , 1.        , 0.61169086, 0.125     , 0.        ,
        0.1111184 , 1.        , 0.        , 0.        ],
       [0.        , 1.        , 0.48642985, 0.        , 0.        ,
        0.05797054, 1.        , 0.        , 0.        ]])

2.2.3 建立和划分数据集

到了这一步,我们现在所需要处理的数据将会是下一节建立的深度学习模型需要直接使用的数据。我们将数据集以8:2的模式划分为训练集和测试集。

# 将数据以随机方式分为训练和测试数据
msk = numpy.random.rand(len(all_df))<0.8
train_df = all_df[msk]
test_df = all_df[~msk]

划分完毕后,训练集有1052项数据,测试集有257项数据

# 显示训练数据与测试数据项数
print('total:',len(all_df),
     'train:',len(train_df),
     'test:',len(test_df))
total: 1309 train: 1074 test: 235

查看划分数据集

train_df[100:102]
survived name pclass sex age sibsp parch fare embarked
120 1 Frauenthal, Mr. Isaac Gerald 1 male 43.0 1 0 27.7208 C
121 1 Frauenthal, Mrs. Henry William (Clara Heinshei... 1 female NaN 1 0 133.6500 S
test_df[100:102]
survived name pclass sex age sibsp parch fare embarked
547 0 Richard, Mr. Emile 2 male 23.0 0 0 15.0458 C
549 1 Richards, Master. William Rowe 2 male 3.0 1 1 18.7500 S

创建DataPreprocessing函数,对之前数据处理方式做一个函数式的整合,方便下次调用

#  创建DataPreprocessing函数,方便下次预处理使用
def DataPreprocessing(raw_df):
    df=raw_df.drop(['name'], axis=1)
    age_mean = df['age'].mean()
    df['age'] = df['age'].fillna(age_mean)
    fare_mean = df['fare'].mean()
    df['fare'] = df['fare'].fillna(fare_mean)
    df['sex']= df['sex'].map({'female':0, 'male': 1}).astype(int)
    x_OneHot_df = pd.get_dummies(data=df,columns=["embarked"])

    ndarray = x_OneHot_df.values
    Features = ndarray[:,1:]
    Label = ndarray[:,0]

    minmax_scale = preprocessing.MinMaxScaler(feature_range=(0, 1))
    scaledFeatures = minmax_scale.fit_transform(Features)    

    return scaledFeatures, Label

使用DataPreprocessing函数建立训练和测试数据集。

# 使用函数处理训练数据和测试数据
train_features, train_label = DataPreprocessing(train_df)
test_featres, test_label = DataPreprocessing(test_df)

查看生成好的数据集

train_features[100:102]
array([[0.        , 1.        , 0.56387684, 0.125     , 0.        ,
        0.0541074 , 1.        , 0.        , 0.        ],
       [0.        , 0.        , 0.39198663, 0.125     , 0.        ,
        0.26086743, 0.        , 0.        , 1.        ]])
train_label[100:102]
array([1., 1.])

3. 采用多层感知机模型进行预测

本节我们将建立多层感知机模型,对模型进行训练和评估,并预测泰坦尼克号上的一些游客生还概率。

3.1 模型建立

接下来我们需要利用keras建立多层感知机模型,模型一共包含一个输入层、两个隐藏层和一个输入层。

  • units各层神经元的个数
  • input_dim是出入层神经元的个数,9表示有9个特征字段
  • kernel_initializer是使用随机数分布初始化权重和偏差
  • activation表示激活函数,这边使用的都是relu和sigmoid
# 导入包
from keras.models import Sequential
from keras.layers import Dense,Dropout
# 使用顺序华的模型
model = Sequential()
# 建立输入层和隐藏层1。Dense神经网络层,Dense的特色完全连接所有上下层神经元
model.add(Dense(units=40,input_dim=9,
               kernel_initializer='uniform',
               activation='relu'))
# 建立隐藏层2
model.add(Dense(units=30,
               kernel_initializer='uniform',
               activation='relu'))
# 建立输出层
model.add(Dense(units=1,
               kernel_initializer='uniform',
               activation='sigmoid'))

model.summary()
Using TensorFlow backend.


Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 40)                400       
_________________________________________________________________
dense_2 (Dense)              (None, 30)                1230      
_________________________________________________________________
dense_3 (Dense)              (None, 1)                 31        
=================================================================
Total params: 1,661
Trainable params: 1,661
Non-trainable params: 0
_________________________________________________________________

1

3.2 开始训练

定义训练参数

  • x和y分别传入上小节建立好的train_features和train_label数据集
  • validation_split为设置训练集和验证集数据的划分比例
  • epoch为训练周期
  • batch_size为单次训练批次
  • verbose为显示训练的过程
# 验证集划分比例
VALIDATION_SPLIT = 0.1
# 训练周期
EPOCHS = 30
# 单批次数据量
BATCH_SIZE = 30
# 训练LOG打印形式
VERBOSE = 2
# 定义训练方式
model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
# 开始训练
train_history = model.fit(x=train_features, 
                          y=train_label, 
                          validation_split=VALIDATION_SPLIT, 
                          epochs=EPOCHS, 
                          batch_size=BATCH_SIZE, 
                          verbose=VERBOSE)
Train on 950 samples, validate on 106 samples
Epoch 1/30
 - 2s - loss: 0.6889 - acc: 0.6116 - val_loss: 0.6671 - val_acc: 0.7925
Epoch 2/30
 - 0s - loss: 0.6589 - acc: 0.6137 - val_loss: 0.5710 - val_acc: 0.7925
Epoch 3/30
 - 0s - loss: 0.5994 - acc: 0.6705 - val_loss: 0.4764 - val_acc: 0.8113
Epoch 4/30
 - 0s - loss: 0.5393 - acc: 0.7579 - val_loss: 0.4594 - val_acc: 0.8113
Epoch 5/30
 - 0s - loss: 0.5069 - acc: 0.7747 - val_loss: 0.4295 - val_acc: 0.8113
Epoch 6/30
 - 0s - loss: 0.4927 - acc: 0.7747 - val_loss: 0.4243 - val_acc: 0.8113
Epoch 7/30
 - 0s - loss: 0.4847 - acc: 0.7695 - val_loss: 0.4288 - val_acc: 0.8113
Epoch 8/30
 - 0s - loss: 0.4796 - acc: 0.7758 - val_loss: 0.4262 - val_acc: 0.8113
Epoch 9/30
 - 0s - loss: 0.4752 - acc: 0.7821 - val_loss: 0.4153 - val_acc: 0.8208
Epoch 10/30
 - 0s - loss: 0.4754 - acc: 0.7779 - val_loss: 0.4186 - val_acc: 0.8302
Epoch 11/30
 - 0s - loss: 0.4717 - acc: 0.7779 - val_loss: 0.4294 - val_acc: 0.8113
Epoch 12/30
 - 0s - loss: 0.4688 - acc: 0.7811 - val_loss: 0.4135 - val_acc: 0.8491
Epoch 13/30
 - 0s - loss: 0.4693 - acc: 0.7821 - val_loss: 0.4135 - val_acc: 0.8302
Epoch 14/30
 - 0s - loss: 0.4658 - acc: 0.7905 - val_loss: 0.4205 - val_acc: 0.8302
Epoch 15/30
 - 0s - loss: 0.4649 - acc: 0.7853 - val_loss: 0.4105 - val_acc: 0.8208
Epoch 16/30
 - 0s - loss: 0.4695 - acc: 0.7895 - val_loss: 0.4116 - val_acc: 0.8302
Epoch 17/30
 - 0s - loss: 0.4632 - acc: 0.7842 - val_loss: 0.4149 - val_acc: 0.8491
Epoch 18/30
 - 0s - loss: 0.4626 - acc: 0.7916 - val_loss: 0.4166 - val_acc: 0.8396
Epoch 19/30
 - 0s - loss: 0.4618 - acc: 0.7916 - val_loss: 0.4131 - val_acc: 0.8396
Epoch 20/30
 - 0s - loss: 0.4597 - acc: 0.7895 - val_loss: 0.4117 - val_acc: 0.8491
Epoch 21/30
 - 0s - loss: 0.4576 - acc: 0.7916 - val_loss: 0.4115 - val_acc: 0.8491
Epoch 22/30
 - 0s - loss: 0.4576 - acc: 0.7884 - val_loss: 0.4119 - val_acc: 0.8491
Epoch 23/30
 - 0s - loss: 0.4573 - acc: 0.7916 - val_loss: 0.4158 - val_acc: 0.8491
Epoch 24/30
 - 0s - loss: 0.4558 - acc: 0.7947 - val_loss: 0.4136 - val_acc: 0.8491
Epoch 25/30
 - 0s - loss: 0.4556 - acc: 0.7874 - val_loss: 0.4109 - val_acc: 0.8396
Epoch 26/30
 - 0s - loss: 0.4577 - acc: 0.7958 - val_loss: 0.4163 - val_acc: 0.8491
Epoch 27/30
 - 0s - loss: 0.4534 - acc: 0.7905 - val_loss: 0.4111 - val_acc: 0.8491
Epoch 28/30
 - 0s - loss: 0.4551 - acc: 0.7863 - val_loss: 0.4172 - val_acc: 0.8491
Epoch 29/30
 - 0s - loss: 0.4532 - acc: 0.7968 - val_loss: 0.4168 - val_acc: 0.8113
Epoch 30/30
 - 0s - loss: 0.4576 - acc: 0.7884 - val_loss: 0.4185 - val_acc: 0.8491

定义绘制函数,绘制出训练结果

import matplotlib.pyplot as plt
def show_train_history(train_history,train,validation):
    plt.plot(train_history.history[train])
    plt.plot(train_history.history[validation])
    plt.title('Train histoty')
    plt.ylabel(train)
    plt.xlabel('Epoch')
    plt.legend(['train','validation',],loc = 'upper left')
    plt.show()
# 显示训练准确率
show_train_history(train_history,'acc','val_acc')

png

通过上面的图像可以发现经过30个周期的训练,训练过程中的准确率和验证准确率都是在提升的。

# 显示训练误差率
show_train_history(train_history,'loss','val_loss')

png

通过上面的图像可以发现经过30个周期的训练,训练过程中的误差率和验证误差率都是在下降的。

3.2 模型评估

利用训练好的模型使用测试集进行模型的评估,分数越高表示训练结果越好

# 评估模型准确率
scores = model.evaluate(x=test_featres,y=test_label,verbose=1)
scores[1]
253/253 [==============================] - 0s 66us/step





0.8102766807842632

在测试中评估结果,可以看到达到了0.81的分数。

3.3 构建自由数据进行预测

我们可以根据电影《泰坦尼克号》中的男女主角,Jack和Rose来进行构建相似的人设,并使用训练好的模型进行生还概率的预测。根据电影的剧情,我们自己构想并建立数据。

  • jack:3等舱、男性、23岁、票价10元
  • rose:头等舱、女性、20岁、票价120元
# 建立好模型后,我们将电影《泰坦尼克号》中jack和rose的数据加入试试效果
# jack是3等舱,男性,23岁,票价20
# rose是头等舱,女性,20岁,票价100
Jack = pd.Series([0, 'Jack', 3, 'male', 23 , 1, 0, 10.000, 'S'])
Rose = pd.Series([1, 'Rose', 1, 'female', 20, 1, 0, 120.000, 'S'])
# 将数据格式化
JR_df = pd.DataFrame([list(Jack),list(Rose)],
                    columns= ['survived', 'name', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'fare', 'embarked'])
all_df = pd.concat( [all_df , JR_df] ,sort=False)

查看构建完成的数据

JR_df
survived name pclass sex age sibsp parch fare embarked
0 0 Jack 3 male 23 1 0 10.0 S
1 1 Rose 1 female 20 1 0 120.0 S

预处理数据

features, label = DataPreprocessing(all_df)
features[-2:]
array([[1.        , 1.        , 0.28601223, 0.125     , 0.        ,
        0.0195187 , 0.        , 0.        , 1.        ],
       [0.        , 0.        , 0.24843392, 0.125     , 0.        ,
        0.2342244 , 0.        , 0.        , 1.        ]])

对数据进行预测,并查看Jack和Rose的预测结果的数据

result = model.predict(features)
result[-2:]
array([[0.15587816],
       [0.9679635 ]], dtype=float32)

可以看到Jack的生还概率只有0.15,而Rose的生还概率却高达0.96,结果还是和电影中的结果是相符合的。

结论

我们本章学习了如何处理泰坦尼克号的数据集和搭建多层感知机模型进行游客生还概率的预测,泰坦尼克号数据集中还包含了许多隐藏的故事,是冰冷的数据无法呈现出来的,例如有些游客生还预测高达0.9以上,但是因为想挽救手足或双亲或者陪伴自己的宠物,却还是不幸遇害,有些乘客是生还率只有0.1的小婴儿,却有幸存活。这些特别的数据背后存在着许多感人的故事和令人惊奇的误会事件,需要具体了解的同学可以自行分析数据,并挖掘出背后的故事,本章不过多阐述。


版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:http://tunm.top/article/learning_08/