11
11
df_train3 = pd .read_csv ("paper_tests/m4_test/Monthly-train3.csv" )
12
12
df_train4 = pd .read_csv ("paper_tests/m4_test/Monthly-train4.csv" )
13
13
df_train = pd .concat ([df_train1 , df_train2 , df_train3 , df_train4 ])
14
- m4_info = pd .read_csv ("paper_tests/m4_test/M4-info.csv" )
15
14
16
15
df_test = pd .read_csv ("paper_tests/m4_test/Monthly-test.csv" )
17
16
ssl_init_df = pd .read_csv ("paper_tests/m4_test/init_SSL/SSL_aic_0.1_false.csv" )
@@ -40,6 +39,20 @@ def MASE(y_train, y_test, prediction, m=12):
40
39
denominator = (1 / (T - m )) * sum ([abs (y_train [j ] - y_train [j - m ]) for j in range (m , T )])
41
40
return numerator / denominator # if denominator != 0 else 0
42
41
42
+ def CRPS (scenarios : np .ndarray , y : np .ndarray ) -> float :
43
+ crps_scores = np .empty (len (y ), dtype = float )
44
+ for k , actual in enumerate (y ):
45
+ sorted_scenarios = np .sort (scenarios [k , :])
46
+ m = len (sorted_scenarios )
47
+ crps_score = 0.0
48
+ for i in range (m ):
49
+ crps_score += (
50
+ (sorted_scenarios [i ] - actual )
51
+ * (m * (actual < sorted_scenarios [i ]) - (i + 1 ) + 0.5 )
52
+ )
53
+ crps_scores [k ] = (2 / m ** 2 ) * crps_score
54
+ return np .mean (crps_scores )
55
+
43
56
def evaluate_ss (input , sample_size , init , hyperparameters_inicialization ):
44
57
train = input ["train" ]
45
58
test = input ["test" ]
@@ -53,32 +66,47 @@ def evaluate_ss(input, sample_size, init, hyperparameters_inicialization):
53
66
results = model .fit (start_params = hyperparameters_inicialization , disp = False , maxiter = 1e5 )
54
67
else :
55
68
results = model .fit (disp = False , maxiter = 1e5 )
56
- forecast = results .get_forecast (steps = 18 )
57
- normalized_forecast_values = forecast .predicted_mean
69
+ config = {
70
+ 'repetitions' : 1000 ,
71
+ 'steps' : 18
72
+ }
73
+ forecast_obj = results .get_forecast (** config )
74
+ forecast_df = forecast_obj .summary_frame ()
75
+ normalized_simulation = np .empty ((len (forecast_df ), 300 ))
76
+ for i in range (len (forecast_df )):
77
+ normalized_simulation [i ] = [np .random .normal (forecast_df ["mean" ].values [i ], forecast_df ["mean_se" ].values [i ]) for _ in range (300 )]
78
+ normalized_forecast_values = forecast_df ["mean" ].values
58
79
forecast_values = [x * (max_train - min_train ) + min_train for x in normalized_forecast_values ]
59
- return sMAPE (test , forecast_values ), MASE (train , test , forecast_values )
80
+ simulation = normalized_simulation * (max_train - min_train ) + min_train
81
+ return sMAPE (test , forecast_values ), MASE (train , test , forecast_values ), CRPS (simulation , test )
60
82
61
83
62
84
results = []
63
85
results_init = []
64
86
for i in range (0 , 48000 ):
65
- hyperparameters_inicialization = [ssl_init_df .loc [i ]["ϵ" ], ssl_init_df .loc [i ]["ξ" ],ssl_init_df .loc [i ]["ζ" ],ssl_init_df .loc [i ]["ω_12" ]]
87
+ if i % 100 == 0 :
88
+ print ("Running series " , i )
89
+ hyperparameters_inicialization = [ssl_init_df .loc [i ]["ϵ" ], ssl_init_df .loc [i ]["ξ" ],ssl_init_df .loc [i ]["ζ" ],ssl_init_df .loc [i ]["ω" ]]
66
90
results .append (evaluate_ss (dict_vec [i ], 2794 , False , hyperparameters_inicialization ))
67
91
results_init .append (evaluate_ss (dict_vec [i ], 2794 , True , hyperparameters_inicialization ))
68
92
69
93
smape_SS = []
70
94
mase_SS = []
71
95
smape_SS_init = []
72
96
mase_SS_init = []
97
+ crps_SS = []
98
+ crps_SS_init = []
73
99
for i in range (0 , len (results )):
74
100
smape_SS .append (results [i ][0 ])
75
101
mase_SS .append (results [i ][1 ])
76
102
smape_SS_init .append (results_init [i ][0 ])
77
103
mase_SS_init .append (results_init [i ][1 ])
104
+ crps_SS .append (results [i ][2 ])
105
+ crps_SS_init .append (results_init [i ][2 ])
78
106
79
107
#create dataframe with mase and smape columns:
80
- df = pd .DataFrame ({'smape' : smape_SS , 'mase' : mase_SS })
81
- df_init = pd .DataFrame ({'smape' : smape_SS_init , 'mase' : mase_SS_init })
108
+ df = pd .DataFrame ({'smape' : smape_SS , 'mase' : mase_SS , 'crps' : crps_SS })
109
+ df_init = pd .DataFrame ({'smape' : smape_SS_init , 'mase' : mase_SS_init , 'crps' : crps_SS_init })
82
110
#save to csv:
83
111
df .to_csv ('paper_tests/m4_test/results_SS/SS.csv' )
84
112
df_init .to_csv ('paper_tests/m4_test/results_SS/SS_init.csv' )
@@ -95,20 +123,25 @@ def evaluate_ss(input, sample_size, init, hyperparameters_inicialization):
95
123
def evaluate_prophet (input ):
96
124
train = input ["train" ]
97
125
test = input ["test" ]
98
- timestamps = pd .date_range (start = "2020-01-01" , periods = len (train ), freq = 'ME ' )
126
+ timestamps = pd .date_range (start = "2020-01-01" , periods = len (train ), freq = 'MS ' )
99
127
#add random seed
100
128
df = pd .DataFrame ({
101
129
'ds' : timestamps ,
102
130
'y' : train
103
131
})
104
132
model = Prophet (interval_width = 0.95 )
105
133
model .fit (df )
106
- future = pd .DataFrame ({
107
- 'ds' : (pd .date_range (start = "2020-01-01" , periods = len (train ) + 18 , freq = 'ME' ))[len (train ):]
108
- })
134
+ future = model .make_future_dataframe (periods = 18 , freq = 'MS' )
135
+ future = future [- 18 :]
109
136
model_forecast = model .predict (future )
110
137
prediction = model_forecast ['yhat' ].values
111
- return sMAPE (test , prediction ), MASE (train , test , prediction )
138
+ model_prob = Prophet (interval_width = 0.95 , mcmc_samples = 300 )
139
+ model_prob .fit (df )
140
+ # Sample 1000 predictive paths
141
+ forecast_samples = model_prob .predictive_samples (future )
142
+ # Construct scenario paths
143
+ simulated_paths = forecast_samples ['yhat' ] # shape: (num_timestamps, num_samples)
144
+ return sMAPE (test , prediction ), MASE (train , test , prediction ), CRPS (simulated_paths , test )
112
145
113
146
def evaluate_chronos (input ):
114
147
train = input ["train" ]
@@ -126,27 +159,31 @@ def evaluate_chronos(input):
126
159
127
160
smape_prophet_vec = []
128
161
mase_prophet_vec = []
162
+ crps_prophet_vec = []
129
163
smape_chronos_vec = []
130
164
mase_chronos_vec = []
165
+
131
166
for i in range (0 , len (dict_vec )):
132
- smape_prophet , mase_prophet = evaluate_prophet (dict_vec [i ])
167
+ smape_prophet , mase_prophet , crps_prophet = evaluate_prophet (dict_vec [i ])
133
168
smape_prophet_vec .append (smape_prophet )
134
169
mase_prophet_vec .append (mase_prophet )
170
+ crps_prophet_vec .append (crps_prophet )
135
171
smape_chronos , mase_chronos = evaluate_chronos (dict_vec [i ])
136
172
smape_chronos_vec .append (smape_chronos )
137
173
mase_chronos_vec .append (mase_chronos )
138
- #
139
174
print ("Runningg series " , i )
140
175
if i % 1000 == 0 :
141
176
print ("Runningg series " , i )
142
177
smape_mean_prophet = np .mean (smape_prophet_vec )
143
- smape_emean_chronos = np .mean (smape_chronos_vec )
178
+ smape_mean_chronos = np .mean (smape_chronos_vec )
144
179
mase_mean_prophet = np .mean (mase_prophet_vec )
145
180
mase_mean_chronos = np .mean (mase_chronos_vec )
181
+ crps_mean_prophet = np .mean (crps_prophet_vec )
146
182
print ("Mean sMape Prophet: " , smape_mean_prophet )
147
- print ("Mean sMape Chronos: " , smape_emean_chronos )
183
+ print ("Mean sMape Chronos: " , smape_mean_chronos )
148
184
print ("Mean Mase Prophet: " , mase_mean_prophet )
149
185
print ("Mean Mase Chronos: " , mase_mean_chronos )
186
+ print ("Mean CRPS Prophet: " , crps_mean_prophet )
150
187
151
188
152
189
NAIVE_sMAPE = 14.427 #M4 Paper
@@ -159,9 +196,11 @@ def evaluate_chronos(input):
159
196
mean_smape_prophet = np .mean (smape_prophet_vec )
160
197
mean_mase_chronos = np .mean (mase_chronos_vec )
161
198
mean_smape_chronos = np .mean (smape_chronos_vec )
199
+ mean_crps_prophet = np .mean (crps_prophet_vec )
162
200
163
- df_results_mean = pd .DataFrame ({'smape' : [mean_smape_prophet , mean_smape_chronos ], 'mase' : [mean_mase_prophet , mean_mase_chronos ], 'owa' : [owa_prophet , owa_chronos ]})
164
-
201
+ df_prophet_results = pd .DataFrame ({'smape' : [mean_smape_prophet ], 'mase' : [mean_mase_prophet ], 'owa' : [owa_prophet ], 'crps' : [ mean_crps_prophet ], 'crps_median' : [ np . median ( crps_prophet_vec ) ]})
202
+ df_chronos_results = pd . DataFrame ({ 'smape' : [ mean_smape_chronos ], 'mase' : [ mean_mase_chronos ], 'owa' : [ owa_chronos ]})
165
203
# save to csv
166
204
167
- df_results_mean .to_csv ('paper_tests/m4_test/metrics_results/PROPHET_CHRONOS_METRICS_RESULTS.csv' )
205
+ df_prophet_results .to_csv ('paper_tests/m4_test/metrics_results/PROPHET_METRICS_RESULTS.csv' )
206
+ df_chronos_results .to_csv ('paper_tests/m4_test/metrics_results/CHRONOS_METRICS_RESULTS.csv' )
0 commit comments