application_vnd.jupyter.stderr_output_2.png text_plain_output_1.png
from keras.callbacks import EarlyStopping

from keras.initializers import Identity

from keras.layers import Input, Dense, Flatten, Dropout, Lambda, \

from keras.layers import Input, LSTM, Dense, BatchNormalization, Lambda, Flatten, Reshape

from keras.layers.normalization import BatchNormalization

from keras.models import Model

from keras.models import Sequential, Model

from keras.optimizers import Adam, SGD, RMSprop

import matplotlib.pyplot as plt

import numpy as np

import numpy as np # linear algebra

import pandas as pd

import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

def read_data():
    data = pd.read_csv('../input/datatrain4/train4.csv')
    data = data.values
    return data

data = read_data()

def handle_country_text(data):
    stats = list(np.unique(data[:, 2]))
    for idx, d in enumerate(data):
        country = d[2]
        id = stats.index(country)
        d[2] = id
    return (stats, data)

def create_sequences(data, stats):
    sequences = []
    to_compute = []
    for idx, s in enumerate(stats):
        seq = data[data[:, 2] == idx]
        if pd.isnull(seq[0, 1]):
            seq = np.delete(seq, [1], 1)
        else:
            to_compute.append(seq)
            stats_p = list(np.unique(seq[:, 1]))
            for idx2, s2 in enumerate(stats_p):
                seqs2 = seq[seq[:, 1] == s2]
                seqs2 = np.delete(seqs2, [0, 1, 3], 1)
                for idx, value in enumerate(reversed(seqs2[:, 1:])):
                    if idx + 1 < len(seqs2):
                        cases = value[0] - seqs2[-(idx + 2), 1]
                        deaths = value[1] - seqs2[-(idx + 2), 2]
                        seqs2[-(idx + 1), 1] = cases
                        seqs2[-(idx + 1), 2] = deaths
                offset = float(idx2) / 10
                seqs2[:, 0] = seqs2[:, 0] + offset
                sequences.append(seqs2)
            continue
        seq = np.delete(seq, [0, 2], 1)
        for idx, value in enumerate(reversed(seq[:, 1:])):
            if idx + 1 < len(seq):
                cases = value[0] - seq[-(idx + 2), 1]
                deaths = value[1] - seq[-(idx + 2), 2]
                seq[-(idx + 1), 1] = cases
                seq[-(idx + 1), 2] = deaths
        sequences.append(seq)
    return np.array(sequences)

sequences = create_sequences(data, stats)
sequences = np.array(sequences)
sequences_train = np.delete(sequences, [0], 2)
sequences_train = np.array(sequences_train)

def dain(input):
    n_features = 2
    mean = Lambda(lambda x: K.mean(input, axis=1))(input)
    adaptive_avg = Dense(n_features, kernel_initializer=Identity(gain=1.0), bias=False)(mean)
    adaptive_avg = Reshape((1, n_features))(adaptive_avg)
    X = Lambda(lambda inputs: inputs[0] - inputs[1])([input, adaptive_avg])
    std = Lambda(lambda x: K.mean(x ** 2, axis=1))(X)
    std = Lambda(lambda x: K.sqrt(x + 1e-08))(std)
    adaptive_std = Dense(n_features, bias=False)(std)
    adaptive_std = Reshape((1, n_features))(adaptive_std)
    X = Lambda(lambda inputs: inputs[0] / inputs[1])([X, adaptive_std])
    avg = Lambda(lambda x: K.mean(x, axis=1))(X)
    gate = Dense(n_features, activation='sigmoid', kernel_initializer=Identity(gain=1.0), bias=False)(avg)
    gate = Reshape((1, n_features))(gate)
    X = Lambda(lambda inputs: inputs[0] * inputs[1])([X, gate])
    return (X, adaptive_avg, adaptive_std)

def build_generator(encoder_input_shape, missing_len, verbose=True):
    learning_rate = 0.0002
    optimizer = Adam(lr=learning_rate)
    generator_decoder_type = 'seq2seq'
    encoder_inputs = Input(shape=encoder_input_shape)
    hidden, avg, std = dain(encoder_inputs)
    decoder_outputs = []
    encoder = LSTM(128, return_sequences=True, return_state=True)
    lstm_outputs, state_h, state_c = encoder(hidden)
    if generator_decoder_type == 'seq2seq':
        states = [state_h, state_c]
        decoder_lstm = LSTM(128, return_sequences=True, return_state=True)
        decoder_cases = Dense(1, activation='relu')
        decoder_deaths = Dense(1, activation='relu')
        all_outputs_c = []
        all_outputs_d = []
        inputs = lstm_outputs
        for idx in range(missing_len):
            outputs, state_h, state_c = decoder_lstm(inputs, initial_state=states)
            inputs = outputs
            outputs = BatchNormalization()(outputs)
            outputs = Flatten()(outputs)
            outputs_cases = decoder_cases(outputs)
            outputs_deaths = decoder_deaths(outputs)
            states = [state_h, state_c]
            std_c = Lambda(lambda inputs: inputs[:, 0, 0])(std)
            avg_c = Lambda(lambda inputs: inputs[:, 0, 0])(avg)
            outputs_cases = Multiply()([outputs_cases, std_c])
            outputs_cases = Add()([outputs_cases, avg_c])
            std_d = Lambda(lambda inputs: inputs[:, 0, 1])(std)
            avg_d = Lambda(lambda inputs: inputs[:, 0, 1])(avg)
            outputs_deaths = Multiply()([outputs_deaths, std_d])
            outputs_deaths = Add()([outputs_deaths, avg_d])
            all_outputs_c.append(outputs_cases)
            all_outputs_d.append(outputs_deaths)
        decoder_outputs_c = Lambda(lambda x: x)(outputs_cases)
        decoder_outputs_d = Lambda(lambda x: x)(outputs_deaths)
    model = Model(inputs=encoder_inputs, outputs=[decoder_outputs_c, decoder_outputs_d])
    model.compile(loss='mean_squared_logarithmic_error', optimizer=optimizer)
    return model

given = 80
missing = 1
total_missing = 33
model = build_generator(sequences_train[:, :given, :].shape[1:], missing)
es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=30)
history = model.fit(x=sequences_train[:, :given, :], y=[sequences_train[:, given:, 0], sequences_train[:, given:, 1]], epochs=1, validation_split=0.2, shuffle=True, callbacks=[es])
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper left')
plt.savefig('plots/losses.png')
plt.close()