# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 2
#     language: python
#     name: python2
# ---

# %load_ext autoreload
# %matplotlib inline

#import dependencies
import numpy as np
# fix random seed for reproducibility
seed = 155
np.random.seed(seed)

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import time

# +
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import sys

# add the 'src' directory as one where we can import modules
src_dir = os.path.join(os.getcwd(), os.pardir,'src')
sys.path.append(src_dir)
# -

# ## Load dataset

# %store -r ili_GLL

l = len(ili_GLL.columns)
print("The data contains {} features".format(l))
ili_GLL.head()

nstates = len(ili_GLL.state.unique())
print("Number of location : {}".format(nstates))

# ## LSTM Data Preparation

# ## Prepare Dataset

# +
#we put everything together
#sepate by states
datasets = {}
states_label = ili_GLL.state.unique()
for s in states_label:
    datasets[s] = ili_GLL[(ili_GLL.state == s)]
    datasets[s].drop(['state'], 1, inplace=True)

nstates = len(datasets)
print("Number of location : {}".format(nstates))


# -

def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    """
    Frame a time series as a supervised learning dataset.
    Arguments:
        data: Sequence of observations as a list or NumPy array.
        n_in: Number of lag observations as input (X).
        n_out: Number of observations as output (y).
        dropnan: Boolean whether or not to drop rows with NaN values.
    Returns:
       Pandas DataFrame of series framed for supervised learning.
    """
    n_vars = 1 if type(data) is list else data.shape[1]
    print("The data contains {} features".format(n_vars))
    df = DataFrame(data)
    cols, names = list(), list()
    # input sequence (t-n, ... t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    # forecast sequence (t, t+1, ... t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
        else:
            names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    # put it all together
    agg = concat(cols, axis=1)
    agg.columns = names
    # drop rows with NaN values
    n_vars = len(agg.columns)
    print("The reframed data contains {} features".format(n_vars))

    if dropnan:
        agg.dropna(inplace=True)
        return agg


# scale train and test data to [-1, 1]
def scale(train, test):
    # fit scaler
    scaler = MinMaxScaler(feature_range=(-1, 1))
    scaler = scaler.fit(train)
    # transform train
    train = train.reshape(train.shape[0], train.shape[1])
    train_scaled = scaler.transform(train)
    # transform test
    test = test.reshape(test.shape[0], test.shape[1])
    test_scaled = scaler.transform(test)
    return scaler, train_scaled, test_scaled


# inverse scaling for a forecasted value
def invert_scale(scaler, X, yhat):
    new_row = [x for x in X] + [yhat]
    array = numpy.array(new_row)
    array = array.reshape(1, len(array))
    inverted = scaler.inverse_transform(array)
    return inverted[0, -1]


# One Hot encoder
def encode_category(data):
    #check the categories
    df = pd.get_dummies(data)
    return df


# parse the data into states
def parse_data(states_label, datasets, n_weeks = 260):
    """
    return a dictionary
    """
    parse_data = {}
    for state in states_label:
        data = datasets[state]
        names = list(data.columns.values)
        
        #drop date value
        if 'date' in names:
            data.drop(['date'], 1, inplace=True)

        # make sure that every states has the same number of weeks
        if(len(data)>= n_weeks):
            parse_data[state] = data
    return parse_data


def reframe_data(data_states, n_weeks =1,n_features =1 ):
    reframed_data = []
    for state in data_states:
        values=data_states[state]
        # ensure all data is float
        values = values.astype('float32')
        # normalize features
        reframed = series_to_supervised(values, n_weeks, n_features)
        # we are predicting ili activity
        reframed_data.append(reframed)
    return reframed_data


def scale_data(values):
    scaler = MinMaxScaler(feature_range=(0, 1))
    scaled_data = scaler.fit_transform(values)
    return scaled_data, scaler


temp_data = data(states_label, datasets, encoder) 
print(len(temp_data))

temp_reframed = reframe_data(temp_data)
print(len(temp_reframed))

n_total_years = 5*52 # equivalent of 5 years of data
n_train_weeks = 3*52 # equivalent of 3 years of data
print("number of weeks in a year: {}".format(n_total_years))
print("number of weeks in the training set : {}".format(n_train_weeks))



print "Number of training samples: %d"%train_features[0].shape[0]
print "Number of test samples: %d"%test_features[0].shape[0]
print "Timestep: %d"%train_features[0].shape[1]
print "Features: %d"%train_features[0].shape[2]

# optional
from keras.callbacks import ModelCheckpoint
# specify filepath- this will write a new file for each epoch with the epoch number contained within the filename
filepath="nn_weights-{epoch:02d}.hdf5"
checkpoint = keras.callbacks.ModelCheckpoint(filepath, monitor='val_acc', verbose=0, 
                                             save_weights_only=False, save_best_only=False, mode='max')

# +
# %autoreload
import time
import os

#from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Input, concatenate
from keras.models import Model

#allow to use time distributed content
#from keras.layers import TimeDistributed
from keras.callbacks import TensorBoard

import numpy as np
from numpy import concatenate

from math import sqrt
import matplotlib.pyplot as plt

# +
data_dim = 13
timesteps = 1
batch_size = 52
states = temp_data.keys()

def simple_rnn_model(data_dim = 13,timesteps = 1,batch_size = 52,states = temp_data.keys(), n_neurons = 50):
    #dataLength =  4 weeks
    stateInputs = {}
    stateLayers = []
    i = 0
    for state in states:
        inputName = "{}_input".format(state)
        stateInputs[inputName] = Input(shape=(timesteps,data_dim),
                                       batch_shape =(batch_size, timesteps, data_dim), 
                                       name=inputName)
    for state in stateInputs:
        stateL = LSTM(n_neurons, return_sequences=False, stateful=True,
                            batch_input_shape=(batch_size, timesteps, data_dim))(stateInputs[state])
        stateLayers.append(stateL)
     
    #combined the output
    output = keras.layers.concatenate(stateLayers)
    output = Dense(1, activation='relu', name='wheighthedAverage_output')(output)
    stateInput = stateInputs.values()
    
    model = Model(inputs = stateInput, outputs = [output])
    model.compile(optimizer='adam', loss='mse', metrics=['accuracy'])
    
    return model


# -

my_first_rnn = simple_rnn_model(data_dim,timesteps,batch_size,states)

processed_dir = os.path.join(os.getcwd(),os.pardir, 'models')
processed_dir

plot_model_history

# verbose=0 suppresses the file writing message
# note that the fit method expects a list of callbacks
start = time.time()
my_first_rnn_fitted = my_first_rnn.fit(
    train_features,
    train_label[0], #label for the targeted state
    validation_data= (
        test_features,
        test_label[0] ),
    epochs=2000,
    verbose=0,
    shuffle = False,
    batch_size=52,
    callbacks=[checkpoint],
    initial_epoch=0
)
end = time.time()
print "Model took %0.2f seconds to train"%(end - start)


# run diagnostic experiments
def run():
    # load dataset
    series = read_csv('shampoo-sales.csv', header=0, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)
    # transform data to be stationary
    raw_values = series.values
    diff_values = difference(raw_values, 1)
    # transform data to be supervised learning
    supervised = timeseries_to_supervised(diff_values, 1)
    supervised_values = supervised.values
    # split data into train and test-sets
    train, test = supervised_values[0:-12], supervised_values[-12:]
    # transform the scale of the data
    scaler, train_scaled, test_scaled = scale(train, test)
    # fit and evaluate model
    train_trimmed = train_scaled[2:, :]
    # config
    repeats = 10
    n_batch = 4
    n_epochs = 500
    n_neurons = 1
    # run diagnostic tests
    for i in range(repeats):
        history = fit_lstm(train_trimmed, test_scaled, raw_values, scaler, n_batch, n_epochs, n_neurons)
        pyplot.plot(history['train'], color='blue')
        pyplot.plot(history['test'], color='orange')
        print('%d) TrainRMSE=%f, TestRMSE=%f' % (i, history['train'].iloc[-1], history['test'].iloc[-1]))
    pyplot.savefig('epochs_diagnostic.png')


# entry point
run()

# [loss, accuracy]
my_first_rnn.evaluate(test_features, test_label[0],batch_size=52, verbose=0)


# train_data.size % batch_size = 0
def plot_model_history(model_history):
    fig, axs = plt.subplots(1,2,figsize=(15,5))
    # summarize history for accuracy
    axs[0].plot(range(1,len(model_history.history['acc'])+1),model_history.history['acc'])
    axs[0].plot(range(1,len(model_history.history['val_acc'])+1),model_history.history['val_acc'])
    axs[0].set_title('Model Accuracy')
    axs[0].set_ylabel('Accuracy')
    axs[0].set_xlabel('Epoch')
    axs[0].set_xticks(np.arange(1,len(model_history.history['acc'])+1),len(model_history.history['acc'])/10)
    axs[0].legend(['train', 'val'], loc='best')
    # summarize history for loss
    axs[1].plot(range(1,len(model_history.history['loss'])+1),model_history.history['loss'])
    axs[1].plot(range(1,len(model_history.history['val_loss'])+1),model_history.history['val_loss'])
    axs[1].set_title('Model Loss')
    axs[1].set_ylabel('Loss')
    axs[1].set_xlabel('Epoch')
    axs[1].set_xticks(np.arange(1,len(model_history.history['loss'])+1),len(model_history.history['loss'])/10)
    axs[1].legend(['train', 'val'], loc='best')
    plt.show()


plot_model_history(my_first_rnn_fitted)


def plot_model_history2(my_first_nn_fitted):
    fig, (ax1, ax2) = plt.subplots(2, 1)
    ax1.plot(range(len(my_first_nn_fitted.history['loss'])), my_first_nn_fitted.history['loss'],linestyle='-', color='blue',label='Training', lw=2)
    ax1.plot(range(len(np.array(test_over_time)[:,0])), np.array(test_over_time)[:,0], linestyle='-', color='green',label='Test', lw=2)
    ax2.plot(range(len(my_first_nn_fitted.history['acc'])), my_first_nn_fitted.history['acc'],linestyle='-', color='blue',label='Training', lw=2)
    ax2.plot(range(len(np.array(test_over_time)[:,1])), np.array(test_over_time)[:,1], linestyle='-', color='green',label='Test', lw=2)
    leg = ax1.legend(bbox_to_anchor=(0.7, 0.9), loc=2, borderaxespad=0.,fontsize=13)
    ax1.set_xticklabels('')
    #ax1.set_yscale('log')
    ax2.set_xlabel('# Epochs',fontsize=14)
    ax1.set_ylabel('Loss',fontsize=14)
    ax2.set_ylabel('Accuracy',fontsize=14)
    plt.show()


plot_model_history(my_first_rnn_fitted)

# ## Model

plot_model_history(my_first_rnn_fitted)







StarcoderdataJupyterScriptsDedupFiltered