import streamlit as st
from src.data import Energy_DataLoader
from src.model import Model_Load
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.graph_objects as go
from sklearn.metrics import mean_absolute_error,mean_squared_error
import numpy as np
import pandas as pd
from streamlit.components.v1 import html
from src.prediction import test_pred,val_pred
# hide menubar and header
hide_streamlit_style = """
"""
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
## Load model object
model_obj=Model_Load()
path='data/LD2011_2014.txt'
obj=Energy_DataLoader(path)
@st.cache_data
def convert_df(df):
return df.to_csv(index=False).encode('utf-8')
st.markdown("""
Energy Demand Forecasting Dashboard
by AI Planet
""", unsafe_allow_html=True)
with st.sidebar:
st.markdown("""
""", unsafe_allow_html=True)
# st.markdown(f"""
#
# """,unsafe_allow_html=True)
option=st.selectbox("Select Model",['TFT','Prophet'])
if option=='TFT':
print("TFT")
## TFT data
train_dataset,test_dataset,training,validation,earliest_time=obj.tft_data()
# st.write(earliest_time)
print(f"TRAINING ::START DATE ::{train_dataset['date'].min()} :: END DATE ::{train_dataset['date'].max()}")
print(f"TESTING ::START DATE ::{test_dataset['date'].min()} :: END DATE ::{test_dataset['date'].max()}")
consumer_list=train_dataset['consumer_id'].unique()
model=model_obj.energy_model_load(option)
with st.sidebar:
# st.success('Model Loaded successfully', icon="✅")
# st.markdown(f"""
#
#
# """,unsafe_allow_html=True)
consumer=st.selectbox("Select Consumer ID",consumer_list)
testing_results=test_pred(model,train_dataset=train_dataset,test_dataset=test_dataset
,consumer_id=consumer)
rmse=np.around(np.sqrt(mean_squared_error(testing_results['Lead_1'],testing_results['prediction'])),2)
mae=np.around(mean_absolute_error(testing_results['Lead_1'],testing_results['prediction']),2)
#-----------------------------------future prediction-----------------------------------------------
final_data=pd.concat([train_dataset,test_dataset])
consumer_data=final_data.loc[final_data['consumer_id']==consumer]
consumer_data.fillna(0,inplace=True)
date_list=[]
demand_prediction=[]
for i in range(24):
encoder_data = consumer_data[lambda x: x.hours_from_start > x.hours_from_start.max() - 192]
last_data = consumer_data[lambda x: x.hours_from_start == x.hours_from_start.max()]
# prediction date and time
date_list.append(encoder_data.tail(1).iloc[-1,:]['date'])
test_prediction = model.predict(encoder_data,
mode="prediction",
trainer_kwargs=dict(accelerator="cpu"),
return_x=True)
decoder_data = pd.concat(
[last_data.assign(date=lambda x: x.date + pd.offsets.Hour(i)) for i in range(1, 2)],
ignore_index=True,
)
decoder_data['hours_from_start']=decoder_data['hours_from_start'].max()+1
decoder_data["days_from_start"] = (decoder_data["date"] - earliest_time).apply(lambda x:x.days)
decoder_data['hour'] = decoder_data['date'].dt.hour
decoder_data['day'] = decoder_data['date'].dt.day
decoder_data['day_of_week'] = decoder_data['date'].dt.dayofweek
decoder_data['month'] = decoder_data['date'].dt.month
decoder_data['power_usage']=float(test_prediction.output[0][-1])
demand_prediction.append(float(test_prediction.output[0][-1]))
decoder_data['time_idx']=int(test_prediction.x['decoder_time_idx'][0][-1])
consumer_data=pd.concat([consumer_data,decoder_data])
consumer_data['lag_1']=consumer_data['power_usage'].shift(1)
consumer_data['lag_5']=consumer_data['power_usage'].shift(5)
consumer_data=consumer_data.reset_index(drop=True)
d2=pd.DataFrame({"date":date_list,"prediction":demand_prediction})[['date','prediction']]
d2['consumer_id']=consumer
print(f"TEST DATA = Consumer ID : {consumer} :: MAE : {mae} :: RMSE : {rmse}")
with st.sidebar:
st.markdown(f"""
""",unsafe_allow_html=True)
# st.write("Models Evalution")
st.dataframe(pd.DataFrame({"KPI":['RMSE','MAE'],"TFT":[8.67,6.48],"Prophet":[12.82,9.79]}).set_index('KPI'),width=300)
st.markdown(f"""
""",unsafe_allow_html=True)
st.dataframe(pd.DataFrame({"KPI":['RMSE','MAE'],"TFT":[rmse,mae]}).set_index('KPI'),width=300)
#--------------------------------------------------------------------------------------------------------------
# tabs
tab1,tab2=st.tabs(['📈Forecast Plot','🗃Forecast Table'])
#------------------------------------------------Tab-1-----------------------------------------------------------
# tab2.write(testing_results)
tab1.markdown("""
📈
Forecast Plot
""", unsafe_allow_html=True)
# testing_results['prediction']=testing_results['prediction'].astype('int')
training_data=train_dataset.loc[(train_dataset['consumer_id']==consumer)][['date','Lead_1']].iloc[-100:,:]
fig = go.Figure([
# go.Scatter(x=training_data['date'],y=training_data['Lead_1'],name='Train Observed',line=dict(color='blue')),
#go.Scatter(x=y_train_pred['ds'],y=y_train_pred['yhat'],name='Prophet Pred.(10 Item)',line=dict(color='blue', dash='dot')),
go.Scatter(x=testing_results['date'], y=testing_results['Lead_1'],name='Observed',line=dict(color='purple')),
go.Scatter(x=testing_results['date'],y=testing_results['prediction'],name='Historical Forecast',line=dict(color='purple', dash='dot')),
go.Scatter(x=d2['date'],y=d2['prediction'],name='Future Forecast',line=dict(color='Dark Orange', dash='dot'))])
fig.update_layout(
xaxis_title='Date',
yaxis_title='Energy Demand',
margin=dict(l=0, r=0, t=50, b=0),
xaxis=dict(title_font=dict(size=20)),
yaxis=dict(title_font=dict(size=20)))
fig.update_layout(width=800,height=400)
tab1.plotly_chart(fig)
#----------------------------------------------Tab-2------------------------------------------------------------
tab2.markdown("""
📃
Forecast Table
""", unsafe_allow_html=True)
final_r=pd.concat([d2[['date','consumer_id','prediction']],testing_results[['date','consumer_id','prediction']]]).sort_values('date').reset_index(drop=True)
csv = convert_df(final_r)
tab2.dataframe(final_r,width=500)
tab2.download_button(
"Download",
csv,
"file.csv",
"text/csv",
key='download-csv'
)
# except:
# st.sidebar.error('Model Not Loaded successfully!',icon="🚨")
elif option=='Prophet':
print("prophet")
# Prophet data
fb_train_data,fb_test_data,consumer_dummay=obj.fb_data()
# print('*'*50)
# fb_test_data
# print('*'*50)
print(f"TRAINING ::START DATE ::{fb_train_data['ds'].min()} :: END DATE ::{fb_train_data['ds'].max()}")
print(f"TESTING ::START DATE ::{fb_test_data['ds'].min()} :: END DATE ::{fb_test_data['ds'].max()}")
train_new=fb_train_data.drop('y',axis=1)
test_new=fb_test_data.drop('y',axis=1)
try:
model=model_obj.energy_model_load(option)
# with st.sidebar:
# st.success('Model Loaded successfully.', icon="✅")
except:
st.error('Model Not Loaded successfully!',icon="🚨")
with st.sidebar:
# st.markdown(f"""
#
#
# """,unsafe_allow_html=True)
consumer=st.selectbox("Select Consumer ID",consumer_dummay)
test_prediction=model.predict(test_new.loc[test_new[consumer]==1])
# train_prediction=model.predict(train_new.loc[train_new[consumer]==1])
y_true_test=fb_test_data.loc[fb_test_data[consumer]==1]
y_true_train=fb_train_data.loc[fb_train_data[consumer]==1]
# y_train_pred=train_prediction[['ds','yhat']].iloc[-60:,:]
y_train_true=y_true_train[['ds','y']].iloc[-60:,:]
y_test_pred=test_prediction[['ds','yhat']]
y_test_true=y_true_test[['ds','y']]
fb_final=pd.concat([fb_train_data,fb_test_data])
fb_consumer=fb_final.loc[fb_final[consumer]==1]
date_list=[]
prediction_list=[]
for i in range(24):
next_prediction=fb_consumer.tail(1).drop('y',axis=1) # drop target of last 01/01/2015 00:00:00
# print(next_prediction)
prediction=model.predict(next_prediction) # pass other feature value to the model
# print('*'*20)
# print("DateTime :: ",prediction['ds'][0])
# print("Prediction ::",prediction['yhat'][0])
date_list.append(prediction['ds'][0]) ## append the datetime of prediction
prediction_list.append(prediction['yhat'][0]) ## append the next timestep prediction
last_data = fb_consumer[lambda x: x.ds == x.ds.max()] # last date present in data
#--------------------------next timestep data simulate-------------------------------------------------------------
decoder_data = pd.concat(
[last_data.assign(ds=lambda x: x.ds + pd.offsets.Hour(i)) for i in range(1, 2)],
ignore_index=True,
)
decoder_data['hour'] = decoder_data['ds'].dt.hour
decoder_data['day'] = decoder_data['ds'].dt.day
decoder_data['day_of_week'] = decoder_data['ds'].dt.dayofweek
decoder_data['month'] = decoder_data['ds'].dt.month
decoder_data['power_usage']=prediction['yhat'][0] # assume next timestep prediction as actual
fb_consumer=pd.concat([fb_consumer,decoder_data]) # append that next timestep data to into main data
fb_consumer['lag_1']=fb_consumer['power_usage'].shift(1) # again find shift of power usage and update into the datset
fb_consumer['lag_5']=fb_consumer['power_usage'].shift(5) #
fb_consumer=fb_consumer.reset_index(drop=True)
future_prediction=pd.DataFrame({'ds':date_list,"yhat":prediction_list})
future_prediction['consumer_id']=consumer
tab1,tab2=st.tabs(['📈Forecast Plot','🗃Forecast Table'])
tab1.markdown("""
📈
Forecast Plot
""", unsafe_allow_html=True)
# y_train_true['y']=y_train_true['y'].astype('float')
# # y_train_pred['yhat']=y_train_pred['yhat'].astype('float')
# y_test_true['y']=y_test_true['y'].astype('float')
# y_test_pred['yhat']=y_test_pred['yhat'].astype('float')
y_train_true.loc[:, 'y'] = y_train_true['y'].astype('float')
# y_train_pred.loc[:, 'yhat'] = y_train_pred['yhat'].astype('float')
y_test_true.loc[:, 'y'] = y_test_true['y'].astype('float')
y_test_pred.loc[:, 'yhat'] = y_test_pred['yhat'].astype('float')
fig = go.Figure([
# go.Scatter(x=y_train_true['ds'],y=y_train_true['y'],name='Train Observed',line=dict(color='blue')),
#go.Scatter(x=y_train_pred['ds'],y=y_train_pred['yhat'],name='Prophet Pred.(10 Consumer)',line=dict(color='blue', dash='dot')),
go.Scatter(x=y_test_true['ds'], y=y_test_true['y'],name='Observed',line=dict(color='purple')),
go.Scatter(x=y_test_pred['ds'],y=y_test_pred['yhat'],name='Historical Forecast',line=dict(color='purple', dash='dot')),
go.Scatter(x=future_prediction['ds'],y=future_prediction['yhat'],name='Future Forecast',line=dict(color='Dark Orange', dash='dot'))
])
fig.update_layout(
xaxis_title='Date',
yaxis_title='Energy Demand',
margin=dict(l=0, r=0, t=50, b=0),
xaxis=dict(title_font=dict(size=20)),
yaxis=dict(title_font=dict(size=20)))
fig.update_layout(width=800,height=400)
tab1.plotly_chart(fig)
rmse=np.sqrt(mean_squared_error(y_test_true['y'],y_test_pred['yhat']))
mae=mean_absolute_error(y_test_true['y'],y_test_pred['yhat'])
with st.sidebar:
st.markdown(f"""
""",unsafe_allow_html=True)
# st.write("Models Evalution")
st.dataframe(pd.DataFrame({"KPI":['RMSE','MAE'],"TFT":[8.67,6.48],"Prophet":[12.82,9.79]}).set_index('KPI'),width=300)
st.markdown(f"""
""",unsafe_allow_html=True)
st.dataframe(pd.DataFrame({"KPI":['RMSE','MAE'],"Prophet":[rmse,mae]}), width=300)
#----------------------------------------
results=y_test_pred.reset_index()
# results['y']=y_test_true['y'].reset_index(drop=True)
results['consumer_id']=consumer
# st.header("Tabular Results")
st.divider()
tab2.markdown("""
📃
Forecast Table
""", unsafe_allow_html=True)
final_results=pd.concat([future_prediction[['ds','consumer_id','yhat']],results[['ds','consumer_id','yhat']]]).sort_values('ds').reset_index(drop=True)
csv = convert_df(final_results)
tab2.dataframe(final_results,width=500)
tab2.download_button("Download",
csv,
"file.csv",
"text/csv",
key='download-csv')