在 TensorFlow.org 上查看
|
在 Google Colab 中运行
|
在 GitHub 上查看源码
|
下载笔记本
|
概览
本端到端演练使用 tf.estimator API 训练逻辑回归模型。该模型通常用作其他更复杂算法的基准。
设置
pip install sklearnimport os
import sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import clear_output
from six.moves import urllib
加载泰坦尼克号数据集
你将使用泰坦尼克号数据集,目标(虽然有些令人伤感)是根据乘客的性别、年龄、舱位等特征来预测其生存情况。
import tensorflow.compat.v2.feature_column as fc
import tensorflow as tf
# Load dataset.
dftrain = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/train.csv')
dfeval = pd.read_csv('https://storage.googleapis.com/tf-datasets/titanic/eval.csv')
y_train = dftrain.pop('survived')
y_eval = dfeval.pop('survived')
探索数据
该数据集包含以下特征
dftrain.head()
dftrain.describe()
训练集和评估集分别包含 627 条和 264 条数据。
dftrain.shape[0], dfeval.shape[0]
大多数乘客的年龄在 20 多岁和 30 多岁。
dftrain.age.hist(bins=20)
船上的男性乘客人数大约是女性乘客的两倍。
dftrain.sex.value_counts().plot(kind='barh')
大多数乘客位于“三等舱”。
dftrain['class'].value_counts().plot(kind='barh')
女性的生还几率远高于男性。这显然是该模型的一个重要预测特征。
pd.concat([dftrain, y_train], axis=1).groupby('sex').survived.mean().plot(kind='barh').set_xlabel('% survive')
模型特征工程
Estimators 使用一种称为特征列 (feature columns) 的系统来描述模型应如何解析每个原始输入特征。Estimator 需要数值输入向量,而特征列描述了模型应如何转换每个特征。
选择和构建合适的特征列集是学习有效模型的关键。特征列可以是原始特征 dict 中的某个原始输入(基础特征列),也可以是使用在一个或多个基础列上定义的转换所创建的新列(派生特征列)。
线性估计器使用数值特征和分类特征。特征列适用于所有 TensorFlow 估计器,其目的是定义用于建模的特征。此外,它们还提供了一些特征工程功能,如独热编码 (one-hot-encoding)、归一化和分桶 (bucketization)。
基础特征列
CATEGORICAL_COLUMNS = ['sex', 'n_siblings_spouses', 'parch', 'class', 'deck',
'embark_town', 'alone']
NUMERIC_COLUMNS = ['age', 'fare']
feature_columns = []
for feature_name in CATEGORICAL_COLUMNS:
vocabulary = dftrain[feature_name].unique()
feature_columns.append(tf.feature_column.categorical_column_with_vocabulary_list(feature_name, vocabulary))
for feature_name in NUMERIC_COLUMNS:
feature_columns.append(tf.feature_column.numeric_column(feature_name, dtype=tf.float32))
input_function 指定了如何将数据转换为以流式方式馈送输入流水线的 tf.data.Dataset。tf.data.Dataset 可以接收多种源,例如数据帧 (dataframe)、CSV 格式文件等。
def make_input_fn(data_df, label_df, num_epochs=10, shuffle=True, batch_size=32):
def input_function():
ds = tf.data.Dataset.from_tensor_slices((dict(data_df), label_df))
if shuffle:
ds = ds.shuffle(1000)
ds = ds.batch(batch_size).repeat(num_epochs)
return ds
return input_function
train_input_fn = make_input_fn(dftrain, y_train)
eval_input_fn = make_input_fn(dfeval, y_eval, num_epochs=1, shuffle=False)
你可以查看数据集
ds = make_input_fn(dftrain, y_train, batch_size=10)()
for feature_batch, label_batch in ds.take(1):
print('Some feature keys:', list(feature_batch.keys()))
print()
print('A batch of class:', feature_batch['class'].numpy())
print()
print('A batch of Labels:', label_batch.numpy())
你也可以使用 tf.keras.layers.DenseFeatures 层来查看特定特征列的结果
age_column = feature_columns[7]
tf.keras.layers.DenseFeatures([age_column])(feature_batch).numpy()
DenseFeatures 仅接受稠密张量。要查看分类列,你需要先将其转换为指示列 (indicator column)
gender_column = feature_columns[0]
tf.keras.layers.DenseFeatures([tf.feature_column.indicator_column(gender_column)])(feature_batch).numpy()
将所有基础特征添加到模型后,让我们开始训练模型。使用 tf.estimator API 训练模型只需一条命令
linear_est = tf.estimator.LinearClassifier(feature_columns=feature_columns)
linear_est.train(train_input_fn)
result = linear_est.evaluate(eval_input_fn)
clear_output()
print(result)
派生特征列
现在你达到了 75% 的准确率。单独使用每个基础特征列可能不足以解释数据。例如,年龄与标签之间的相关性在不同性别下可能不同。因此,如果你只为 gender="Male" 和 gender="Female" 学习单一的模型权重,将无法捕获所有年龄-性别组合(例如,无法区分 gender="Male" 且 age="30" 与 gender="Male" 且 age="40" 的区别)。
为了学习不同特征组合之间的差异,你可以向模型添加交叉特征列 (crossed feature columns)(你也可以在交叉列之前对年龄列进行分桶处理)
age_x_gender = tf.feature_column.crossed_column(['age', 'sex'], hash_bucket_size=100)
添加组合特征后,让我们再次训练模型
derived_feature_columns = [age_x_gender]
linear_est = tf.estimator.LinearClassifier(feature_columns=feature_columns+derived_feature_columns)
linear_est.train(train_input_fn)
result = linear_est.evaluate(eval_input_fn)
clear_output()
print(result)
现在准确率达到了 77.6%,比仅使用基础特征训练的结果略有提升。你可以尝试使用更多特征和转换,看看能否取得更好的效果!
现在你可以使用训练好的模型对评估集中的乘客进行预测。TensorFlow 模型已针对批量或一次性预测一组样本进行了优化。之前,eval_input_fn 是使用整个评估集定义的。
pred_dicts = list(linear_est.predict(eval_input_fn))
probs = pd.Series([pred['probabilities'][1] for pred in pred_dicts])
probs.plot(kind='hist', bins=20, title='predicted probabilities')
最后,查看结果的接收者操作特征 (ROC) 曲线,这将使我们更好地了解真阳性率与假阳性率之间的权衡。
from sklearn.metrics import roc_curve
from matplotlib import pyplot as plt
fpr, tpr, _ = roc_curve(y_eval, probs)
plt.plot(fpr, tpr)
plt.title('ROC curve')
plt.xlabel('false positive rate')
plt.ylabel('true positive rate')
plt.xlim(0,)
plt.ylim(0,)
在 TensorFlow.org 上查看
在 Google Colab 中运行
在 GitHub 上查看源码
下载笔记本