added an overview with links and leaderboard
Browse files- app.py +20 -3
- components.py +38 -0
- utils.py +15 -0
app.py
CHANGED
|
@@ -8,10 +8,12 @@ from components import (
|
|
| 8 |
logos,
|
| 9 |
model_selector,
|
| 10 |
header,
|
|
|
|
| 11 |
)
|
| 12 |
import utils
|
| 13 |
|
| 14 |
PAGES = [
|
|
|
|
| 15 |
"Buildings",
|
| 16 |
"Models",
|
| 17 |
"Performance",
|
|
@@ -42,8 +44,21 @@ models = sorted(data["model"].unique().tolist())
|
|
| 42 |
with st.sidebar:
|
| 43 |
logos()
|
| 44 |
view = st.selectbox("View", PAGES, index=0)
|
| 45 |
-
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
refresh = st.button(
|
| 48 |
"Refresh", use_container_width=True, help="Fetch the latest data from W&B"
|
| 49 |
)
|
|
@@ -54,7 +69,9 @@ with st.sidebar:
|
|
| 54 |
|
| 55 |
header()
|
| 56 |
|
| 57 |
-
if view == "
|
|
|
|
|
|
|
| 58 |
buildings_view(data)
|
| 59 |
elif view == "Models":
|
| 60 |
models_view(data)
|
|
|
|
| 8 |
logos,
|
| 9 |
model_selector,
|
| 10 |
header,
|
| 11 |
+
overview_view,
|
| 12 |
)
|
| 13 |
import utils
|
| 14 |
|
| 15 |
PAGES = [
|
| 16 |
+
"Overview",
|
| 17 |
"Buildings",
|
| 18 |
"Models",
|
| 19 |
"Performance",
|
|
|
|
| 44 |
with st.sidebar:
|
| 45 |
logos()
|
| 46 |
view = st.selectbox("View", PAGES, index=0)
|
| 47 |
+
|
| 48 |
+
if view == "Performance" or view == "Computational Resources":
|
| 49 |
+
models_to_plot = model_selector(models)
|
| 50 |
+
|
| 51 |
+
if view == "Overview":
|
| 52 |
+
st.header("Sources")
|
| 53 |
+
st.link_button("GitHub Repository", url="https://github.com/attila-balint-kul/energy-forecast-benchmark-toolkit", use_container_width=True)
|
| 54 |
+
st.link_button("Documentation", url="https://attila-balint-kul.github.io/energy-forecast-benchmark-toolkit/", use_container_width=True)
|
| 55 |
+
st.link_button("Electricity Demand Dataset", url="https://huggingface.co/datasets/EDS-lab/electricity-demand", use_container_width=True)
|
| 56 |
+
st.link_button("HuggingFace Organization", url="https://huggingface.co/EDS-lab", use_container_width=True)
|
| 57 |
+
|
| 58 |
+
st.header("Other Dashboards")
|
| 59 |
+
st.link_button("PV Generation", url="https://huggingface.co/spaces/EDS-lab/EnFoBench-PVGeneration", use_container_width=True)
|
| 60 |
+
|
| 61 |
+
st.header("Refresh data")
|
| 62 |
refresh = st.button(
|
| 63 |
"Refresh", use_container_width=True, help="Fetch the latest data from W&B"
|
| 64 |
)
|
|
|
|
| 69 |
|
| 70 |
header()
|
| 71 |
|
| 72 |
+
if view == "Overview":
|
| 73 |
+
overview_view(data)
|
| 74 |
+
elif view == "Buildings":
|
| 75 |
buildings_view(data)
|
| 76 |
elif view == "Models":
|
| 77 |
models_view(data)
|
components.py
CHANGED
|
@@ -2,6 +2,8 @@ import pandas as pd
|
|
| 2 |
import streamlit as st
|
| 3 |
import plotly.express as px
|
| 4 |
|
|
|
|
|
|
|
| 5 |
|
| 6 |
def header() -> None:
|
| 7 |
st.title("EnFoBench - Electricity Demand")
|
|
@@ -51,6 +53,42 @@ def model_selector(models: list[str]) -> set[str]:
|
|
| 51 |
return models_to_plot
|
| 52 |
|
| 53 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
def buildings_view(data):
|
| 55 |
buildings = (
|
| 56 |
data[
|
|
|
|
| 2 |
import streamlit as st
|
| 3 |
import plotly.express as px
|
| 4 |
|
| 5 |
+
from utils import get_leaderboard
|
| 6 |
+
|
| 7 |
|
| 8 |
def header() -> None:
|
| 9 |
st.title("EnFoBench - Electricity Demand")
|
|
|
|
| 53 |
return models_to_plot
|
| 54 |
|
| 55 |
|
| 56 |
+
def overview_view(data):
|
| 57 |
+
st.markdown("""
|
| 58 |
+
[EnFoBench](https://github.com/attila-balint-kul/energy-forecast-benchmark-toolkit)
|
| 59 |
+
is a community driven benchmarking framework for energy forecasting models.
|
| 60 |
+
|
| 61 |
+
This dashboard presents the results of the electricity demand forecasting usecase. All models were cross-validated
|
| 62 |
+
on **365 days** of day ahead forecasting horizon *(10AM until midnight of the next day)*.
|
| 63 |
+
""")
|
| 64 |
+
|
| 65 |
+
st.divider()
|
| 66 |
+
st.markdown("## Leaderboard")
|
| 67 |
+
|
| 68 |
+
leaderboard = get_leaderboard(data, ["MAE.mean", "RMSE.mean", "rMAE.mean"])
|
| 69 |
+
|
| 70 |
+
left, middle, right = st.columns(3)
|
| 71 |
+
with left:
|
| 72 |
+
best_models_mae = leaderboard.sort_values("MAE.mean", ascending=False).head(10).sort_values("MAE.mean")
|
| 73 |
+
fig = px.bar(best_models_mae, x="MAE.mean", y=best_models_mae.index)
|
| 74 |
+
fig.update_layout(title="Top 10 models by MAE", xaxis_title="", yaxis_title="Model")
|
| 75 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 76 |
+
|
| 77 |
+
with middle:
|
| 78 |
+
best_models_mae = leaderboard.sort_values("RMSE.mean", ascending=False).head(10).sort_values("RMSE.mean")
|
| 79 |
+
fig = px.bar(best_models_mae, x="RMSE.mean", y=best_models_mae.index)
|
| 80 |
+
fig.update_layout(title="Top 10 models by RMSE", xaxis_title="", yaxis_title="")
|
| 81 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 82 |
+
|
| 83 |
+
with right:
|
| 84 |
+
best_models_mae = leaderboard.sort_values("rMAE.mean", ascending=False).head(10).sort_values("rMAE.mean")
|
| 85 |
+
fig = px.bar(best_models_mae, x="rMAE.mean", y=best_models_mae.index)
|
| 86 |
+
fig.update_layout(title="Top 10 models by rMAE", xaxis_title="", yaxis_title="")
|
| 87 |
+
st.plotly_chart(fig, use_container_width=True)
|
| 88 |
+
|
| 89 |
+
st.dataframe(leaderboard, use_container_width=True)
|
| 90 |
+
|
| 91 |
+
|
| 92 |
def buildings_view(data):
|
| 93 |
buildings = (
|
| 94 |
data[
|
utils.py
CHANGED
|
@@ -27,3 +27,18 @@ def get_wandb_data(entity: str, project: str, api_key: str, job_type: str) -> pd
|
|
| 27 |
runs_df = pd.concat([summary_df, config_df], axis=1)
|
| 28 |
runs_df.index = name_list
|
| 29 |
return runs_df
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
runs_df = pd.concat([summary_df, config_df], axis=1)
|
| 28 |
runs_df.index = name_list
|
| 29 |
return runs_df
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def get_leaderboard(runs_df: pd.DataFrame, metrics: list[str]) -> pd.DataFrame:
|
| 33 |
+
leaderboard = pd.DataFrame(
|
| 34 |
+
index=runs_df['model'].unique(),
|
| 35 |
+
columns=metrics
|
| 36 |
+
).fillna(0)
|
| 37 |
+
|
| 38 |
+
for _, building_df in runs_df.groupby("unique_id"):
|
| 39 |
+
for column in leaderboard.columns:
|
| 40 |
+
best_model = building_df.loc[building_df[column].idxmin()].model
|
| 41 |
+
leaderboard.loc[best_model, column] += 1
|
| 42 |
+
|
| 43 |
+
leaderboard = leaderboard.sort_values(by=list(leaderboard.columns), ascending=False)
|
| 44 |
+
return leaderboard
|