C4W4: Using real world data#

Daily Minimum Temperatures in Melbourne dataset

import csv
import pickle
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from dataclasses import dataclass
TEMPERATURES_CSV = '../../../data/daily-min-temperatures.csv'

with open(TEMPERATURES_CSV, 'r') as csvfile:
    for _ in range (3):
        print(csvfile.readline())
"Date","Temp"

"1981-01-01",20.7

"1981-01-02",17.9
def plot_series(time, series, format="-", start=0, end=None):
    plt.plot(time[start:end], series[start:end], format)
    plt.xlabel("Time")
    plt.ylabel("Value")
    plt.grid(True)
def parse_data_from_file(filename):
    
    times = []
    temperatures = []

    with open(filename) as csvfile:
        
        reader = csv.reader(csvfile, delimiter=',')
        next(reader)
        
        for row in reader:
            times.append(row[0])
            temperatures.append(float(row[1]))
            
    return times, temperatures
@dataclass
class G:
    TEMPERATURES_CSV = '../../../data/daily-min-temperatures.csv'
    times, temperatures = parse_data_from_file(TEMPERATURES_CSV)
    TIME = np.array(times)
    SERIES = np.array(temperatures)
    SPLIT_TIME = 2500
    WINDOW_SIZE = 64
    BATCH_SIZE = 256
    SHUFFLE_BUFFER_SIZE = 1000


plt.figure(figsize=(10, 6))
plot_series(G.TIME, G.SERIES)
plt.show()
../../_images/c4w4_using_real_world_data_6_01.png
def train_val_split(time, series, time_step=G.SPLIT_TIME):

    time_train = time[:time_step]
    series_train = series[:time_step]
    time_valid = time[time_step:]
    series_valid = series[time_step:]

    return time_train, series_train, time_valid, series_valid


time_train, series_train, time_valid, series_valid = train_val_split(G.TIME, G.SERIES)
def windowed_dataset(series, window_size=G.WINDOW_SIZE, batch_size=G.BATCH_SIZE, shuffle_buffer=G.SHUFFLE_BUFFER_SIZE):
    ds = tf.data.Dataset.from_tensor_slices(series)
    ds = ds.window(window_size + 1, shift=1, drop_remainder=True)
    ds = ds.flat_map(lambda w: w.batch(window_size + 1))
    
    ds = ds.shuffle(shuffle_buffer)
    ds = ds.map(lambda w: (w[:-1], w[-1]))

    ds = ds.batch(batch_size).cache().prefetch(tf.data.AUTOTUNE)
    
    return ds

train_set = windowed_dataset(series_train, window_size=64, batch_size=256, shuffle_buffer=1000)
def create_model():
    
    model = tf.keras.models.Sequential([
        tf.keras.layers.Conv1D(64, 3, padding='causal', activation='relu', input_shape=[G.WINDOW_SIZE, 1]),
        tf.keras.layers.LSTM(64, return_sequences=True),
        tf.keras.layers.LSTM(32),
        tf.keras.layers.Dense(32, activation='relu'),
        tf.keras.layers.Dense(1)
    ]) 

    model.compile(optimizer='adam',
                  loss='huber',
                  metrics=["mae"])  

    return model
model = create_model()

history = model.fit(train_set, epochs=50)
Epoch 1/50
10/10 [==============================] - 7s 221ms/step - loss: 9.2751 - mae: 9.7736
Epoch 2/50
10/10 [==============================] - 1s 42ms/step - loss: 7.4739 - mae: 7.9707
Epoch 3/50
10/10 [==============================] - 1s 47ms/step - loss: 5.6399 - mae: 6.1280
Epoch 4/50
10/10 [==============================] - 1s 48ms/step - loss: 4.0485 - mae: 4.5253
Epoch 5/50
10/10 [==============================] - 1s 46ms/step - loss: 3.0455 - mae: 3.5153
Epoch 6/50
10/10 [==============================] - 1s 42ms/step - loss: 2.7269 - mae: 3.1937
Epoch 7/50
10/10 [==============================] - 1s 40ms/step - loss: 2.7261 - mae: 3.1936
Epoch 8/50
10/10 [==============================] - 1s 45ms/step - loss: 2.7124 - mae: 3.1792
Epoch 9/50
10/10 [==============================] - 1s 44ms/step - loss: 2.6910 - mae: 3.1571
Epoch 10/50
10/10 [==============================] - 1s 47ms/step - loss: 2.6817 - mae: 3.1470
Epoch 11/50
10/10 [==============================] - 1s 43ms/step - loss: 2.6579 - mae: 3.1230
Epoch 12/50
10/10 [==============================] - 1s 47ms/step - loss: 2.5972 - mae: 3.0622
Epoch 13/50
10/10 [==============================] - 1s 48ms/step - loss: 2.4299 - mae: 2.8890
Epoch 14/50
10/10 [==============================] - 1s 40ms/step - loss: 2.1392 - mae: 2.5958
Epoch 15/50
10/10 [==============================] - 1s 42ms/step - loss: 1.9019 - mae: 2.3555
Epoch 16/50
10/10 [==============================] - 1s 40ms/step - loss: 1.7733 - mae: 2.2215
Epoch 17/50
10/10 [==============================] - 1s 44ms/step - loss: 1.7260 - mae: 2.1777
Epoch 18/50
10/10 [==============================] - 1s 40ms/step - loss: 1.6671 - mae: 2.1164
Epoch 19/50
10/10 [==============================] - 1s 41ms/step - loss: 1.6247 - mae: 2.0704
Epoch 20/50
10/10 [==============================] - 1s 39ms/step - loss: 1.6008 - mae: 2.0477
Epoch 21/50
10/10 [==============================] - 1s 42ms/step - loss: 1.5897 - mae: 2.0354
Epoch 22/50
10/10 [==============================] - 1s 40ms/step - loss: 1.5413 - mae: 1.9850
Epoch 23/50
10/10 [==============================] - 1s 39ms/step - loss: 1.5210 - mae: 1.9631
Epoch 24/50
10/10 [==============================] - 1s 42ms/step - loss: 1.5125 - mae: 1.9558
Epoch 25/50
10/10 [==============================] - 1s 40ms/step - loss: 1.5417 - mae: 1.9868
Epoch 26/50
10/10 [==============================] - 1s 40ms/step - loss: 1.5078 - mae: 1.9504
Epoch 27/50
10/10 [==============================] - 1s 40ms/step - loss: 1.5002 - mae: 1.9405
Epoch 28/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4951 - mae: 1.9375
Epoch 29/50
10/10 [==============================] - 1s 39ms/step - loss: 1.4901 - mae: 1.9312
Epoch 30/50
10/10 [==============================] - 1s 41ms/step - loss: 1.4941 - mae: 1.9371
Epoch 31/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4897 - mae: 1.9310
Epoch 32/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4885 - mae: 1.9299
Epoch 33/50
10/10 [==============================] - 1s 39ms/step - loss: 1.4897 - mae: 1.9306
Epoch 34/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4783 - mae: 1.9210
Epoch 35/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4961 - mae: 1.9366
Epoch 36/50
10/10 [==============================] - 1s 39ms/step - loss: 1.4793 - mae: 1.9219
Epoch 37/50
10/10 [==============================] - 1s 39ms/step - loss: 1.4917 - mae: 1.9321
Epoch 38/50
10/10 [==============================] - 1s 40ms/step - loss: 1.5165 - mae: 1.9584
Epoch 39/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4927 - mae: 1.9314
Epoch 40/50
10/10 [==============================] - 1s 38ms/step - loss: 1.4809 - mae: 1.9223
Epoch 41/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4836 - mae: 1.9226
Epoch 42/50
10/10 [==============================] - 1s 40ms/step - loss: 1.5097 - mae: 1.9530
Epoch 43/50
10/10 [==============================] - 1s 39ms/step - loss: 1.5025 - mae: 1.9436
Epoch 44/50
10/10 [==============================] - 1s 39ms/step - loss: 1.4817 - mae: 1.9218
Epoch 45/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4799 - mae: 1.9216
Epoch 46/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4672 - mae: 1.9083
Epoch 47/50
10/10 [==============================] - 1s 41ms/step - loss: 1.4749 - mae: 1.9142
Epoch 48/50
10/10 [==============================] - 1s 39ms/step - loss: 1.4609 - mae: 1.9008
Epoch 49/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4638 - mae: 1.9026
Epoch 50/50
10/10 [==============================] - 1s 40ms/step - loss: 1.4622 - mae: 1.9024
def compute_metrics(true_series, forecast):
    
    mse = tf.keras.metrics.mean_squared_error(true_series, forecast).numpy()
    mae = tf.keras.metrics.mean_absolute_error(true_series, forecast).numpy()

    return mse, mae
def model_forecast(model, series, window_size):
    ds = tf.data.Dataset.from_tensor_slices(series)
    ds = ds.window(window_size, shift=1, drop_remainder=True)
    ds = ds.flat_map(lambda w: w.batch(window_size))
    ds = ds.batch(32).cache().prefetch(tf.data.AUTOTUNE)

    forecast = model.predict(ds)

    return forecast
forecast_series = G.SERIES[G.SPLIT_TIME - G.WINDOW_SIZE:-1]
rnn_forecast = model_forecast(model, forecast_series, G.WINDOW_SIZE).squeeze()

plt.figure(figsize=(10, 6))
plot_series(time_valid, series_valid)
plot_series(time_valid, rnn_forecast)
36/36 [==============================] - 1s 12ms/step
../../_images/c4w4_using_real_world_data_13_1.png
mse, mae = compute_metrics(series_valid, rnn_forecast)

print(f"mse: {mse:.2f}, mae: {mae:.2f} for forecast")
mse: 5.48, mae: 1.83 for forecast

To pass this assignment your forecast should achieve a MSE of 6 or less and a MAE of 2 or less.

# model.save("my_model.h5")