本文正在参与「金石方案 . 瓜分6万现金大奖」
前言
本文主要是运用 cpu 版本的 tensorflow 2.4 完成对 Titanic 乘客的救援猜测使命。咱们用到的数据是 Titanic 乘客数据,先建立深度学习模型,模型会依据乘客的年龄、性别、舱室等特征来猜测乘客被救援生还的可能性。
本文纲要
- 获取 Titanic 数据
- 处理特征数据
- 建立、编译、练习模型
- 评价模型
- 运用模型猜测
完成进程
1. 获取 Titanic 数据
(1)本文的用到的 Titanic 数据需要运用 tensorflow 的内置函数从网络上进行下载,下载好的数据一般会放在主用户目录下面的 .keras/datasets 文件见之内,咱们能够发现多了一个 train.csv 和一个 eval.csv 。
(2)需要注意的是这儿的 train_file_path 和 test_file_path 变量中保存的便是下载好的练习数据和测试数据分别在本地磁盘的绝对路径。
(3)这儿为了方便用户阅览,咱们运用了 set_printoptions 将数据集中的浮点数都只保存 3 位小数,而且对极大/极小数不运用科学计数法。
import functools
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
train_filePath = tf.keras.utils.get_file("train.csv", "https://storage.googleapis.com/tf-datasets/titanic/train.csv")
test_filePath = tf.keras.utils.get_file("eval.csv", "https://storage.googleapis.com/tf-datasets/titanic/eval.csv")
np.set_printoptions(precision=3, suppress=True)
(4)经过观察数据咱们数据中榜首列 survived 是标签表明该乘客是否能被获救,后面列都是特征,包含 sex、age、n_siblings_spouses、parch、are、class、deck、embark_town、alone 。
! head -n 3 {train_filePath}
输出成果:
survived,sex,age,n_siblings_spouses,parch,fare,class,deck,embark_town,alone
0,male,22.0,1,0,7.25,Third,unknown,Southampton,n
1,female,38.0,1,0,71.2833,First,C,Cherbourg,n
2. 处理特征数据
(1)由于咱们现在只是得到了练习数据文件和测试数据文件的绝对路径,所以咱们要经过 tensorflow 内置函数 make_csv_dataset ,从指定的 csv 文件中加载数据,该函数会将指定文件中的一切列数据都加载。
(2)咱们将 batch_size 设置为 32 ,也便是说 train_data 或者 test_data 中的一个目标包含的便是一个 batch_size 大小的特征值和标签,将数据的标签设置为 survived 列,也便是其他列是特征,而且对于空值都设置为“?”字符串。
def get_dataset(filePath):
dataset = tf.data.experimental.make_csv_dataset( filePath,
batch_size=32,
label_name='survived',
na_value="?",
num_epochs=1,
ignore_errors=True,
shuffle=False)
return dataset
train_data = get_dataset(train_filePath).shuffle(500)
test_data = get_dataset(test_filePath)
(3)由于有些特征列的值都是离散的,比方 sex、class、deck、embark_town、alone 等,咱们运用变量 d 保存了对应列中的离散值,然后运用函数 categorical_column_with_vocabulary_list 和 indicator_column 将它们转换成可用的形式。
d = {
'sex': ['male', 'female'],
'class' : ['First', 'Second', 'Third'],
'deck' : ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
'embark_town' : ['Cherbourg', 'Southhampton', 'Queenstown'],
'alone' : ['y', 'n']
}
cls_cols = []
for k, v in d.items():
col = tf.feature_column.categorical_column_with_vocabulary_list(key=k, vocabulary_list=v)
cls_cols.append(tf.feature_column.indicator_column(col))
(4)由于有些特征列的值都是连续值,比方 age、 n_siblings_spouses、parch、fare ,所以咱们要先将它们进行标准化,而且从一维转换成二维向量。这儿咱们用 means 保存每一列的平均值,在进行 process 标准化核算的时候能够直接拿来用。需要运用函数 numeric_column 将它们转换成可用的形式。
def process(mean, data):
data = tf.cast(data, tf.float32) * 1/(2*mean)
return tf.reshape(data, [-1, 1])
means = {'age' : 29.631308,
'n_siblings_spouses' : 0.545455,
'parch' : 0.379585,
'fare' : 34.385399}
num_cols = []
for f in means.keys():
num_col = tf.feature_column.numeric_column(f, normalizer_fn=functools.partial(process, means[f]))
num_cols.append(num_col)
3. 建立、编译、练习模型
(1)榜首层是将一切的特征拼接起来,运用 DenseFeatures 创立一个进行预处理的输入层。
(2)第二层是一个输出 256 维向量的全衔接层,并运用了激活函数 relu 进行非线性改变。
(3)第三层是一个输出 128 维向量的全衔接层,并运用了激活函数 relu 进行非线性改变。
(4)第四层是一个输出 1 维向量的全衔接输出层,并运用了激活函数 sigmoid ,这其实便是输出该乘客被救的概率。
(5)挑选丢失值为 binary_crossentropy 。
(6)挑选优化器为 adam 。
(7)挑选评价指标为 accuracy 。
(8)运用练习数据练习 20 个 epoch 。
model = tf.keras.Sequential([ tf.keras.layers.DenseFeatures(cls_cols + num_cols),
tf.keras.layers.Dense(256, activation='relu'),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')])
model.compile( loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(train_data, epochs=20, verbose=2)
练习进程如下:
Epoch 1/20
20/20 - 1s - loss: 0.5738 - accuracy: 0.7560
Epoch 2/20
20/20 - 0s - loss: 0.4440 - accuracy: 0.8086
...
Epoch 20/20
20/20 - 0s - loss: 0.3313 - accuracy: 0.8612
4. 评价模型
运用测试数据对练习好的模型进行指标评价。
test_loss, test_accuracy = model.evaluate(test_data)
print('\n测试数据的 Loss 为 {}, Accuracy 为 {}'.format(test_loss, test_accuracy))
输出成果为:
测试数据的 Loss 为 0.4356554448604584, Accuracy 为 0.8295454382896423
5. 运用模型猜测
取出前 5 条测试数据进行救援概率的猜测。
predictions = model.predict(test_data)
for prediction, survived in zip(predictions[:5], list(test_data)[0][1][:5]):
print("猜测的获救概率为: {:.2%}".format(prediction[0]),
",实际情况该乘客: ",
("被救" if bool(survived) else "逝世"))
成果输出为:
猜测的获救概率为: 8.64% ,实际情况该乘客: 逝世
猜测的获救概率为: 45.76% ,实际情况该乘客: 逝世
猜测的获救概率为: 82.74% ,实际情况该乘客: 被救
猜测的获救概率为: 64.96% ,实际情况该乘客: 被救
猜测的获救概率为: 3.34% ,实际情况该乘客: 被救