Постройте линейную модель с помощью Estimators

Посмотреть на TensorFlow.org Запустить в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

Обзор

Это сквозное пошаговое руководство обучает модель логистической регрессии с помощью API tf.estimator . Модель часто используется в качестве основы для других, более сложных алгоритмов.

Настраивать

pip install sklearn
import 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]
(627, 264)

Большинству пассажиров от 20 до 30 лет.

dftrain.age.hist(bins=20)
<AxesSubplot:>

png

На борту пассажиров-мужчин примерно в два раза больше, чем пассажиров-женщин.

dftrain.sex.value_counts().plot(kind='barh')
<AxesSubplot:>

png

Большинство пассажиров были в «третьем» классе.

dftrain['class'].value_counts().plot(kind='barh')
<AxesSubplot:>

png

У самок гораздо больше шансов выжить, чем у самцов. Это явно прогностическая особенность модели.

pd.concat([dftrain, y_train], axis=1).groupby('sex').survived.mean().plot(kind='barh').set_xlabel('% survive')
Text(0.5, 0, '% survive')

png

Разработка функций для модели

Оценщики используют систему, называемую столбцами признаков , для описания того, как модель должна интерпретировать каждый из необработанных входных признаков. Оценщик ожидает вектор числовых входных данных, а столбцы функций описывают, как модель должна преобразовывать каждую функцию.

Выбор и создание правильного набора столбцов функций является ключом к изучению эффективной модели. Столбец признаков может быть либо одним из необработанных входных данных в исходном dict признаков ( базовый столбец признаков ), либо любыми новыми столбцами, созданными с использованием преобразований, определенных для одного или нескольких базовых столбцов (столбцы производных признаков ).

Линейная оценка использует как числовые, так и категориальные признаки. Столбцы функций работают со всеми оценщиками TensorFlow, и их цель — определить функции, используемые для моделирования. Кроме того, они предоставляют некоторые возможности разработки функций, такие как однократное горячее кодирование, нормализация и сегментация.

Столбцы базовых функций

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 может принимать несколько источников, таких как фрейм данных, файл в формате 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())
Some feature keys: ['sex', 'age', 'n_siblings_spouses', 'parch', 'fare', 'class', 'deck', 'embark_town', 'alone']

A batch of class: [b'Third' b'Third' b'Third' b'Third' b'Third' b'First' b'Second' b'First'
 b'First' b'Third']

A batch of Labels: [0 1 1 0 0 1 0 1 1 0]

Вы также можете проверить результат определенного столбца объектов, используя слой tf.keras.layers.DenseFeatures :

age_column = feature_columns[7]
tf.keras.layers.DenseFeatures([age_column])(feature_batch).numpy()
array([[35.],
       [14.],
       [28.],
       [19.],
       [28.],
       [35.],
       [60.],
       [63.],
       [45.],
       [21.]], dtype=float32)

DenseFeatures принимает только плотные тензоры, чтобы проверить категориальный столбец, вам нужно сначала преобразовать его в столбец индикатора:

gender_column = feature_columns[0]
tf.keras.layers.DenseFeatures([tf.feature_column.indicator_column(gender_column)])(feature_batch).numpy()
array([[1., 0.],
       [0., 1.],
       [0., 1.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [1., 0.],
       [0., 1.],
       [0., 1.],
       [0., 1.]], dtype=float32)

После добавления всех базовых функций в модель давайте обучим модель. Обучение модели — это всего лишь одна команда с использованием API tf.estimator :

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)
{'accuracy': 0.7537879, 'accuracy_baseline': 0.625, 'auc': 0.8060607, 'auc_precision_recall': 0.7480768, 'average_loss': 0.5639972, 'label/mean': 0.375, 'loss': 0.5542658, 'precision': 0.7741935, 'prediction/mean': 0.25232768, 'recall': 0.4848485, 'global_step': 200}

Столбцы производных признаков

Теперь вы достигли точности 75%. Использование каждого столбца базовых функций по отдельности может оказаться недостаточным для объяснения данных. Например, корреляция между возрастом и меткой может быть разной для разных полов. Таким образом, если вы узнаете только вес одной модели для gender="Male" и gender="Female" , вы не сможете зафиксировать каждую комбинацию возраста и пола (например, различать gender="Male" И age="30" И gender="Male" ). gender="Male" И age="40" ).

Чтобы изучить различия между различными комбинациями признаков, вы можете добавить в модель столбцы перекрестных признаков (вы также можете разбить столбец возраста перед столбцом перекрестных столбцов):

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)
{'accuracy': 0.7462121, 'accuracy_baseline': 0.625, 'auc': 0.845577, 'auc_precision_recall': 0.7873878, 'average_loss': 0.47313985, 'label/mean': 0.375, 'loss': 0.46722567, 'precision': 0.6509434, 'prediction/mean': 0.41550797, 'recall': 0.6969697, 'global_step': 200}

Теперь он достигает точности 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')
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpe5vngw46/model.ckpt-200
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.
<AxesSubplot:title={'center':'predicted probabilities'}, ylabel='Frequency'>

png

Наконец, взгляните на рабочие характеристики приемника (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,)
(0.0, 1.05)

png