Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Árboles potenciados mediante estimadores

Ver en TensorFlow.org Ejecutar en Google Colab Ver fuente en GitHub Descargar cuaderno

Este tutorial es un tutorial completo sobre el entrenamiento de un modelo de tf.estimator gradiente mediante árboles de decisión con la API tf.estimator . Los modelos Boosted Trees se encuentran entre los enfoques de aprendizaje automático más populares y efectivos tanto para la regresión como para la clasificación. Es una técnica de conjunto que combina las predicciones de varios modelos de árbol (piense en diez, cien o incluso mil).

Los modelos Boosted Trees son populares entre muchos profesionales del aprendizaje automático, ya que pueden lograr un rendimiento impresionante con un ajuste mínimo de hiperparámetros.

Cargue el conjunto de datos titánico

Utilizará el conjunto de datos titánico, donde el objetivo (bastante morboso) es predecir la supervivencia de los pasajeros, dadas características como sexo, edad, clase, etc.

import numpy as np
import pandas as pd
from IPython.display import clear_output
from matplotlib import pyplot as plt

# 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')
import tensorflow as tf
tf.random.set_seed(123)

El conjunto de datos consta de un conjunto de entrenamiento y un conjunto de evaluación:

  • dftrain e y_train son el conjunto de entrenamiento , los datos que el modelo usa para aprender.
  • El modelo se prueba con eval set , dfeval y y_eval .

Para la formación, utilizará las siguientes funciones:

Nombre de la función Descripción
sexo Género del pasajero
años Edad del pasajero
n_siblings_spouses hermanos y socios a bordo
tostar de padres e hijos a bordo
tarifa Pasajero de tarifa pagada.
clase Clase de pasajero en barco
cubierta En que pasajero de cubierta estaba
embark_town De qué ciudad se embarcó el pasajero
solo Si el pasajero estuviera solo

Explore los datos

Primero, obtengamos una vista previa de algunos de los datos y creemos estadísticas resumidas sobre el conjunto de entrenamiento.

dftrain.head()
dftrain.describe()

Hay 627 y 264 ejemplos en los conjuntos de capacitación y evaluación, respectivamente.

dftrain.shape[0], dfeval.shape[0]
(627, 264)

La mayoría de los pasajeros tienen entre 20 y 30 años.

dftrain.age.hist(bins=20)
plt.show()

png

Hay aproximadamente el doble de pasajeros hombres que mujeres a bordo.

dftrain.sex.value_counts().plot(kind='barh')
plt.show()

png

La mayoría de los pasajeros estaban en la "tercera" clase.

dftrain['class'].value_counts().plot(kind='barh')
plt.show()

png

La mayoría de los pasajeros se embarcaron en Southampton.

dftrain['embark_town'].value_counts().plot(kind='barh')
plt.show()

png

Las hembras tienen muchas más posibilidades de sobrevivir que los machos. Esta será claramente una característica predictiva para el modelo.

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

png

Cree columnas de características y funciones de entrada

El estimador Gradient Boosting puede utilizar características tanto numéricas como categóricas. Las columnas de características funcionan con todos los estimadores de TensorFlow y su propósito es definir las características que se utilizan para el modelado. Además, brindan algunas capacidades de ingeniería de características como codificación en caliente, normalización y agrupación. En este tutorial, los campos de CATEGORICAL_COLUMNS se transforman de columnas categóricas a columnas con codificación única ( columna indicadora ):

CATEGORICAL_COLUMNS = ['sex', 'n_siblings_spouses', 'parch', 'class', 'deck',
                       'embark_town', 'alone']
NUMERIC_COLUMNS = ['age', 'fare']

def one_hot_cat_column(feature_name, vocab):
  return tf.feature_column.indicator_column(
      tf.feature_column.categorical_column_with_vocabulary_list(feature_name,
                                                 vocab))
feature_columns = []
for feature_name in CATEGORICAL_COLUMNS:
  # Need to one-hot encode categorical features.
  vocabulary = dftrain[feature_name].unique()
  feature_columns.append(one_hot_cat_column(feature_name, vocabulary))

for feature_name in NUMERIC_COLUMNS:
  feature_columns.append(tf.feature_column.numeric_column(feature_name,
                                           dtype=tf.float32))

Puede ver la transformación que produce una columna de entidad. Por ejemplo, aquí está el resultado cuando se usa la indicator_column en un solo ejemplo:

example = dict(dftrain.head(1))
class_fc = tf.feature_column.indicator_column(tf.feature_column.categorical_column_with_vocabulary_list('class', ('First', 'Second', 'Third')))
print('Feature value: "{}"'.format(example['class'].iloc[0]))
print('One-hot encoded: ', tf.keras.layers.DenseFeatures([class_fc])(example).numpy())
Feature value: "Third"
One-hot encoded:  [[0. 0. 1.]]

Además, puede ver todas las transformaciones de columnas de entidades juntas:

tf.keras.layers.DenseFeatures(feature_columns)(example).numpy()
array([[22.  ,  1.  ,  0.  ,  1.  ,  0.  ,  0.  ,  1.  ,  0.  ,  0.  ,

         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  1.  ,  0.  ,  0.  ,  0.  ,
         7.25,  1.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  1.  ,
         0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  1.  ,  0.  ]], dtype=float32)

A continuación, debe crear las funciones de entrada. Estos especificarán cómo se leerán los datos en nuestro modelo tanto para el entrenamiento como para la inferencia. Utilizará el método from_tensor_slices en la API tf.data para leer datos directamente de Pandas. Esto es adecuado para conjuntos de datos en memoria más pequeños. Para conjuntos de datos más grandes, la API tf.data admite una variedad de formatos de archivo (incluido csv ) para que pueda procesar conjuntos de datos que no quepan en la memoria.

# Use entire batch since this is such a small dataset.
NUM_EXAMPLES = len(y_train)

def make_input_fn(X, y, n_epochs=None, shuffle=True):
  def input_fn():
    dataset = tf.data.Dataset.from_tensor_slices((dict(X), y))
    if shuffle:
      dataset = dataset.shuffle(NUM_EXAMPLES)
    # For training, cycle thru dataset as many times as need (n_epochs=None).
    dataset = dataset.repeat(n_epochs)
    # In memory training doesn't use batching.
    dataset = dataset.batch(NUM_EXAMPLES)
    return dataset
  return input_fn

# Training and evaluation input functions.
train_input_fn = make_input_fn(dftrain, y_train)
eval_input_fn = make_input_fn(dfeval, y_eval, shuffle=False, n_epochs=1)

Entrenar y evaluar el modelo

A continuación, realizará los siguientes pasos:

  1. Inicialice el modelo, especificando las características y los hiperparámetros.
  2. Alimente los datos de entrenamiento al modelo usando train_input_fn y entrene el modelo usando la función train .
  3. Evaluará el rendimiento del modelo utilizando el conjunto de evaluación; en este ejemplo, el dfeval dfeval. Verificará que las predicciones coincidan con las etiquetas de la matriz y_eval .

Antes de entrenar un modelo Boosted Trees, entrenemos primero un clasificador lineal (modelo de regresión logística). Es una buena práctica comenzar con un modelo más simple para establecer un punto de referencia.

linear_est = tf.estimator.LinearClassifier(feature_columns)

# Train model.
linear_est.train(train_input_fn, max_steps=100)

# Evaluation.
result = linear_est.evaluate(eval_input_fn)
clear_output()
print(pd.Series(result))
accuracy                  0.765152
accuracy_baseline         0.625000
auc                       0.832844
auc_precision_recall      0.789631
average_loss              0.478908
label/mean                0.375000
loss                      0.478908
precision                 0.703297
prediction/mean           0.350790
recall                    0.646465
global_step             100.000000
dtype: float64

A continuación, entrenemos un modelo Boosted Trees. Para árboles potenciados, se BoostedTreesRegressor regresión ( BoostedTreesRegressor ) y clasificación ( BoostedTreesClassifier ). Dado que el objetivo es predecir una clase, sobrevivir o no sobrevivir, utilizará BoostedTreesClassifier .

# Since data fits into memory, use entire dataset per layer. It will be faster.
# Above one batch is defined as the entire dataset.
n_batches = 1
est = tf.estimator.BoostedTreesClassifier(feature_columns,
                                          n_batches_per_layer=n_batches)

# The model will stop training once the specified number of trees is built, not
# based on the number of steps.
est.train(train_input_fn, max_steps=100)

# Eval.
result = est.evaluate(eval_input_fn)
clear_output()
print(pd.Series(result))
accuracy                  0.833333
accuracy_baseline         0.625000
auc                       0.874778
auc_precision_recall      0.859794
average_loss              0.406492
label/mean                0.375000
loss                      0.406492
precision                 0.795699
prediction/mean           0.385033
recall                    0.747475
global_step             100.000000
dtype: float64

Ahora puede usar el modelo de tren para hacer predicciones sobre un pasajero del conjunto de evaluación. Los modelos de TensorFlow están optimizados para realizar predicciones en un lote o colección de ejemplos a la vez. Anteriormente, eval_input_fn se define utilizando el conjunto de evaluación completo.

pred_dicts = list(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')
plt.show()
INFO:tensorflow:Calling model_fn.
INFO:tensorflow:Done calling model_fn.
INFO:tensorflow:Graph was finalized.
INFO:tensorflow:Restoring parameters from /tmp/tmpgmenxqlc/model.ckpt-100
INFO:tensorflow:Running local_init_op.
INFO:tensorflow:Done running local_init_op.

png

Por último, también puede observar la característica operativa del receptor (ROC) de los resultados, lo que nos dará una mejor idea de la compensación entre la tasa de verdaderos positivos y la tasa de falsos positivos.

from sklearn.metrics import roc_curve

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,)
plt.show()

png