Esta página foi traduzida pela API Cloud Translation.
Switch to English

Carregar dados CSV

Ver em TensorFlow.org Executar no Google Colab Ver fonte no GitHub Download do caderno

Este tutorial fornece um exemplo de como carregar dados CSV de um arquivo em um tf.data.Dataset .

Os dados usados ​​neste tutorial foram retirados da lista de passageiros do Titanic. O modelo preverá a probabilidade de sobrevivência de um passageiro com base em características como idade, sexo, classe de passagem e se a pessoa estava viajando sozinha.

Configuração

 import functools

import numpy as np
import tensorflow as tf
 
 TRAIN_DATA_URL = "https://storage.googleapis.com/tf-datasets/titanic/train.csv"
TEST_DATA_URL = "https://storage.googleapis.com/tf-datasets/titanic/eval.csv"

train_file_path = tf.keras.utils.get_file("train.csv", TRAIN_DATA_URL)
test_file_path = tf.keras.utils.get_file("eval.csv", TEST_DATA_URL)
 
Downloading data from https://storage.googleapis.com/tf-datasets/titanic/train.csv
32768/30874 [===============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tf-datasets/titanic/eval.csv
16384/13049 [=====================================] - 0s 0us/step

 # Make numpy values easier to read.
np.set_printoptions(precision=3, suppress=True)
 

Carregar dados

Para começar, vamos olhar na parte superior do arquivo CSV para ver como ele está formatado.

head {train_file_path}
survived,sex,age,n_siblings_spouses,parch,fare,class,deck,embark_town,alone
0,male,22.0,1,0,7.25,Third,unknown,Southampton,n
1,female,38.0,1,0,71.2833,First,C,Cherbourg,n
1,female,26.0,0,0,7.925,Third,unknown,Southampton,y
1,female,35.0,1,0,53.1,First,C,Southampton,n
0,male,28.0,0,0,8.4583,Third,unknown,Queenstown,y
0,male,2.0,3,1,21.075,Third,unknown,Southampton,n
1,female,27.0,0,2,11.1333,Third,unknown,Southampton,n
1,female,14.0,1,0,30.0708,Second,unknown,Cherbourg,n
1,female,4.0,1,1,16.7,Third,G,Southampton,n

Você pode carregar isso usando pandas e passar as matrizes NumPy para o TensorFlow. Se você precisar escalar até um grande conjunto de arquivos ou precisar de um carregador que se integre ao TensorFlow e ao tf.data , use a função tf.data.experimental.make_csv_dataset :

A única coluna que você precisa identificar explicitamente é aquela com o valor que o modelo pretende prever.

 LABEL_COLUMN = 'survived'
LABELS = [0, 1]
 

Agora leia os dados CSV do arquivo e crie um conjunto de dados.

(Para a documentação completa, consulte tf.data.experimental.make_csv_dataset )

 def get_dataset(file_path, **kwargs):
  dataset = tf.data.experimental.make_csv_dataset(
      file_path,
      batch_size=5, # Artificially small to make examples easier to show.
      label_name=LABEL_COLUMN,
      na_value="?",
      num_epochs=1,
      ignore_errors=True, 
      **kwargs)
  return dataset

raw_train_data = get_dataset(train_file_path)
raw_test_data = get_dataset(test_file_path)
 
 def show_batch(dataset):
  for batch, label in dataset.take(1):
    for key, value in batch.items():
      print("{:20s}: {}".format(key,value.numpy()))
 

Cada item do conjunto de dados é um lote, representado como uma tupla de ( muitos exemplos , muitos rótulos ). Os dados dos exemplos são organizados em tensores baseados em colunas (em vez de tensores baseados em linhas), cada um com tantos elementos quanto o tamanho do lote (5 neste caso).

Pode ajudar a ver isso você mesmo.

 show_batch(raw_train_data)
 
sex                 : [b'female' b'male' b'female' b'female' b'male']
age                 : [41. 28. 28. 48. 28.]
n_siblings_spouses  : [0 1 0 1 0]
parch               : [2 0 0 0 0]
fare                : [20.212 15.5    7.879 39.6   56.496]
class               : [b'Third' b'Third' b'Third' b'First' b'Third']
deck                : [b'unknown' b'unknown' b'unknown' b'A' b'unknown']
embark_town         : [b'Southampton' b'Queenstown' b'Queenstown' b'Cherbourg' b'Southampton']
alone               : [b'n' b'n' b'y' b'n' b'y']

Como você pode ver, as colunas no CSV são nomeadas. O construtor do conjunto de dados selecionará esses nomes automaticamente. Se o arquivo com o qual você está trabalhando não contiver os nomes das colunas na primeira linha, passe-os em uma lista de cadeias para o argumento column_names na função make_csv_dataset .

 CSV_COLUMNS = ['survived', 'sex', 'age', 'n_siblings_spouses', 'parch', 'fare', 'class', 'deck', 'embark_town', 'alone']

temp_dataset = get_dataset(train_file_path, column_names=CSV_COLUMNS)

show_batch(temp_dataset)
 
sex                 : [b'male' b'male' b'male' b'male' b'male']
age                 : [28. 39. 16. 59. 28.]
n_siblings_spouses  : [1 0 1 0 0]
parch               : [0 0 3 0 0]
fare                : [82.171 13.    34.375 13.5    0.   ]
class               : [b'First' b'Second' b'Third' b'Second' b'Second']
deck                : [b'unknown' b'unknown' b'unknown' b'unknown' b'unknown']
embark_town         : [b'Cherbourg' b'Southampton' b'Southampton' b'Southampton' b'Southampton']
alone               : [b'n' b'y' b'n' b'y' b'y']

Este exemplo vai usar todas as colunas disponíveis. Se você precisar omitir algumas colunas do conjunto de dados, crie uma lista apenas das colunas que planeja usar e passe-a para o argumento (opcional) select_columns do construtor.

 SELECT_COLUMNS = ['survived', 'age', 'n_siblings_spouses', 'class', 'deck', 'alone']

temp_dataset = get_dataset(train_file_path, select_columns=SELECT_COLUMNS)

show_batch(temp_dataset)
 
age                 : [38. 24. 22. 24. 28.]
n_siblings_spouses  : [0 1 0 0 1]
class               : [b'First' b'Second' b'Third' b'First' b'Third']
deck                : [b'C' b'unknown' b'unknown' b'B' b'unknown']
alone               : [b'n' b'n' b'y' b'y' b'n']

Pré-processamento de dados

Um arquivo CSV pode conter uma variedade de tipos de dados. Normalmente, você deseja converter esses tipos mistos em um vetor de comprimento fixo antes de alimentar os dados em seu modelo.

O TensorFlow possui um sistema interno para descrever conversões de entrada comuns: tf.feature_column , consulte este tutorial para obter detalhes.

Você pode pré-processar seus dados usando qualquer ferramenta que desejar (como nltk ou sklearn ) e apenas passar a saída processada para o TensorFlow.

A principal vantagem de fazer o pré-processamento dentro do seu modelo é que, quando você exporta o modelo, ele inclui o pré-processamento. Dessa forma, você pode passar os dados brutos diretamente para o seu modelo.

Dados contínuos

Se seus dados já estiverem em um formato numérico apropriado, você poderá compactá-los em um vetor antes de transmiti-los ao modelo:

 SELECT_COLUMNS = ['survived', 'age', 'n_siblings_spouses', 'parch', 'fare']
DEFAULTS = [0, 0.0, 0.0, 0.0, 0.0]
temp_dataset = get_dataset(train_file_path, 
                           select_columns=SELECT_COLUMNS,
                           column_defaults = DEFAULTS)

show_batch(temp_dataset)
 
age                 : [34.5 44.  41.  26.  28. ]
n_siblings_spouses  : [0. 0. 0. 0. 0.]
parch               : [0. 0. 5. 0. 0.]
fare                : [ 6.438  7.925 39.688 56.496  7.25 ]

 example_batch, labels_batch = next(iter(temp_dataset)) 
 

Aqui está uma função simples que agrupará todas as colunas:

 def pack(features, label):
  return tf.stack(list(features.values()), axis=-1), label
 

Aplique isso a cada elemento do conjunto de dados:

 packed_dataset = temp_dataset.map(pack)

for features, labels in packed_dataset.take(1):
  print(features.numpy())
  print()
  print(labels.numpy())
 
[[ 28.      0.      0.     15.05 ]
 [ 21.      0.      0.      7.796]
 [ 35.      0.      0.    512.329]
 [ 16.      0.      0.     10.5  ]
 [ 26.      0.      0.      8.05 ]]

[0 1 1 0 0]

Se você tiver tipos de dados mistos, poderá separar esses campos numéricos simples. A API tf.feature_column pode lidar com eles, mas isso gera alguma sobrecarga e deve ser evitado, a menos que seja realmente necessário. Volte para o conjunto de dados misto:

 show_batch(raw_train_data)
 
sex                 : [b'male' b'male' b'male' b'male' b'female']
age                 : [32. 24. 18. 11. 28.]
n_siblings_spouses  : [1 1 1 5 1]
parch               : [0 0 1 2 0]
fare                : [15.85  16.1    7.854 46.9   15.5  ]
class               : [b'Third' b'Third' b'Third' b'Third' b'Third']
deck                : [b'unknown' b'unknown' b'unknown' b'unknown' b'unknown']
embark_town         : [b'Southampton' b'Southampton' b'Southampton' b'Southampton' b'Queenstown']
alone               : [b'n' b'n' b'n' b'n' b'n']

 example_batch, labels_batch = next(iter(temp_dataset)) 
 

Portanto, defina um pré-processador mais geral que selecione uma lista de recursos numéricos e os agrupe em uma única coluna:

 class PackNumericFeatures(object):
  def __init__(self, names):
    self.names = names

  def __call__(self, features, labels):
    numeric_features = [features.pop(name) for name in self.names]
    numeric_features = [tf.cast(feat, tf.float32) for feat in numeric_features]
    numeric_features = tf.stack(numeric_features, axis=-1)
    features['numeric'] = numeric_features

    return features, labels
 
 NUMERIC_FEATURES = ['age','n_siblings_spouses','parch', 'fare']

packed_train_data = raw_train_data.map(
    PackNumericFeatures(NUMERIC_FEATURES))

packed_test_data = raw_test_data.map(
    PackNumericFeatures(NUMERIC_FEATURES))
 
 show_batch(packed_train_data)
 
sex                 : [b'female' b'male' b'female' b'male' b'male']
class               : [b'Second' b'First' b'First' b'Third' b'Third']
deck                : [b'E' b'B' b'unknown' b'unknown' b'unknown']
embark_town         : [b'Southampton' b'Southampton' b'Cherbourg' b'Southampton' b'Queenstown']
alone               : [b'y' b'y' b'n' b'y' b'y']
numeric             : [[32.5    0.     0.    13.   ]
 [40.     0.     0.     0.   ]
 [54.     1.     0.    59.4  ]
 [41.     0.     0.     7.125]
 [19.     0.     0.     6.75 ]]

 example_batch, labels_batch = next(iter(packed_train_data)) 
 

Normalização de dados

Dados contínuos sempre devem ser normalizados.

 import pandas as pd
desc = pd.read_csv(train_file_path)[NUMERIC_FEATURES].describe()
desc
 
 MEAN = np.array(desc.T['mean'])
STD = np.array(desc.T['std'])
 
 def normalize_numeric_data(data, mean, std):
  # Center the data
  return (data-mean)/std

 

Agora crie uma coluna numérica. A API tf.feature_columns.numeric_column aceita um argumento normalizer_fn , que será executado em cada lote.

Ligue o MEAN e o STD ao normalizador fn usando functools.partial .

 # See what you just created.
normalizer = functools.partial(normalize_numeric_data, mean=MEAN, std=STD)

numeric_column = tf.feature_column.numeric_column('numeric', normalizer_fn=normalizer, shape=[len(NUMERIC_FEATURES)])
numeric_columns = [numeric_column]
numeric_column
 
NumericColumn(key='numeric', shape=(4,), default_value=None, dtype=tf.float32, normalizer_fn=functools.partial(<function normalize_numeric_data at 0x7f58602b7378>, mean=array([29.631,  0.545,  0.38 , 34.385]), std=array([12.512,  1.151,  0.793, 54.598])))

Ao treinar o modelo, inclua esta coluna de recurso para selecionar e centralizar este bloco de dados numéricos:

 example_batch['numeric']
 
<tf.Tensor: shape=(5, 4), dtype=float32, numpy=
array([[23.   ,  0.   ,  0.   , 10.5  ],
       [24.   ,  2.   ,  0.   , 24.15 ],
       [ 9.   ,  1.   ,  1.   , 15.9  ],
       [28.   ,  0.   ,  0.   ,  7.733],
       [29.   ,  0.   ,  0.   ,  7.775]], dtype=float32)>
 numeric_layer = tf.keras.layers.DenseFeatures(numeric_columns)
numeric_layer(example_batch).numpy()
 
array([[-0.53 , -0.474, -0.479, -0.437],
       [-0.45 ,  1.264, -0.479, -0.187],
       [-1.649,  0.395,  0.782, -0.339],
       [-0.13 , -0.474, -0.479, -0.488],
       [-0.05 , -0.474, -0.479, -0.487]], dtype=float32)

A normalização baseada em média usada aqui requer conhecer os meios de cada coluna antes do tempo.

Dados categóricos

Algumas das colunas nos dados CSV são colunas categóricas. Ou seja, o conteúdo deve ser um de um conjunto limitado de opções.

Use a API tf.feature_column para criar uma coleção com um tf.feature_column.indicator_column para cada coluna categórica.

 CATEGORIES = {
    'sex': ['male', 'female'],
    'class' : ['First', 'Second', 'Third'],
    'deck' : ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
    'embark_town' : ['Cherbourg', 'Southhampton', 'Queenstown'],
    'alone' : ['y', 'n']
}

 
 categorical_columns = []
for feature, vocab in CATEGORIES.items():
  cat_col = tf.feature_column.categorical_column_with_vocabulary_list(
        key=feature, vocabulary_list=vocab)
  categorical_columns.append(tf.feature_column.indicator_column(cat_col))
 
 # See what you just created.
categorical_columns
 
[IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='sex', vocabulary_list=('male', 'female'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),
 IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='class', vocabulary_list=('First', 'Second', 'Third'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),
 IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='deck', vocabulary_list=('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),
 IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='embark_town', vocabulary_list=('Cherbourg', 'Southhampton', 'Queenstown'), dtype=tf.string, default_value=-1, num_oov_buckets=0)),
 IndicatorColumn(categorical_column=VocabularyListCategoricalColumn(key='alone', vocabulary_list=('y', 'n'), dtype=tf.string, default_value=-1, num_oov_buckets=0))]
 categorical_layer = tf.keras.layers.DenseFeatures(categorical_columns)
print(categorical_layer(example_batch).numpy()[0])
 
[1. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]

Isso fará parte de uma entrada de processamento de dados posteriormente, quando você construir o modelo.

Camada de pré-processamento combinado

Adicione as duas coleções de colunas de recursos e passe-as para um tf.keras.layers.DenseFeatures para criar uma camada de entrada que extrairá e pré-processará os dois tipos de entrada:

 preprocessing_layer = tf.keras.layers.DenseFeatures(categorical_columns+numeric_columns)
 
 print(preprocessing_layer(example_batch).numpy()[0])
 
[ 1.     0.     0.     1.     0.     0.     0.     0.     0.     0.

  0.     0.     0.     0.     0.     0.     0.     0.    -0.53  -0.474
 -0.479 -0.437  1.     0.   ]

Construa o modelo

Crie um tf.keras.Sequential , começando com o preprocessing_layer .

 model = tf.keras.Sequential([
  preprocessing_layer,
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(1),
])

model.compile(
    loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
    optimizer='adam',
    metrics=['accuracy'])
 

Treine, avalie e preveja

Agora o modelo pode ser instanciado e treinado.

 train_data = packed_train_data.shuffle(500)
test_data = packed_test_data
 
 model.fit(train_data, epochs=20)
 
Epoch 1/20
126/126 [==============================] - 0s 3ms/step - loss: 0.5173 - accuracy: 0.7273
Epoch 2/20
126/126 [==============================] - 0s 3ms/step - loss: 0.4178 - accuracy: 0.8166
Epoch 3/20
126/126 [==============================] - 0s 3ms/step - loss: 0.4067 - accuracy: 0.8134
Epoch 4/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3902 - accuracy: 0.8278
Epoch 5/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3832 - accuracy: 0.8421
Epoch 6/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3728 - accuracy: 0.8309
Epoch 7/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3639 - accuracy: 0.8389
Epoch 8/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3572 - accuracy: 0.8485
Epoch 9/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3506 - accuracy: 0.8437
Epoch 10/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3450 - accuracy: 0.8453
Epoch 11/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3474 - accuracy: 0.8533
Epoch 12/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3363 - accuracy: 0.8549
Epoch 13/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3326 - accuracy: 0.8517
Epoch 14/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3357 - accuracy: 0.8517
Epoch 15/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3298 - accuracy: 0.8596
Epoch 16/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3212 - accuracy: 0.8549
Epoch 17/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3148 - accuracy: 0.8581
Epoch 18/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3353 - accuracy: 0.8501
Epoch 19/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3128 - accuracy: 0.8596
Epoch 20/20
126/126 [==============================] - 0s 3ms/step - loss: 0.3135 - accuracy: 0.8565

<tensorflow.python.keras.callbacks.History at 0x7f5860326080>

Depois que o modelo é treinado, você pode verificar sua precisão no conjunto test_data .

 test_loss, test_accuracy = model.evaluate(test_data)

print('\n\nTest Loss {}, Test Accuracy {}'.format(test_loss, test_accuracy))
 
53/53 [==============================] - 0s 3ms/step - loss: 0.4639 - accuracy: 0.8447


Test Loss 0.46389907598495483, Test Accuracy 0.8446969985961914

Use tf.keras.Model.predict para inferir rótulos em um lote ou em um conjunto de dados de lotes.

 predictions = model.predict(test_data)

# Show some results
for prediction, survived in zip(predictions[:10], list(test_data)[0][1][:10]):
  prediction = tf.sigmoid(prediction).numpy()
  print("Predicted survival: {:.2%}".format(prediction[0]),
        " | Actual outcome: ",
        ("SURVIVED" if bool(survived) else "DIED"))

 
Predicted survival: 84.39%  | Actual outcome:  DIED
Predicted survival: 93.52%  | Actual outcome:  DIED
Predicted survival: 7.61%  | Actual outcome:  SURVIVED
Predicted survival: 45.15%  | Actual outcome:  DIED
Predicted survival: 7.44%  | Actual outcome:  DIED