Spaces:
Running
Running
Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import numpy as np
|
4 |
+
import plotly.graph_objs as go
|
5 |
+
from io import BytesIO
|
6 |
+
|
7 |
+
# Function to convert df to csv for download
|
8 |
+
def convert_df_to_csv(df):
|
9 |
+
return df.to_csv(index=False).encode('utf-8')
|
10 |
+
|
11 |
+
# Load your data
|
12 |
+
df = pd.read_csv('Predictions.csv')
|
13 |
+
df['Date'] = pd.to_datetime(df['Date'], dayfirst=True)
|
14 |
+
df_filtered = df.dropna(subset=['Price'])
|
15 |
+
|
16 |
+
# Load input dataC:\Users\mmascare\Documents\Code\Forecast_API\Scrape\datasets\DATA_ELIA.csv
|
17 |
+
df_input = pd.read_csv('DATA_ELIA.csv')
|
18 |
+
df_input['Date'] = pd.to_datetime(df_input['Date'], dayfirst=True)
|
19 |
+
|
20 |
+
# Determine the first and last date
|
21 |
+
min_date_allowed = df_input['Date'].min().date()
|
22 |
+
max_date_allowed = df_input['Date'].max().date()
|
23 |
+
|
24 |
+
min_date_allowed_pred = df_filtered['Date'].min().date()
|
25 |
+
max_date_allowed_pred = df_filtered['Date'].max().date()
|
26 |
+
|
27 |
+
end_date = df['Date'].max().date()
|
28 |
+
start_date = end_date - pd.Timedelta(days=7)
|
29 |
+
|
30 |
+
st.title("Belgium: Electricity Price Forecasting")
|
31 |
+
|
32 |
+
# Sidebar for inputs
|
33 |
+
with st.sidebar:
|
34 |
+
st.write("### Variables Selection for Graph")
|
35 |
+
st.write("Select which variables you'd like to include in the graph. This will affect the displayed charts and available data for download.")
|
36 |
+
selected_variables = st.multiselect("Select variables to display:", options=['Price', 'DNN', 'LEAR', 'Persis'], default=['Price', 'DNN', 'LEAR', 'Persis'])
|
37 |
+
|
38 |
+
st.write("### Date Range for Metrics Calculation")
|
39 |
+
st.write("Select the date range to calculate the metrics for the predictions. This will influence the accuracy metrics displayed below. The complete dataset ranges from 10/03/2024 until today.")
|
40 |
+
start_date_pred, end_date_pred = st.date_input("Select Date Range for Metrics Calculation:", [min_date_allowed_pred, max_date_allowed_pred])
|
41 |
+
|
42 |
+
# Main content
|
43 |
+
if not selected_variables:
|
44 |
+
st.warning("Please select at least one variable to display.")
|
45 |
+
else:
|
46 |
+
# Plotting
|
47 |
+
st.write("## Belgian Day-Ahead Electricity Prices")
|
48 |
+
temp_df = df[(df['Date'] >= pd.Timestamp(start_date)) & (df['Date'] <= pd.Timestamp(end_date))]
|
49 |
+
fig = go.Figure()
|
50 |
+
|
51 |
+
# Updated labels for each variable
|
52 |
+
variable_labels = {
|
53 |
+
'Price': 'Real Price',
|
54 |
+
'DNN': 'DNN Forecast',
|
55 |
+
'LEAR': 'LEAR Forecast',
|
56 |
+
'Persis': 'Persistence Forecast'
|
57 |
+
}
|
58 |
+
|
59 |
+
for variable in selected_variables:
|
60 |
+
fig.add_trace(go.Scatter(x=temp_df['Date'], y=temp_df[variable], mode='lines', name=variable_labels[variable]))
|
61 |
+
|
62 |
+
fig.update_layout(xaxis_title="Date", yaxis_title="Price [EUR/MWh]")
|
63 |
+
st.plotly_chart(fig, use_container_width=True)
|
64 |
+
st.write("The graph presented here illustrates the day-ahead electricity price forecasts for Belgium, covering the period from one week ago up to tomorrow. It incorporates predictions from three distinct models: DNN (Deep Neural Networks), LEAR (Lasso Estimated AutoRegressive), and Persistence, alongside the actual electricity prices up until today. The Persistence model, a seasonal naive forecaster, bases its predictions on the prices from one week ago. More information regarding the DNN and LEAR models can be found in article titled: Forecasting day-ahead electricity prices: A review of state-of-the-art algorithms, best practices and an open-access benchmark, published in Applied Energy, volume 293, pages 116983, in 2021. Authored by Jesus Lago, Grzegorz Marcjasz, Bart De Schutter, and Rafał Weron.")
|
65 |
+
|
66 |
+
# Download Predictions Button
|
67 |
+
st.write("## Download Predictions")
|
68 |
+
st.write("Download Day-Ahead Price & Model Predictions: Receive a detailed CSV file comprising the actual day-ahead electricity prices and the corresponding LEAR and DNN model forecasts. This data enables you to compare performance and accuracy.")
|
69 |
+
csv = convert_df_to_csv(df)
|
70 |
+
st.download_button(
|
71 |
+
label="Download Predictions CSV",
|
72 |
+
data=csv,
|
73 |
+
file_name='predictions.csv',
|
74 |
+
mime='text/csv',
|
75 |
+
)
|
76 |
+
|
77 |
+
# Calculating and displaying metrics
|
78 |
+
if start_date_pred and end_date_pred:
|
79 |
+
st.header("Accuracy Metrics")
|
80 |
+
st.write("Evaluate the forecasting accuracy of our models with key performance indicators. The table summarizes the Mean Absolute Error (MAE), Symmetric Mean Absolute Percentage Error (SMAPE), and Root Mean Square Error (RMSE) for the Persistence, DNN and LEAR models over your selected date range. Lower values indicate higher precision and reliability of the forecasts.")
|
81 |
+
filtered_df = df_filtered[(df_filtered['Date'] >= pd.Timestamp(start_date_pred)) & (df_filtered['Date'] <= pd.Timestamp(end_date_pred))]
|
82 |
+
|
83 |
+
# Here you would calculate your metrics based on filtered_df
|
84 |
+
# For demonstration, let's assume these are your metrics
|
85 |
+
p_real = filtered_df['Price']
|
86 |
+
p_pred_dnn = filtered_df['DNN']
|
87 |
+
p_pred_lear = filtered_df['LEAR']
|
88 |
+
p_pred_persis = filtered_df['Persis']
|
89 |
+
|
90 |
+
# Recalculate the metrics
|
91 |
+
mae_dnn = np.mean(np.abs(p_real - p_pred_dnn))
|
92 |
+
smape_dnn = 100 * np.mean(np.abs(p_real - p_pred_dnn) / ((np.abs(p_real) + np.abs(p_pred_dnn)) / 2))
|
93 |
+
rmse_dnn = np.sqrt(np.mean((p_real - p_pred_dnn) ** 2))
|
94 |
+
|
95 |
+
|
96 |
+
mae_lear = np.mean(np.abs(p_real - p_pred_lear))
|
97 |
+
smape_lear = 100 * np.mean(np.abs(p_real - p_pred_lear) / ((np.abs(p_real) + np.abs(p_pred_lear)) / 2))
|
98 |
+
rmse_lear = np.sqrt(np.mean((p_real - p_pred_lear) ** 2))
|
99 |
+
|
100 |
+
|
101 |
+
mae_persis = np.mean(np.abs(p_real - p_pred_persis))
|
102 |
+
smape_persis = 100 * np.mean(np.abs(p_real - p_pred_persis) / ((np.abs(p_real) + np.abs(p_pred_persis)) / 2))
|
103 |
+
rmse_persis = np.sqrt(np.mean((p_real - p_pred_persis) ** 2))
|
104 |
+
|
105 |
+
|
106 |
+
new_metrics_df = pd.DataFrame({
|
107 |
+
'Metric': ['MAE', 'SMAPE', 'RMSE'],
|
108 |
+
'Persistence': [f"{mae_persis:.2f}", f"{smape_persis:.2f}%", f"{rmse_persis:.2f}"],
|
109 |
+
'DNN': [f"{mae_dnn:.2f}", f"{smape_dnn:.2f}%", f"{rmse_dnn:.2f}"],
|
110 |
+
'LEAR': [f"{mae_lear:.2f}", f"{smape_lear:.2f}%", f"{rmse_lear:.2f}"]
|
111 |
+
})
|
112 |
+
st.dataframe(new_metrics_df, hide_index=True)
|