Skip to content

Commit e5fb390

Browse files
Merge pull request #54 from LAMPSPUC/Add_assertions
Add assertions to improve input validation and prevent bugs
2 parents 2f30ca0 + 701515a commit e5fb390

File tree

3 files changed

+94
-2
lines changed

3 files changed

+94
-2
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "StateSpaceLearning"
22
uuid = "971c4b7c-2c4e-4bac-8525-e842df3cde7b"
33
authors = ["andreramosfc <[email protected]>"]
4-
version = "1.4.1"
4+
version = "1.4.2"
55

66
[deps]
77
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"

paper_tests/m4_test/m4_test.py

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22
import math
33
import statsmodels.api as sm
44
import numpy as np
5+
from prophet import Prophet
6+
from chronos import ChronosPipeline
7+
import torch
58

69
df_train1 = pd.read_csv("paper_tests/m4_test/Monthly-train1.csv")
710
df_train2 = pd.read_csv("paper_tests/m4_test/Monthly-train2.csv")
811
df_train3 = pd.read_csv("paper_tests/m4_test/Monthly-train3.csv")
912
df_train4 = pd.read_csv("paper_tests/m4_test/Monthly-train4.csv")
1013
df_train = pd.concat([df_train1, df_train2, df_train3, df_train4])
1114
m4_info = pd.read_csv("paper_tests/m4_test/M4-info.csv")
15+
1216
df_test = pd.read_csv("paper_tests/m4_test/Monthly-test.csv")
1317
ssl_init_df = pd.read_csv("paper_tests/m4_test/init_SSL/SSL_aic_0.1_false.csv")
1418

@@ -54,6 +58,7 @@ def evaluate_ss(input, sample_size, init, hyperparameters_inicialization):
5458
forecast_values = [x * (max_train - min_train) + min_train for x in normalized_forecast_values]
5559
return sMAPE(test, forecast_values), MASE(train, test, forecast_values)
5660

61+
5762
results = []
5863
results_init = []
5964
for i in range(0, 48000):
@@ -85,4 +90,78 @@ def evaluate_ss(input, sample_size, init, hyperparameters_inicialization):
8590
df_mean_init = pd.DataFrame({'smape': [np.mean(smape_SS_init)], 'mase': [np.mean(mase_SS_init)], 'owa': [(np.mean(smape_SS_init) / NAIVE_sMAPE + np.mean(mase_SS_init) / NAIVE_MASE) / 2]})
8691

8792
df_mean.to_csv('paper_tests/m4_test/metrics_results/SS_METRICS_RESULTS.csv')
88-
df_mean_init.to_csv('paper_tests/m4_test/metrics_results/SS_INIT_METRICS_RESULTS.csv')
93+
df_mean_init.to_csv('paper_tests/m4_test/metrics_results/SS_INIT_METRICS_RESULTS.csv')
94+
95+
def evaluate_prophet(input):
96+
train = input["train"]
97+
test = input["test"]
98+
timestamps = pd.date_range(start="2020-01-01", periods=len(train), freq='ME')
99+
#add random seed
100+
df = pd.DataFrame({
101+
'ds': timestamps,
102+
'y': train
103+
})
104+
model = Prophet(interval_width=0.95)
105+
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+
})
109+
model_forecast = model.predict(future)
110+
prediction = model_forecast['yhat'].values
111+
return sMAPE(test, prediction), MASE(train, test, prediction)
112+
113+
def evaluate_chronos(input):
114+
train = input["train"]
115+
test = input["test"]
116+
chronos_forecast = ChronosPipeline.from_pretrained(
117+
f"amazon/chronos-t5-large",
118+
device_map="mps"
119+
).predict(
120+
context=torch.tensor(train),
121+
prediction_length=18,
122+
limit_prediction_length=False
123+
)
124+
prediction = np.quantile(chronos_forecast[0].numpy(), [0.5], axis=0)[0]
125+
return sMAPE(test, prediction), MASE(train, test, prediction)
126+
127+
smape_prophet_vec = []
128+
mase_prophet_vec = []
129+
smape_chronos_vec = []
130+
mase_chronos_vec = []
131+
for i in range(0, len(dict_vec)):
132+
smape_prophet, mase_prophet = evaluate_prophet(dict_vec[i])
133+
smape_prophet_vec.append(smape_prophet)
134+
mase_prophet_vec.append(mase_prophet)
135+
smape_chronos, mase_chronos = evaluate_chronos(dict_vec[i])
136+
smape_chronos_vec.append(smape_chronos)
137+
mase_chronos_vec.append(mase_chronos)
138+
#
139+
print("Runningg series ", i)
140+
if i % 1000 == 0:
141+
print("Runningg series ", i)
142+
smape_mean_prophet = np.mean(smape_prophet_vec)
143+
smape_emean_chronos = np.mean(smape_chronos_vec)
144+
mase_mean_prophet = np.mean(mase_prophet_vec)
145+
mase_mean_chronos = np.mean(mase_chronos_vec)
146+
print("Mean sMape Prophet: ", smape_mean_prophet)
147+
print("Mean sMape Chronos: ", smape_emean_chronos)
148+
print("Mean Mase Prophet: ", mase_mean_prophet)
149+
print("Mean Mase Chronos: ", mase_mean_chronos)
150+
151+
152+
NAIVE_sMAPE = 14.427 #M4 Paper
153+
NAIVE_MASE = 1.063 #M4 Paper
154+
155+
owa_prophet = (np.mean(smape_prophet_vec) / NAIVE_sMAPE + np.mean(mase_prophet_vec) / NAIVE_MASE) / 2
156+
owa_chronos = (np.mean(smape_chronos_vec) / NAIVE_sMAPE + np.mean(mase_chronos_vec) / NAIVE_MASE) / 2
157+
158+
mean_mase_prophet = np.mean(mase_prophet_vec)
159+
mean_smape_prophet = np.mean(smape_prophet_vec)
160+
mean_mase_chronos = np.mean(mase_chronos_vec)
161+
mean_smape_chronos = np.mean(smape_chronos_vec)
162+
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+
165+
# save to csv
166+
167+
df_results_mean.to_csv('paper_tests/m4_test/metrics_results/PROPHET_CHRONOS_METRICS_RESULTS.csv')

src/models/structural_model.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,19 @@ mutable struct StructuralModel <: StateSpaceLearningModel
116116
else
117117
cycle_matrix = Vector{Matrix}(undef, 0)
118118
end
119+
120+
if typeof(freq_seasonal) <: Vector
121+
@assert all(freq_seasonal .> 0) "Seasonal period must be greater than 0"
122+
end
123+
124+
if typeof(cycle_period) <: Vector
125+
@assert all(cycle_period .>= 0) "Cycle period must be greater than or equal to 0"
126+
end
127+
128+
if cycle_period == 0
129+
@assert !stochastic_cycle "stochastic_cycle must be false if cycle_period is 0"
130+
end
131+
119132
X = create_X(
120133
level,
121134
stochastic_level,

0 commit comments

Comments
 (0)