JavadBayazi commited on
Commit
ec72f78
·
1 Parent(s): 06412fb

Improve terminology and update app descriptions

Browse files

- Replace 'training' with 'historical context' (zero-shot forecasting)
- Update 'Actual Test Data' to 'Actual Values'
- Change 'Train/Test Split' to 'Forecast Window'
- Update app title and description to reflect multi-model support
- Add comprehensive About section with feature list
- Clarify slider help text for backtesting
- Make ERCOT info message conditional

Files changed (1) hide show
  1. app.py +34 -21
app.py CHANGED
@@ -20,8 +20,11 @@ def fetch_data(source_name, days_back=180):
20
  return fetch_data_with_fallback(source_name, days_back)
21
 
22
  # Streamlit app interface
23
- st.title("Electricity Market Price Forecasting with Chronos-2")
24
- st.write("This demo uses **Chronos-2** to forecast electricity prices from ERCOT (Texas) market data.")
 
 
 
25
 
26
  # Model selection
27
  available_model_names = ModelConfig.get_model_names()
@@ -66,7 +69,8 @@ else:
66
  default_data.strip(),
67
  height=150
68
  )
69
- st.info("💡 Live data from ERCOT's Day-Ahead Market (DAM SPP) - averaged across all settlement points per day")
 
70
 
71
  try:
72
  time_series_data = process_input(user_input)
@@ -74,34 +78,34 @@ except ValueError:
74
  st.error("Please make sure all values are numbers, separated by commas.")
75
  time_series_data = [] # Set empty data on error to prevent further processing
76
 
77
- # Select the number of days for testing (forecasting on known data)
78
  max_test_days = min(64, len(time_series_data) - 10) if len(time_series_data) > 10 else 1
79
  prediction_length = st.slider(
80
- "Select Test Window (Days to Forecast & Compare)",
81
  min_value=1,
82
  max_value=max_test_days,
83
  value=min(14, max_test_days),
84
- help="The last N days will be used as test data. The model will forecast these days and compare with actual values."
85
  )
86
 
87
  # If data is valid, perform the forecast
88
  if time_series_data:
89
- # Split data into train and test
90
- train_length = len(time_series_data) - prediction_length
91
- train_data = time_series_data[:train_length]
92
- test_data = time_series_data[train_length:]
93
 
94
  # Create timestamps
95
  end_date = datetime.now()
96
  start_date = end_date - timedelta(days=len(time_series_data) - 1)
97
  all_dates = pd.date_range(start=start_date, periods=len(time_series_data), freq='D')
98
- train_dates = all_dates[:train_length]
99
- test_dates = all_dates[train_length:]
100
 
101
- # Create a DataFrame for training
102
  context_df = pd.DataFrame({
103
- 'timestamp': train_dates,
104
- 'target': train_data,
105
  'id': 'ercot_prices'
106
  })
107
 
@@ -128,12 +132,12 @@ if time_series_data:
128
 
129
  # Plot the historical and forecasted data with dates
130
  plt.figure(figsize=(14, 7))
131
- plt.plot(train_dates, train_data, color="royalblue", label="Training Data", linewidth=2)
132
- plt.plot(test_dates, test_data, color="green", label="Actual Test Data", linewidth=2, marker='o', markersize=4)
133
  plt.plot(test_dates, median, color="tomato", label="Forecast", linewidth=2, linestyle='--', marker='s', markersize=4)
134
  plt.fill_between(test_dates, low, high, color="tomato", alpha=0.3, label="80% Prediction Interval")
135
- plt.axvline(x=train_dates[-1], color='gray', linestyle=':', linewidth=1, alpha=0.7)
136
- plt.text(train_dates[-1], plt.ylim()[1]*0.95, ' Train/Test Split', fontsize=10, color='gray')
137
  plt.xlabel("Date")
138
  plt.ylabel("Price ($/MWh)")
139
  plt.title(f"ERCOT Electricity Price Forecast - {prediction_length} Day Test Window")
@@ -169,5 +173,14 @@ if time_series_data:
169
  st.dataframe(comparison_df, use_container_width=True)
170
 
171
  # Note for comments, feedback, or questions
172
- st.write("### Notes")
173
- st.write("For comments, feedback, or any questions, please reach out to me on [LinkedIn](https://www.linkedin.com/in/javadbayazi/).")
 
 
 
 
 
 
 
 
 
 
20
  return fetch_data_with_fallback(source_name, days_back)
21
 
22
  # Streamlit app interface
23
+ st.title("Electricity Market Price Forecasting")
24
+ st.write("""
25
+ This demo uses **Amazon Chronos** pretrained models for zero-shot time series forecasting on electricity market data.
26
+ Select a model, choose your data source, and evaluate forecasting performance with backtesting on real ERCOT prices.
27
+ """)
28
 
29
  # Model selection
30
  available_model_names = ModelConfig.get_model_names()
 
69
  default_data.strip(),
70
  height=150
71
  )
72
+ if "ERCOT" in data_source_used:
73
+ st.info("💡 Live data from ERCOT's Day-Ahead Market (DAM SPP) - Daily average prices across all settlement points")
74
 
75
  try:
76
  time_series_data = process_input(user_input)
 
78
  st.error("Please make sure all values are numbers, separated by commas.")
79
  time_series_data = [] # Set empty data on error to prevent further processing
80
 
81
+ # Select the forecast window for backtesting
82
  max_test_days = min(64, len(time_series_data) - 10) if len(time_series_data) > 10 else 1
83
  prediction_length = st.slider(
84
+ "Forecast Horizon (Days to Backtest)",
85
  min_value=1,
86
  max_value=max_test_days,
87
  value=min(14, max_test_days),
88
+ help="The model will use historical context to forecast the last N days, then compare predictions with actual values to evaluate performance."
89
  )
90
 
91
  # If data is valid, perform the forecast
92
  if time_series_data:
93
+ # Split data into context (historical) and test
94
+ context_length = len(time_series_data) - prediction_length
95
+ context_data = time_series_data[:context_length]
96
+ test_data = time_series_data[context_length:]
97
 
98
  # Create timestamps
99
  end_date = datetime.now()
100
  start_date = end_date - timedelta(days=len(time_series_data) - 1)
101
  all_dates = pd.date_range(start=start_date, periods=len(time_series_data), freq='D')
102
+ context_dates = all_dates[:context_length]
103
+ test_dates = all_dates[context_length:]
104
 
105
+ # Create a DataFrame with context for the model
106
  context_df = pd.DataFrame({
107
+ 'timestamp': context_dates,
108
+ 'target': context_data,
109
  'id': 'ercot_prices'
110
  })
111
 
 
132
 
133
  # Plot the historical and forecasted data with dates
134
  plt.figure(figsize=(14, 7))
135
+ plt.plot(context_dates, context_data, color="royalblue", label="Historical Context", linewidth=2)
136
+ plt.plot(test_dates, test_data, color="green", label="Actual Values", linewidth=2, marker='o', markersize=4)
137
  plt.plot(test_dates, median, color="tomato", label="Forecast", linewidth=2, linestyle='--', marker='s', markersize=4)
138
  plt.fill_between(test_dates, low, high, color="tomato", alpha=0.3, label="80% Prediction Interval")
139
+ plt.axvline(x=context_dates[-1], color='gray', linestyle=':', linewidth=1, alpha=0.7)
140
+ plt.text(context_dates[-1], plt.ylim()[1]*0.95, ' Forecast Window', fontsize=10, color='gray')
141
  plt.xlabel("Date")
142
  plt.ylabel("Price ($/MWh)")
143
  plt.title(f"ERCOT Electricity Price Forecast - {prediction_length} Day Test Window")
 
173
  st.dataframe(comparison_df, use_container_width=True)
174
 
175
  # Note for comments, feedback, or questions
176
+ st.write("### About")
177
+ st.write("""
178
+ **Features:**
179
+ - 🤖 Multiple Chronos models (Chronos-2 and T5 variants)
180
+ - 📊 Real-time ERCOT electricity market data
181
+ - 🎯 Backtesting with error metrics (MAE, RMSE, MAPE)
182
+ - 📈 Visual comparison of forecasts vs actual values
183
+ - 🔧 Modular architecture for easy extension
184
+
185
+ For questions or feedback, reach out on [LinkedIn](https://www.linkedin.com/in/javadbayazi/).
186
+ """)