Loading

1-1结构化数据建模流程范例 ——eat_tensorflow2_in_30_days

1-1结构化数据建模流程范例

准备数据

titanic数据集的目标是根据乘客信息预测他们在Titanic号撞击冰山沉没后能否生存。
结构化数据一般会使用Pandas中的DataFrame进行预处理。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import models, layers


dftrain_raw = pd.read_csv('./data/titanic/train.csv')
dftest_raw = pd.read_csv('./data/titanic/test.csv')
dftrain_raw.head(10)

字段说明:

  • Survived:0代表死亡,1代表存活【y标签】
  • Pclass:乘客所持票类,有三种值(1,2,3) 【转换成onehot编码】
  • Name:乘客姓名 【舍去】
  • Sex:乘客性别 【转换成bool特征】
  • Age:乘客年龄(有缺失) 【数值特征,添加“年龄是否缺失”作为辅助特征】
  • SibSp:乘客兄弟姐妹/配偶的个数(整数值) 【数值特征】
  • Parch:乘客父母/孩子的个数(整数值)【数值特征】
  • Ticket:票号(字符串)【舍去】
  • Fare:乘客所持票的价格(浮点数,0-500不等) 【数值特征】
  • Cabin:乘客所在船舱(有缺失) 【添加“所在船舱是否缺失”作为辅助特征】
  • Embarked:乘客登船港口:S、C、Q(有缺失)【转换成onehot编码,四维度 S,C,Q,nan】
  • 利用Pandas的数据可视化功能我们可以简单地进行探索性数据分析EDA(Exploratory Data Analysis)。
%matplotlib inline
%config InlineBackend.figure_format = 'png'
# label分布情况
ax = dftrain_raw['Survived'].value_counts().plot(kind='bar', 
                                                figsize=(12, 8), fontsize=15, rot=0)
ax.set_ylabel('Counts', fontsize=15)
ax.set_xlabel('Survived', fontsize=15)
plt.show()

# 年龄分布情况
%matplotlib inline
%config InlineBackend.figure_format='png'
ax = dftrain_raw['Age'].plot(kind='hist', bins=20, color='purple', figsize=(12, 8), fontsize=15)
ax.set_ylabel('Frequency', fontsize=15)
ax.set_xlabel('Age', fontsize=15)
plt.show()

# 年龄和label的相关性
ax = dftrain_raw.query('Survived == 0')['Age'].plot(kind='density', figsize=(12, 8), fontsize=15)
dftrain_raw.query('Survived == 1')['Age'].plot(kind='density', figsize=(12, 8), fontsize=15)
ax.legend(['Survived==0', 'Survived==1'], fontsize=12)
ax.set_ylabel('Density', fontsize=15)
ax.set_xlabel('Age', fontsize=15)
plt.show()

  • 数据预处理
def preprocessing(dfdata):
    dfresult = pd.DataFrame()
    
    # Pclass
    dfPclass = pd.get_dummies(dfdata['Pclass'])
    dfPclass.columns = ['Pclass_' + str(x) for x in dfPclass.columns]
    dfresult = pd.concat([dfresult, dfPclass], axis=1)
    
    # Sex
    dfSex = pd.get_dummies(dfdata['Sex'])
    dfresult = pd.concat([dfresult, dfSex], axis=1)
    
    # Age
    dfresult['Age'] = dfdata['Age'].fillna(0)
    dfresult['Age_null'] = pd.isna(dfdata['Age']).astype('int32')
    
    # SibSp, Parch, Fare
    dfresult['SibSp'] = dfdata['SibSp']
    dfresult['Parch'] = dfdata['Parch']
    dfresult['Fare'] = dfdata['Fare']
    
    # Carbin
    dfresult['Cabin_null'] = pd.isna(dfdata['Cabin']).astype('int32')
    
    # Embarked
    dfEmbarked = pd.get_dummies(dfdata['Embarked'], dummy_na=True)
    dfEmbarked.columns = ['Embarked_' + str(x) for x in dfEmbarked.columns]
    dfresult = pd.concat([dfresult, dfEmbarked], axis=1)
    
    return dfresult

x_train = preprocessing(dftrain_raw)
y_train = dftrain_raw['Survived'].values

x_test = preprocessing(dftest_raw)
y_test = dftest_raw['Survived'].values

print("x_train.shape=", x_train.shape)
print("x_test.shape=", x_test.shape)

"""
def preprocessing(dfdata):

    dfresult = pd.DataFrame()

    

    # Pclass

    dfPclass = pd.get_dummies(dfdata['Pclass'])

    dfPclass.columns = ['Pclass_' + str(x) for x in dfPclass.columns]

    dfresult = pd.concat([dfresult, dfPclass], axis=1)

    

    # Sex

    dfSex = pd.get_dummies(dfdata['Sex'])

    dfresult = pd.concat([dfresult, dfSex], axis=1)

    

    # Age

    dfresult['Age'] = dfdata['Age'].fillna(0)

    dfresult['Age_null'] = pd.isna(dfdata['Age']).astype('int32')

    

    # SibSp, Parch, Fare

    dfresult['SibSp'] = dfdata['SibSp']

    dfresult['Parch'] = dfdata['Parch']

    dfresult['Fare'] = dfdata['Fare']

    

    # Carbin

    dfresult['Cabin_null'] = pd.isna(dfdata['Cabin']).astype('int32')

    

    # Embarked

    dfEmbarked = pd.get_dummies(dfdata['Embarked'], dummy_na=True)

    dfEmbarked.columns = ['Embarked_' + str(x) for x in dfEmbarked.columns]

    dfresult = pd.concat([dfresult, dfEmbarked], axis=1)

    

    return dfresult

​

x_train = preprocessing(dftrain_raw)

y_train = dftrain_raw['Survived'].values

​

x_test = preprocessing(dftest_raw)

y_test = dftest_raw['Survived'].values

​

print("x_train.shape=", x_train.shape)

print("x_test.shape=", x_test.shape)

x_train.shape= (712, 15)
x_test.shape= (179, 15)
"""

定义模型

使用Keras接口有以下3种方式构建模型:使用Sequential按层顺序构建模型,使用函数式API构建任意结构模型,继承Model基类构建自定义模型。
此处选择使用最简单的Sequential,按层顺序模型。

tf.keras.backend.clear_session()

model = tf.keras.models.Sequential([
    layers.Dense(20, activation='relu', input_shape=(15,)),
    layers.Dense(10, activation='relu'),
    layers.Dense(1, activation='sigmoid')
])
model.summary()

"""
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense (Dense)               (None, 20)                320       
                                                                 
 dense_1 (Dense)             (None, 10)                210       
                                                                 
 dense_2 (Dense)             (None, 1)                 11        
                                                                 
=================================================================
Total params: 541
Trainable params: 541
Non-trainable params: 0
_________________________________________________________________
"""

训练模型

训练模型通常有3种方法,内置fit方法,内置train_on_batch方法,以及自定义训练循环。此处我们选择最常用也最简单的内置fit方法。

# 二分类问题选择二元交叉熵损失函数
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['AUC'])
history = model.fit(x_train, y_train, batch_size=64, epochs=30, validation_split=0.2)  # 分割 一部分数据用于验证

评估模型

我们首先评估一下模型在训练集和验证集上的效果。

%matplotlib inline
%config InlineBackend.figure_format='svg'

def plot_metric(history, metric):
    train_metrics = history.history[metric]
    val_metrics = history.history['val_'+metric]
    epochs = range(1, len(train_metrics)+1)
    plt.plot(epochs, train_metrics, 'bo--')
    plt.plot(epochs, val_metrics, 'ro-')
    plt.title('Training and validation' + metric)
    plt.xlabel('Epochs')
    plt.ylabel(metric)
    plt.legend(['train_'+metric, 'val_'+metric])
    plt.show()
plot_metric(history, 'loss')

plot_metric(history, 'auc')

我们再看一下模型在测试集上的效果.

model.evaluate(x=x_test, y=y_test)

"""
6/6 [==============================] - 0s 1ms/step - loss: 0.5240 - auc: 0.8050

[0.52403324842453, 0.8050082325935364]
"""

使用模型

# 预测概率
model.predict(x_test[0: 10])

"""
array([[0.12006765],
       [0.42072523],
       [0.4267687 ],
       [0.85354537],
       [0.5159656 ],
       [0.43939105],
       [0.11880974],
       [0.7531639 ],
       [0.41171274],
       [0.19604053]], dtype=float32)
"""
# 预测类别
(model.predict(x_test[0: 10])>0.5).astype(np.int32)

"""
array([[0],
       [0],
       [0],
       [1],
       [1],
       [0],
       [0],
       [1],
       [0],
       [0]], dtype=int32)
"""

保存模型

可以使用Keras方式保存模型,也可以使用TensorFlow原生方式保存。

  • 前者仅仅适合使用Python环境恢复模型;
  • 后者则可以跨平台进行模型部署。
    推荐使用后一种方式进行保存。
  • Keras方式保存
model.save('./data/keras_model.h5')

del model

# identical to the previous one
model = models.load_model('./data/keras_model.h5')
model.evaluate(x_test, y_test)

"""
6/6 [==============================] - 0s 1ms/step - loss: 0.5240 - auc: 0.8050

[0.52403324842453, 0.8050082325935364]
"""
# 保存模型结构
json_str = model.to_json()

# 恢复模型结构
model_json = models.model_from_json(json_str)

# 保存模型权重
model.save_weights('./data/keras_model_weight.h5')

# 恢复模型结构
model_json = models.model_from_json(json_str)
model_json.compile(optimizer='adam', loss='binary_crossentropy', metrics=['AUC'])

# 加载权重
model_json.load_weights('./data/keras_model_weight.h5')
model_json.evaluate(x_test, y_test)

"""
6/6 [==============================] - 0s 1ms/step - loss: 0.5240 - auc: 0.8050

[0.52403324842453, 0.8050082325935364]
"""
  • TensorFlow原生方式保存
# 保存权重,该方式仅保存权重张量
model.save_weights('./data/tf_model_weights.ckpt', save_format='tf')

# 保存模型结构与模型参数到文件,该方式保存的模型具有跨平台性便于部署
model.save('./data/tf_model_savedmodel', save_format='tf')
print('export saved model')

model_loaded = tf.keras.models.load_model('./data/tf_model_savedmodel/')
model_loaded.evaluate(x_test, y_test)

"""
export saved model
6/6 [==============================] - 1s 1ms/step - loss: 0.5240 - auc: 0.8050

[0.52403324842453, 0.8050082325935364]
"""
posted @ 2022-07-17 00:40  lotuslaw  阅读(66)  评论(0编辑  收藏  举报