Path: blob/master/site/es-419/tutorials/load_data/csv.ipynb
25118 views
Copyright 2019 The TensorFlow Authors.
Cargar datos CSV
Este tutorial da ejemplos de cómo usar datos CSV con TensorFlow.
Hay dos partes principales:
Cargar los datos del disco
Preprocesarlos en una forma adecuada para el entrenamiento.
Este tutorial se centra en la carga y ofrece algunos ejemplos rápidos de preprocesamiento. Para aprender más sobre el aspecto del preprocesamiento, consulte la guía Trabajar con capas de preprocesamiento y el tutorial Clasificar datos estructurados utilizando capas de preprocesamiento Keras.
Preparación
Cargar datos en la memoria
Para cualquier conjunto de datos CSV pequeño, la forma más sencilla de entrenar un modelo TensorFlow en él es cargarlo en memoria como un Dataframe pandas o un arreglo de NumPy.
Un ejemplo relativamente sencillo es el conjunto de datos de abalones.
El conjunto de datos es pequeño.
Todas las características de entrada son valores de punto flotante de rango limitado.
Así es como se descargan los datos en un DataFrame
pandas:
El conjunto de datos contiene una serie de mediciones de abalones, un tipo de molusco marino.
“Concha de abalón” (por Nicki Dugan Pogue, CC BY-SA 2.0)
La tarea nominal de este conjunto de datos es predecir la edad a partir de las demás medidas, por lo que se separan las características y las etiquetas para el entrenamiento:
Para este conjunto de datos tratará todas las características de forma idéntica. Empaquete las características en un único arreglo NumPy.:
Luego haga que un modelo de regresión prediga la edad. Dado que sólo hay un único tensor de entrada, basta aquí con un modelo tf.keras.Sequential
.
Para entrenar ese modelo, pase las características y las etiquetas a Model.fit
:
Acaba de ver la forma más básica de entrenar un modelo usando datos CSV. Ahora, aprenderá a aplicar el preprocesamiento para normalizar las columnas numéricas.
Preprocesamiento básico
Es una buena práctica normalizar las entradas a su modelo. Las capas de preprocesamiento Keras aportan una forma cómoda de incorporar esta normalización a su modelo.
La capa tf.keras.layers.Normalization
calcula previamente la media y la varianza de cada columna, y las usa para normalizar los datos.
En primer lugar, cree la capa:
Luego, use el método Normalization.adapt
para adaptar la capa de normalización a sus datos.
Nota: Utilice únicamente sus datos de entrenamiento con el método PreprocessingLayer.adapt
. No use sus datos de validación o de prueba.
Luego, use la capa de normalización en su modelo:
Tipos de datos mezclados
El conjunto de datos "Titanic" contiene información sobre los pasajeros del Titanic. La tarea nominal en este conjunto de datos es predecir quién sobrevivió.
Imagen de Wikimedia
Los datos sin procesar pueden cargarse fácilmente como un DataFrame
de Pandas, pero no son inmediatamente utilizables como entrada para un modelo TensorFlow.
Como los tipos de datos y rangos son diferentes, no puede simplemente acumular las funciones en un arreglo NumPy y pasarlo a un modelo tf.keras.Sequential
. Cada columna necesita ser manejada individualmente.
Como opción, podría preprocesar sus datos fuera de línea (usando cualquier herramienta que desee) para convertir columnas categóricas en columnas numéricas, y luego pasar la salida procesada a su modelo TensorFlow. La desventaja de ese enfoque es que si guarda y exporta su modelo, el preprocesamiento no se guarda con él. Las capas Keras de preprocesamiento evitan este problema porque forman parte del modelo.
En este ejemplo, construirá un modelo que implementa la lógica de preprocesamiento usando la API funcional de Keras. También podría hacerlo mediante subclases.
La API funcional opera con tensores "simbólicos". Los tensores "eager" normales tienen un valor. En cambio, estos tensores "simbólicos" no lo tienen. En su lugar, llevan un seguimiento de las operaciones que se ejecutan sobre ellos, y construyen una representación del cálculo, que puede ejecutar más tarde. He aquí un ejemplo rápido:
Para construir el modelo de preprocesamiento, se empieza por construir un conjunto de objetos simbólicos tf.keras.Input
, que coincidan con los nombres y tipos de datos de las columnas CSV.
El primer paso en su lógica de preprocesamiento es concatenar las entradas numéricas y hacerlas pasar por una capa de normalización:
Recoge todos los resultados del preprocesamiento simbólico, para concatenarlos posteriormente:
Para las entradas de cadena use la función tf.keras.layers.StringLookup
para mapear de cadenas a índices enteros en un vocabulario. A continuación, use tf.keras.layers.CategoryEncoding
para convertir los índices en datos float32
apropiados para el modelo.
Los ajustes predeterminados para la capa tf.keras.layers.CategoryEncoding
crean un vector de un solo golpe para cada entrada. Una capa tf.keras.layers.Embedding
también funcionaría. Consulte la guía Trabajar con capas de preprocesamiento y el tutorial Clasificar datos estructurados usando capas de preprocesamiento Keras para más información sobre este tema.
Con la recolección de inputs
y preprocessed_inputs
, puede concatenar todas las entradas preprocesadas y construir un modelo que se encargue del preprocesamiento:
Este modelo sólo contiene el preprocesamiento de entrada. Puede ejecutarlo para ver lo que hace con sus datos. Los modelos Keras no convierten automáticamente los pandas DataFrame
s porque no está claro si se debe convertir a un tensor o a un diccionario de tensores. Por lo tanto, conviértalo en un diccionario de tensores:
Corte el primer ejemplo de entrenamiento y páselo a este modelo de preprocesamiento, verá las características numéricas y las cadenas de un solo paso todas concatenadas:
Ahora, construya el modelo sobre esto:
Cuando entrene el modelo, pase el diccionario de características como x
, y la etiqueta como y
.
Dado que el preprocesamiento forma parte del modelo, puede guardar el modelo y volver a cargarlo en otro lugar y obtener resultados idénticos:
Usar tf.data
En la sección anterior, usted confió en el mezclado y procesamiento por lotes de datos incorporado en el modelo durante el entrenamiento del mismo.
Si necesita más control sobre la canalización de los datos de entrada o necesita usar datos que no caben fácilmente en la memoria: use tf.data
.
Para más ejemplos, consulte la tf.data
: Construir canalizaciones de entrada TensorFlow.
Sobre datos en memoria
Como primer ejemplo de aplicación de tf.data
a datos CSV, considere el siguiente código para trocear manualmente el diccionario de características de la sección anterior. Para cada índice, toma ese índice para cada característica:
Ejecútelo e imprima el primer ejemplo:
El cargador de datos en memoria tf.data.Dataset
más básico es el constructor Dataset.from_tensor_slices
. Éste devuelve un tf.data.Dataset
que implementa una versión generalizada de la función slices
anterior, en TensorFlow.
Puede iterar sobre un tf.data.Dataset
como cualquier otro iterable de python:
La función from_tensor_slices
puede manejar cualquier estructura de diccionarios anidados o tuplas. El siguiente código crea un conjunto de datos de pares (features_dict, labels)
:
Para entrenar un modelo usando este Dataset
, necesitará al menos hacer shuffle
y batch
los datos.
En lugar de pasar features
y labels
a Model.fit
, se pasa el conjunto de datos:
Desde un único archivo
Hasta ahora este tutorial ha trabajado con datos en memoria. tf.data
es un conjunto de herramientas altamente escalable para construir canalizaciones de datos, y ofrece algunas funciones para tratar la carga de archivos CSV.
Ahora lea los datos CSV del archivo y cree un tf.data.Dataset
.
(Para ver la documentación completa, consulte tf.data.experimental.make_csv_dataset
)
Esta función incluye muchas características convenientes, por lo que es fácil trabajar con los datos. Esto incluye:
Usar las cabeceras de las columnas como claves del diccionario.
Determinar automáticamente el tipo de cada columna.
Precaución: Asegúrese de establecer el argumento num_epochs
en tf.data.experimental.make_csv_dataset
, de lo contrario el comportamiento predeterminado para tf.data.Dataset
es hacer un bucle sin fin.
Nota: Si ejecuta la celda anterior dos veces producirá resultados diferentes. Los ajustes predeterminados para tf.data.experimental.make_csv_dataset
incluyen shuffle_buffer_size=1000
, que es más que suficiente para este pequeño conjunto de datos, pero puede no serlo para un conjunto de datos del mundo real.
También puede descomprimir los datos sobre la marcha. Aquí tiene un archivo CSV descomprimido que contiene el conjunto de datos de tráfico interestatal de metro.
Imagen de Wikimedia
Ajuste el argumento compression_type
para leer directamente del archivo comprimido:
Nota: Si necesita analizar esas cadenas de fecha y hora en la canalización tfa.data
, puede usar tfa.text.parse_time
.
Almacenamiento en caché
El análisis sintáctico de los datos CSV conlleva algunos esfuerzos. Para los modelos pequeños esto puede ser el cuello de botella en el entrenamiento.
Dependiendo de su caso de uso, puede ser una buena idea usar Dataset.cache
o tf.data.Dataset.snapshot
, para que los datos CSV sólo se parseen en la primera época.
La principal diferencia entre los métodos cache
y snapshot
es que los archivos cache
sólo pueden ser usados por el proceso TensorFlow que los creó, pero los archivos snapshot
pueden ser leídos por otros procesos.
Por ejemplo, iterar sobre el traffic_volume_csv_gz_ds
20 veces puede llevar unos 15 segundos sin almacenamiento en caché, o unos dos segundos con almacenamiento en caché.
Nota: Dataset.cache
almacena los datos de la primera época y los reproduce en orden. Por tanto, usar el método cache
desactiva cualquier mezcla anterior en la canalización. Más adelante, Dataset.shuffle
se vuelve a añadir después de Dataset.cache
.
Nota: Los archivos tf.data.Dataset.snapshot
están pensados para el almacenamiento temporal de un conjunto de datos mientras se usa. Este no es un formato para el almacenamiento a largo plazo. El formato de archivo se considera un detalle interno, y no se garantiza entre las versiones de TensorFlow.
Si la carga de sus datos se ralentiza al cargar archivos CSV, y Dataset.cache
y tf.data.Dataset.snapshot
son insuficientes para su caso de uso, considere la posibilidad de recodificar sus datos en un formato más ágil.
Múltiples archivos
Todos los ejemplos hasta ahora en esta sección podrían hacerse fácilmente sin tf.data
. Un lugar donde tf.data
puede realmente simplificar las cosas es cuando se trata de colecciones de archivos.
Por ejemplo, el conjunto de datos imágenes de fuentes de caracteres se distribuye como una recopilación de archivos csv, uno por fuente.
Imagen por Willi Heidelbach de Pixabay
Descargue el conjunto de datos y revise los archivos que contiene:
Cuando trabaje con numerosos archivos, puede pasar un file_pattern
de tipo glob a la función tf.data.experimental.make_csv_dataset
. El orden de los archivos se mezcla en cada iteración.
Use el argumento num_parallel_reads
para establecer cuántos archivos se leen en paralelo y se intercalan juntos.
Estos archivos CSV tienen las imágenes aplanadas en una sola fila. Los nombres de las columnas tienen el formato r{row}c{column}
. Aquí está el primer lote:
Opcional: Campos de empaquetado
Probablemente no querrá trabajar con cada pixel en columnas separadas como esta. Antes de intentar usar este conjunto de datos asegúrese de empaquetar los pixeles en un tensor de imagen.
Este es el código que analiza los nombres de las columnas para construir las imágenes de cada ejemplo:
Aplique esa función a cada lote del conjunto de datos:
Trace las imágenes resultantes:
Funciones de nivel inferior
Hasta ahora este tutorial se ha centrado en las utilidades de más alto nivel para la lectura de datos csv. Existen otras dos API que pueden ser útiles para usuarios avanzados si su caso de uso no se ajusta a los patrones básicos.
tf.io.decode_csv
: una función para parsear líneas de texto en una lista de tensores de columnas CSV.tf.data.experimental.CsvDataset
: un constructor de conjuntos de datos CSV de nivel inferior.
Esta sección recrea la funcionalidad proporcionada por tf.data.experimental.make_csv_dataset
, para demostrar cómo se puede usar esta funcionalidad de nivel inferior.
tf.io.decode_csv
Esta función decodifica una cadena o una lista de cadenas en una lista de columnas.
A diferencia de tf.data.experimental.make_csv_dataset
esta función no intenta adivinar los tipos de datos de las columnas. Usted especifica los tipos de columna mediante una lista de record_defaults
que contiene un valor del tipo correcto, para cada columna.
Para leer los datos del Titanic como cadenas usando tf.io.decode_csv
usted pondría:
Para parsearlos con sus tipos reales, cree una lista de record_defaults
de los tipos correspondientes:
Nota: Es más eficiente llamar a tf.io.decode_csv
en grandes lotes de líneas que en líneas individuales de texto CSV.
tf.data.experimental.CsvDataset
La clase tf.data.experimental.CsvDataset
ofrece una interfaz mínima Dataset
CSV sin las características convenientes de la función tf.data.experimental.make_csv_dataset
: análisis sintáctico de cabeceras de columna, inferencia del tipo de columna, mezclado automático, intercalación de archivos.
Este constructor usa record_defaults
del mismo modo que tf.io.decode_csv
:
El código anterior equivale básicamente a:
Múltiples archivos
Para parsear el conjunto de datos de fuentes usando tf.data.experimental.CsvDataset
, primero necesita determinar los tipos de columna para el record_defaults
. Empiece por inspeccionar la primera fila de un archivo:
Sólo los dos primeros campos son cadenas, el resto son números enteros o flotantes, y puede obtener el número total de características contando las comas:
El constructor tf.data.experimental.CsvDataset
puede tomar una lista de archivos de entrada, pero los lee secuencialmente. El primer archivo de la lista de CSV es AGENCY.csv
:
Así, cuando pase la lista de archivos a CsvDataset
, se leerán primero los registros de AGENCY.csv
:
Para intercalar varios archivos, use Dataset.interleave
.
Aquí tiene un conjunto de datos inicial que contiene los nombres de los archivos CSV:
Esto mezcla los nombres de los archivos en cada época:
El método interleave
toma un map_func
que crea un Dataset
hijo para cada elemento del Dataset
padre.
En este caso, desea crear un tf.data.experimental.CsvDataset
a partir de cada elemento del conjunto de datos de archivos:
El Conjunto de datos
devuelto por interleave devuelve elementos haciendo un ciclo sobre un número de los Dataset
s hijo. Observe, a continuación, cómo el conjunto de datos cicla sobre cycle_length=3
tres archivos de fuentes:
Rendimiento
Antes, se observó que tf.io.decode_csv
es más eficiente cuando se ejecuta sobre un lote de cadenas.
Es posible aprovechar este hecho, cuando se usan lotes de gran tamaño, para mejorar el rendimiento de la carga de CSV (pero pruebe caching primero).
Con el cargador integrado 20, los lotes de 2048 muestras tardan unos 17 s.
El paso de lotes de líneas de texto a decode_csv
se ejecuta más rápido, por unos 5 s:
Para ver otro ejemplo de cómo aumentar el rendimiento de CSV usando grandes lotes, consulte el tutorial Sobreajuste y subajuste.
Este tipo de enfoque puede funcionar, pero considere otras opciones como Dataset.cache
y tf.data.Dataset.snapshot
, o recodifique sus datos en un formato más ágil.