Aliazimi00 commited on
Commit
ae71e01
·
verified ·
1 Parent(s): b47effb

Update core/train_eval.py

Browse files
Files changed (1) hide show
  1. core/train_eval.py +30 -5
core/train_eval.py CHANGED
@@ -3,7 +3,7 @@ import pandas as pd
3
  import torch
4
  from torch import nn, optim
5
  from sklearn.preprocessing import StandardScaler
6
- from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
7
  from torch.utils.data import DataLoader, TensorDataset
8
  import matplotlib.pyplot as plt
9
  import os
@@ -26,6 +26,27 @@ def mean_absolute_percentage_error(y_true, y_pred):
26
  return np.mean(np.abs((y_true[non_zero] - y_pred[non_zero]) / y_true[non_zero])) * 100
27
 
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  def train_and_evaluate(
30
  df,
31
  future_df,
@@ -85,7 +106,7 @@ def train_and_evaluate(
85
  patience = 5
86
  counter = 0
87
  best_model_state = None
88
- last_lr = lr # Track learning rate for manual logging
89
 
90
  model.train()
91
  for epoch in range(epochs):
@@ -111,7 +132,6 @@ def train_and_evaluate(
111
  val_loss /= len(val_loader)
112
  val_losses.append(val_loss)
113
 
114
- # Step scheduler and manually log learning rate changes
115
  scheduler.step(val_loss)
116
  current_lr = optimizer.param_groups[0]['lr']
117
  if current_lr != last_lr and verbose:
@@ -161,12 +181,18 @@ def train_and_evaluate(
161
  mae = mean_absolute_error(targets_inv, preds_inv)
162
  r2 = r2_score(targets_inv, preds_inv)
163
  mape = mean_absolute_percentage_error(targets_inv, preds_inv)
 
 
 
164
 
165
  result["metrics"] = {
166
  "R2": round(r2, 4),
 
 
167
  "RMSE": round(rmse, 4),
168
  "MAE": round(mae, 4),
169
- "MAPE": round(mape, 4) if not np.isnan(mape) else None
 
170
  }
171
 
172
  result["forecast"] = preds_inv
@@ -183,7 +209,6 @@ def train_and_evaluate(
183
 
184
  result["latest_prediction"] = future_pred_inv[0].tolist()
185
 
186
- # Include actual future values if available
187
  if not future_df.empty:
188
  result["future_actuals"] = future_df['value'].values.tolist()[:horizon]
189
 
 
3
  import torch
4
  from torch import nn, optim
5
  from sklearn.preprocessing import StandardScaler
6
+ from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score, explained_variance_score
7
  from torch.utils.data import DataLoader, TensorDataset
8
  import matplotlib.pyplot as plt
9
  import os
 
26
  return np.mean(np.abs((y_true[non_zero] - y_pred[non_zero]) / y_true[non_zero])) * 100
27
 
28
 
29
+ def mean_absolute_scaled_error(y_true, y_pred, y_train):
30
+ """Calculate MASE, using naive forecast as denominator."""
31
+ y_true, y_pred = np.array(y_true), np.array(y_pred)
32
+ errors = np.abs(y_true - y_pred)
33
+ # Naive forecast: use previous value as prediction
34
+ naive_errors = np.abs(y_train[1:] - y_train[:-1])
35
+ mean_naive_error = np.mean(naive_errors) if len(naive_errors) > 0 else 1.0
36
+ return np.mean(errors) / mean_naive_error if mean_naive_error != 0 else np.nan
37
+
38
+
39
+ def mean_directional_accuracy(y_true, y_pred):
40
+ """Calculate MDA: percentage of correct direction predictions."""
41
+ y_true, y_pred = np.array(y_true), np.array(y_pred)
42
+ if len(y_true) < 2:
43
+ return np.nan
44
+ true_diff = np.sign(y_true[1:] - y_true[:-1])
45
+ pred_diff = np.sign(y_pred[1:] - y_pred[:-1])
46
+ correct = np.sum(true_diff == pred_diff)
47
+ return (correct / (len(y_true) - 1)) * 100
48
+
49
+
50
  def train_and_evaluate(
51
  df,
52
  future_df,
 
106
  patience = 5
107
  counter = 0
108
  best_model_state = None
109
+ last_lr = lr
110
 
111
  model.train()
112
  for epoch in range(epochs):
 
132
  val_loss /= len(val_loader)
133
  val_losses.append(val_loss)
134
 
 
135
  scheduler.step(val_loss)
136
  current_lr = optimizer.param_groups[0]['lr']
137
  if current_lr != last_lr and verbose:
 
181
  mae = mean_absolute_error(targets_inv, preds_inv)
182
  r2 = r2_score(targets_inv, preds_inv)
183
  mape = mean_absolute_percentage_error(targets_inv, preds_inv)
184
+ evs = explained_variance_score(targets_inv, preds_inv)
185
+ mase = mean_absolute_scaled_error(targets_inv, preds_inv, original_values[:len(original_values)-horizon])
186
+ mda = mean_directional_accuracy(targets_inv, preds_inv)
187
 
188
  result["metrics"] = {
189
  "R2": round(r2, 4),
190
+ "Explained Variance": round(evs, 4),
191
+ "MDA (%)": round(mda, 4) if not np.isnan(mda) else None,
192
  "RMSE": round(rmse, 4),
193
  "MAE": round(mae, 4),
194
+ "MAPE (%)": round(mape, 4) if not np.isnan(mape) else None,
195
+ "MASE": round(mase, 4) if not np.isnan(mase) else None
196
  }
197
 
198
  result["forecast"] = preds_inv
 
209
 
210
  result["latest_prediction"] = future_pred_inv[0].tolist()
211
 
 
212
  if not future_df.empty:
213
  result["future_actuals"] = future_df['value'].values.tolist()[:horizon]
214