Загрузка pandas.DataFrame

Смотрите на TensorFlow.org Запустите в Google Colab Изучайте код на GitHub Скачайте ноутбук

Из этого руководства вы узнаете, как загрузить датафрейм Pandas в tf.data.Dataset.

Это руководство использует небольшой датасет предоставленный Фондом сердечных заболеваний кливлендской клиники. В ней несколько сотен строк в формате CSV. Каждая строка описывает пациента, а каждый столбец описывает свойство. Мы используем эту информацию чтобы предсказать имеет ли пациент сердечное заболевание, что в этом датасете является задачей двоичной классификации.

Прочитайте данные используя pandas

import pandas as pd
import tensorflow as tf

Скачайте файл csv содержащий датасет с пациентами.

csv_file = tf.keras.utils.get_file('heart.csv', 'https://storage.googleapis.com/applied-dl/heart.csv')
Downloading data from https://storage.googleapis.com/applied-dl/heart.csv
16384/13273 [=====================================] - 0s 0us/step

Прочитайте csv файл используя pandas.

df = pd.read_csv(csv_file)
df.head()
df.dtypes
age           int64
sex           int64
cp            int64
trestbps      int64
chol          int64
fbs           int64
restecg       int64
thalach       int64
exang         int64
oldpeak     float64
slope         int64
ca            int64
thal         object
target        int64
dtype: object

Конвертируйте столбец thal являющийся object в датафрейме в дискретные числовые значения.

df['thal'] = pd.Categorical(df['thal'])
df['thal'] = df.thal.cat.codes
df.head()

Загрузите данные используя tf.data.Dataset

Используйте tf.data.Dataset.from_tensor_slices чтобы прочитать значения из датафрейма pandas.

Одним из преимуществ использования tf.data.Dataset является то, что он позволяет вам писать простые высокоэффективные конвейеры данных. Прочитайте руководство по загрузке данных для подробностей.

target = df.pop('target')
dataset = tf.data.Dataset.from_tensor_slices((df.values, target.values))
for feat, targ in dataset.take(5):
  print ('Признаки: {}, Цель: {}'.format(feat, targ))
Признаки: [ 63.    1.    1.  145.  233.    1.    2.  150.    0.    2.3   3.    0.

   2. ], Цель: 0
Признаки: [ 67.    1.    4.  160.  286.    0.    2.  108.    1.    1.5   2.    3.
   3. ], Цель: 1
Признаки: [ 67.    1.    4.  120.  229.    0.    2.  129.    1.    2.6   2.    2.
   4. ], Цель: 0
Признаки: [ 37.    1.    3.  130.  250.    0.    0.  187.    0.    3.5   3.    0.
   3. ], Цель: 0
Признаки: [ 41.    0.    2.  130.  204.    0.    2.  172.    0.    1.4   1.    0.
   3. ], Цель: 0

Поскольку pd.Series реализует протокол __array__ он может быть использован практически везде где вы бы использовали np.array или tf.Tensor.

tf.constant(df['thal'])
<tf.Tensor: shape=(303,), dtype=int8, numpy=
array([2, 3, 4, 3, 3, 3, 3, 3, 4, 4, 2, 3, 2, 4, 4, 3, 4, 3, 3, 3, 3, 3,
       3, 4, 4, 3, 3, 3, 3, 4, 3, 4, 3, 4, 3, 3, 4, 2, 4, 3, 4, 3, 4, 4,
       2, 3, 3, 4, 3, 3, 4, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 4, 4, 3, 3, 4,
       4, 2, 3, 3, 4, 3, 4, 3, 3, 4, 4, 3, 3, 4, 4, 3, 3, 3, 3, 4, 4, 4,
       3, 3, 4, 3, 4, 4, 3, 4, 3, 3, 3, 4, 3, 4, 4, 3, 3, 4, 4, 4, 4, 4,
       3, 3, 3, 3, 4, 3, 4, 3, 4, 4, 3, 3, 2, 4, 4, 2, 3, 3, 4, 4, 3, 4,
       3, 3, 4, 2, 4, 4, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
       4, 3, 3, 3, 4, 3, 4, 3, 4, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3,
       3, 3, 3, 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 3, 2,
       4, 4, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 2, 2, 4, 3, 4, 2, 4, 3,
       3, 4, 3, 3, 3, 3, 4, 3, 4, 3, 4, 2, 2, 4, 3, 4, 3, 2, 4, 3, 3, 2,
       4, 4, 4, 4, 3, 0, 3, 3, 3, 3, 1, 4, 3, 3, 3, 4, 3, 4, 3, 3, 3, 4,
       3, 3, 4, 4, 4, 4, 3, 3, 4, 3, 4, 3, 4, 4, 3, 4, 4, 3, 4, 4, 3, 3,
       3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 3, 2, 4, 4, 4, 4], dtype=int8)>

Перемешайте датасет и разбейте его на пакеты.

train_dataset = dataset.shuffle(len(df)).batch(1)

Создайте и обучите модель

def get_compiled_model():
  model = tf.keras.Sequential([
    tf.keras.layers.Dense(10, activation='relu'),
    tf.keras.layers.Dense(10, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
  ])

  model.compile(optimizer='adam',
                loss='binary_crossentropy',
                metrics=['accuracy'])
  return model
model = get_compiled_model()
model.fit(train_dataset, epochs=15)
Epoch 1/15
WARNING:tensorflow:Layer dense is casting an input tensor from dtype float64 to the layer's dtype of float32, which is new behavior in TensorFlow 2.  The layer has dtype float32 because its dtype defaults to floatx.

If you intended to run this layer in float32, you can safely ignore this warning. If in doubt, this warning is likely only an issue if you are porting a TensorFlow 1.X model to TensorFlow 2.

To change all layers to have dtype float64 by default, call `tf.keras.backend.set_floatx('float64')`. To change just this layer, pass dtype='float64' to the layer constructor. If you are the author of this layer, you can disable autocasting by passing autocast=False to the base Layer constructor.

303/303 [==============================] - 1s 2ms/step - loss: 2.0320 - accuracy: 0.6238
Epoch 2/15
303/303 [==============================] - 1s 2ms/step - loss: 1.0159 - accuracy: 0.6700
Epoch 3/15
303/303 [==============================] - 1s 2ms/step - loss: 0.7789 - accuracy: 0.7228
Epoch 4/15
303/303 [==============================] - 1s 2ms/step - loss: 0.6698 - accuracy: 0.7360
Epoch 5/15
303/303 [==============================] - 1s 2ms/step - loss: 0.6533 - accuracy: 0.7426
Epoch 6/15
303/303 [==============================] - 1s 2ms/step - loss: 0.6030 - accuracy: 0.7195
Epoch 7/15
303/303 [==============================] - 1s 2ms/step - loss: 0.6020 - accuracy: 0.7360
Epoch 8/15
303/303 [==============================] - 1s 2ms/step - loss: 0.5410 - accuracy: 0.7756
Epoch 9/15
303/303 [==============================] - 1s 2ms/step - loss: 0.5082 - accuracy: 0.7789
Epoch 10/15
303/303 [==============================] - 1s 2ms/step - loss: 0.4826 - accuracy: 0.7789
Epoch 11/15
303/303 [==============================] - 1s 2ms/step - loss: 0.5324 - accuracy: 0.7921
Epoch 12/15
303/303 [==============================] - 1s 2ms/step - loss: 0.4939 - accuracy: 0.7789
Epoch 13/15
303/303 [==============================] - 1s 2ms/step - loss: 0.5211 - accuracy: 0.7756
Epoch 14/15
303/303 [==============================] - 1s 2ms/step - loss: 0.5575 - accuracy: 0.7723
Epoch 15/15
303/303 [==============================] - 1s 2ms/step - loss: 0.5177 - accuracy: 0.7558

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

Альтернатива столбцам признаков

Передать словарь в качестве входных данных для модели так же просто, как и создать словарь соответствия слоев tf.keras.layers.Input, применяя любой препроцессинг и складывая их, используя функциональный api. Вы можете использовать это в качестве альтернативы столбцов признаков.

inputs = {key: tf.keras.layers.Input(shape=(), name=key) for key in df.keys()}
x = tf.stack(list(inputs.values()), axis=-1)

x = tf.keras.layers.Dense(10, activation='relu')(x)
output = tf.keras.layers.Dense(1, activation='sigmoid')(x)

model_func = tf.keras.Model(inputs=inputs, outputs=output)

model_func.compile(optimizer='adam',
                   loss='binary_crossentropy',
                   metrics=['accuracy'])

Простейший способ сохранения структуры столбцов в pd.DataFrame при использовании с tf.data это конвертация pd.DataFrame в dict и сделав срезы этого словаря.

dict_slices = tf.data.Dataset.from_tensor_slices((df.to_dict('list'), target.values)).batch(16)
for dict_slice in dict_slices.take(1):
  print (dict_slice)
({'age': <tf.Tensor: shape=(16,), dtype=int32, numpy=
array([63, 67, 67, 37, 41, 56, 62, 57, 63, 53, 57, 56, 56, 44, 52, 57],
      dtype=int32)>, 'sex': <tf.Tensor: shape=(16,), dtype=int32, numpy=array([1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1], dtype=int32)>, 'cp': <tf.Tensor: shape=(16,), dtype=int32, numpy=array([1, 4, 4, 3, 2, 2, 4, 4, 4, 4, 4, 2, 3, 2, 3, 3], dtype=int32)>, 'trestbps': <tf.Tensor: shape=(16,), dtype=int32, numpy=
array([145, 160, 120, 130, 130, 120, 140, 120, 130, 140, 140, 140, 130,
       120, 172, 150], dtype=int32)>, 'chol': <tf.Tensor: shape=(16,), dtype=int32, numpy=
array([233, 286, 229, 250, 204, 236, 268, 354, 254, 203, 192, 294, 256,
       263, 199, 168], dtype=int32)>, 'fbs': <tf.Tensor: shape=(16,), dtype=int32, numpy=array([1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0], dtype=int32)>, 'restecg': <tf.Tensor: shape=(16,), dtype=int32, numpy=array([2, 2, 2, 0, 2, 0, 2, 0, 2, 2, 0, 2, 2, 0, 0, 0], dtype=int32)>, 'thalach': <tf.Tensor: shape=(16,), dtype=int32, numpy=
array([150, 108, 129, 187, 172, 178, 160, 163, 147, 155, 148, 153, 142,
       173, 162, 174], dtype=int32)>, 'exang': <tf.Tensor: shape=(16,), dtype=int32, numpy=array([0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0], dtype=int32)>, 'oldpeak': <tf.Tensor: shape=(16,), dtype=float32, numpy=
array([2.3, 1.5, 2.6, 3.5, 1.4, 0.8, 3.6, 0.6, 1.4, 3.1, 0.4, 1.3, 0.6,

       0. , 0.5, 1.6], dtype=float32)>, 'slope': <tf.Tensor: shape=(16,), dtype=int32, numpy=array([3, 2, 2, 3, 1, 1, 3, 1, 2, 3, 2, 2, 2, 1, 1, 1], dtype=int32)>, 'ca': <tf.Tensor: shape=(16,), dtype=int32, numpy=array([0, 3, 2, 0, 0, 0, 2, 0, 1, 0, 0, 0, 1, 0, 0, 0], dtype=int32)>, 'thal': <tf.Tensor: shape=(16,), dtype=int32, numpy=array([2, 3, 4, 3, 3, 3, 3, 3, 4, 4, 2, 3, 2, 4, 4, 3], dtype=int32)>}, <tf.Tensor: shape=(16,), dtype=int64, numpy=array([0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0])>)

model_func.fit(dict_slices, epochs=15)
Epoch 1/15
19/19 [==============================] - 0s 2ms/step - loss: 10.0650 - accuracy: 0.2805
Epoch 2/15
19/19 [==============================] - 0s 2ms/step - loss: 3.7608 - accuracy: 0.6106
Epoch 3/15
19/19 [==============================] - 0s 2ms/step - loss: 3.5055 - accuracy: 0.5710
Epoch 4/15
19/19 [==============================] - 0s 2ms/step - loss: 3.1131 - accuracy: 0.5380
Epoch 5/15
19/19 [==============================] - 0s 2ms/step - loss: 2.8139 - accuracy: 0.5545
Epoch 6/15
19/19 [==============================] - 0s 2ms/step - loss: 2.5233 - accuracy: 0.5545
Epoch 7/15
19/19 [==============================] - 0s 2ms/step - loss: 2.2155 - accuracy: 0.5578
Epoch 8/15
19/19 [==============================] - 0s 2ms/step - loss: 1.8840 - accuracy: 0.5611
Epoch 9/15
19/19 [==============================] - 0s 2ms/step - loss: 1.5834 - accuracy: 0.5314
Epoch 10/15
19/19 [==============================] - 0s 2ms/step - loss: 1.2625 - accuracy: 0.5578
Epoch 11/15
19/19 [==============================] - 0s 2ms/step - loss: 1.0255 - accuracy: 0.5941
Epoch 12/15
19/19 [==============================] - 0s 2ms/step - loss: 0.9045 - accuracy: 0.6139
Epoch 13/15
19/19 [==============================] - 0s 2ms/step - loss: 0.8331 - accuracy: 0.6106
Epoch 14/15
19/19 [==============================] - 0s 2ms/step - loss: 0.7851 - accuracy: 0.6337
Epoch 15/15
19/19 [==============================] - 0s 2ms/step - loss: 0.7513 - accuracy: 0.6403

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