Prepare features and labels

Le tutoriel qui sert de référence pour celui-ci est Preparing features and labels de Sequences, Time Series and Prediction (Coursera/Semaine 2).

In this case our feature is effectively a number of values in the series, with our label being the next value. We’ll call that number of values that will treat as our feature, the window size, where we’re taking a window of the data and training an ML model to predict the next value. So for example, if we take our time series data, say, 30 days at a time, we’ll use 30 values as the feature and the next value is the label

https://www.coursera.org/learn/tensorflow-sequences-time-series-and-prediction/lecture/TYErD/preparing-features-and-labels

Dans une time série les inputs sont les données sur une fenêtre et le label est la donnée au temps t+1

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

Créons un dataset

exempledataset = tf.data.Dataset.range(7)
list(exempledataset.as_numpy_iterator()) 
[0, 1, 2, 3, 4, 5, 6]

Notre fenêtre (pour créer notre jeu de données d’apprentissage) est ici 2, c’est à dire 2 éléments à chaque fois que c’est possible

exemple = exempledataset.window(2)
for window in exemple: 
  print(list(window.as_numpy_iterator()))
[0, 1]
[2, 3]
[4, 5]
[6]

Avec une fenêtre de 3

exemple = exempledataset.window(3)
for window in exemple: 
  print(list(window.as_numpy_iterator())) 
[0, 1, 2]
[3, 4, 5]
[6]

Par défaut shift = None

exemple = exempledataset.window(2, shift=None)
for window in exemple: 
  print(list(window.as_numpy_iterator()))
[0, 1]
[2, 3]
[4, 5]
[6]

Avec un shift de 1 élément

exemple = exempledataset.window(2, shift=1)
for window in exemple: 
  print(list(window.as_numpy_iterator())) 
[0, 1]
[1, 2]
[2, 3]
[3, 4]
[4, 5]
[5, 6]
[6]

Avec un shit de 2 éléments

exemple = exempledataset.window(2, shift=2)
for window in exemple: 
  print(list(window.as_numpy_iterator())) 
[0, 1]
[2, 3]
[4, 5]
[6]

Avec un shift de 3

exemple = exempledataset.window(2, shift=3)
for window in exemple: 
  print(list(window.as_numpy_iterator())) 
[0, 1]
[3, 4]
[6]

Si on veut, ce qui est souhaitable, voire obligatoire, que tous les paquets de données aient le même effectif, on utilise drop remainder

exemple = exempledataset.window(2, shift=1, drop_remainder=True)
for window in exemple: 
  print(list(window.as_numpy_iterator())) 
[0, 1]
[1, 2]
[2, 3]
[3, 4]
[4, 5]
[5, 6]

Créons un nouveau jeu de données, fenêtre de 5, shift = 1, drop_remainder = True

dataset=tf.data.Dataset.range(10)
dataset=dataset.window(5, shift=1, drop_remainder=True)
for window in dataset:
  print(list(window.as_numpy_iterator())) 
[0, 1, 2, 3, 4]
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]
[3, 4, 5, 6, 7]
[4, 5, 6, 7, 8]
[5, 6, 7, 8, 9]
dataset=tf.data.Dataset.range(10)
dataset=dataset.window(5, shift=1, drop_remainder=True)
dataset=dataset.flat_map(lambda elt:elt.batch(5))
for unelt in dataset:
  print(unelt.numpy())
[0 1 2 3 4]
[1 2 3 4 5]
[2 3 4 5 6]
[3 4 5 6 7]
[4 5 6 7 8]
[5 6 7 8 9]

Pour avoir des numpy lists, ce qui est nécessaire avec le réseau de neurones

dataset=tf.data.Dataset.range(10)
dataset=dataset.window(5, shift=1, drop_remainder=True)
dataset=dataset.flat_map(lambda window:window.batch(5))
for window in dataset:
  print(window.numpy())
[0 1 2 3 4]
[1 2 3 4 5]
[2 3 4 5 6]
[3 4 5 6 7]
[4 5 6 7 8]
[5 6 7 8 9]

Pour séparer les labels :

dataset=tf.data.Dataset.range(10)
dataset=dataset.window(5, shift=1, drop_remainder=True)
dataset=dataset.flat_map(lambda window:window.batch(5))
dataset=dataset.map(lambda window: (window[:-1], window[-1:]))
for x, y in dataset:
  print(x.numpy(), y.numpy())
[0 1 2 3] [4]
[1 2 3 4] [5]
[2 3 4 5] [6]
[3 4 5 6] [7]
[4 5 6 7] [8]
[5 6 7 8] [9]

Puis on shuffle les données

dataset=tf.data.Dataset.range(10)
dataset=dataset.window(5, shift=1, drop_remainder=True)
dataset=dataset.flat_map(lambda window:window.batch(5))
dataset=dataset.map(lambda window: (window[:-1], window[-1:]))
dataset=dataset.shuffle(buffer_size=10)
for x, y in dataset:
  print(x.numpy(), y.numpy())

Le buffer_size est égal au nombre de données dont on dispose ici

[3 4 5 6] [7]
[4 5 6 7] [8]
[5 6 7 8] [9]
[0 1 2 3] [4]
[1 2 3 4] [5]
[2 3 4 5] [6]

Pour terminer, on batch les données.

dataset=tf.data.Dataset.range(10)
dataset=dataset.window(5, shift=1, drop_remainder=True)
dataset=dataset.flat_map(lambda window:window.batch(5))
dataset=dataset.map(lambda window: (window[:-1], window[-1:]))
dataset=dataset.shuffle(buffer_size=10)
dataset=dataset.batch(2).prefetch(1)
for x, y in dataset:
  print(x.numpy(), y.numpy())
[[5 6 7 8]
 [2 3 4 5]] [[9]
 [6]]
[[1 2 3 4]
 [0 1 2 3]] [[5]
 [4]]
[[4 5 6 7]
 [3 4 5 6]] [[8]
 [7]]