# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

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

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
!pip install tensorflow_probability==0.12.2
import tensorflow_probability as tfp
#title Import and set ups
%matplotlib inline
import matplotlib as mpl
from matplotlib import pylab as plt
import matplotlib.dates as mdates
import seaborn as sns
import pandas as pd

import collections

import numpy as np
import tensorflow.compat.v2 as tf
import tensorflow_probability as tfp

from tensorflow_probability import distributions as tfd
from tensorflow_probability import sts

tf.enable_v2_behavior()
#tfp.sts.build_factored_surrogate_posterior(model=demand_model)
"""
Importing the dataset
"""
df = pd.read_csv('../input/household-energy-consumption/Household_Energy_Consumption.csv')
df.head()
df.shape
new = df["Sub_metering_1"].str.split(".", n = 1, expand = True)
df["Sub_metering_1"] = new[0]
new1 = df["Sub_metering_2"].str.split(".", n = 1, expand = True)
df["Sub_metering_2"] = new1[0]
df["Sub_metering_1"] = df['Sub_metering_1'].str.replace('?', '0').astype(float)
df["Sub_metering_2"] = df['Sub_metering_2'].str.replace('?', '0').astype(float)
df.info()
df.fillna(0, inplace=True)
df['Meter'] = df.apply(lambda row: row['Sub_metering_1'] + row['Sub_metering_2'] + row['Sub_metering_3'], axis=1)
df.isna().sum()
df['Date1'] = pd.to_datetime(df['Date1'])
df.set_index('Date1', inplace=True)
df.head()
df1 = df['Meter']
df1_hourly = df1.resample('H').sum()
df1_Daily = df1.resample('D').sum()
df1_weekly = df1.resample('W').sum()
df1_monthly = df1.resample('M').sum()
num_forecast_steps = 24 * 7 * 2 # Two weeks.
demand_training_data = df1_hourly[:-num_forecast_steps]
demand_training_data.shape
def build_model(observed_time_series):
    
    hour_of_day_effect = sts.Seasonal(num_seasons=24, observed_time_series=observed_time_series,
      name='hour_of_day_effect')
    day_of_week_effect = sts.Seasonal(num_seasons = 7, num_steps_per_season=24, observed_time_series=observed_time_series,
      name='day_of_week_effect')
    week_of_year_effect = sts.Seasonal(num_seasons = 52, num_steps_per_season=168, observed_time_series=observed_time_series,
      name='week_of_year_effect')    
    month_of_year_effect = sts.Seasonal(num_seasons = 12, num_steps_per_season=728, observed_time_series=observed_time_series,
      name='month_of_year_effect')    
    autoregressive = sts.Autoregressive(order=1, observed_time_series=observed_time_series, name='autoregressive')
    model = sts.Sum([hour_of_day_effect, day_of_week_effect, week_of_year_effect, month_of_year_effect, autoregressive],
                   observed_time_series=observed_time_series)
    return model
trainingdata = demand_training_data.to_numpy().reshape(-1, 1)
"""
Flip to TPU usage for model training
"""
# detect and init the TPU
#tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()

# instantiate a distribution strategy
#tpu_strategy = tf.distribute.experimental.TPUStrategy(tpu)

# instantiating the model in the strategy scope creates the model on the TPU
#with tpu_strategy.scope():
#    demand_model = build_model(trainingdata)
#    variational_posteriors = tfp.sts.build_factored_surrogate_posterior(model=demand_model)

# train model normally
#model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=…)
demand_model = build_model(trainingdata)
%time
# Build the variational surrogate posteriors `qs`. Using GPU
variational_posteriors = tfp.sts.build_factored_surrogate_posterior(model=demand_model)
demand_model.components
variational_posteriors