-
Notifications
You must be signed in to change notification settings - Fork 918
/
Copy pathtest_ensemble_models.py
149 lines (123 loc) · 5.27 KB
/
test_ensemble_models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import numpy as np
import pandas as pd
import unittest
from darts.tests.base_test_class import DartsBaseTestClass
from darts import TimeSeries
from darts.utils import timeseries_generation as tg
from darts.models import NaiveDrift, NaiveSeasonal, Theta, ExponentialSmoothing
from darts.models import NaiveEnsembleModel
from darts.logging import get_logger
logger = get_logger(__name__)
try:
from darts.models import RNNModel, TCNModel, NBEATSModel
TORCH_AVAILABLE = True
except ImportError:
logger.warning("Torch not installed - Some ensemble models tests will be skipped.")
TORCH_AVAILABLE = False
def _make_ts(start_value=0, n=100):
times = pd.date_range(start="1/1/2013", periods=n, freq="D")
pd_series = pd.Series(range(start_value, start_value + n), index=times)
return TimeSeries.from_series(pd_series)
class EnsembleModelsTestCase(DartsBaseTestClass):
series1 = tg.sine_timeseries(value_frequency=(1 / 5), value_y_offset=10, length=50)
series2 = tg.linear_timeseries(length=50)
seq1 = [_make_ts(0), _make_ts(10), _make_ts(20)]
cov1 = [_make_ts(5), _make_ts(15), _make_ts(25)]
def test_untrained_models(self):
model = NaiveDrift()
_ = NaiveEnsembleModel([model])
# trained models should raise error
model.fit(self.series1)
with self.assertRaises(ValueError):
NaiveEnsembleModel([model])
def test_input_models_local_models(self):
with self.assertRaises(ValueError):
NaiveEnsembleModel([])
with self.assertRaises(ValueError):
NaiveEnsembleModel([NaiveDrift, NaiveSeasonal, Theta, ExponentialSmoothing])
with self.assertRaises(ValueError):
NaiveEnsembleModel(
[NaiveDrift(), NaiveSeasonal, Theta(), ExponentialSmoothing()]
)
NaiveEnsembleModel(
[NaiveDrift(), NaiveSeasonal(), Theta(), ExponentialSmoothing()]
)
def test_call_predict_local_models(self):
naive_ensemble = NaiveEnsembleModel([NaiveSeasonal(), Theta()])
with self.assertRaises(Exception):
naive_ensemble.predict(5)
naive_ensemble.fit(self.series1)
naive_ensemble.predict(5)
def test_predict_ensemble_local_models(self):
naive = NaiveSeasonal(K=5)
theta = Theta()
naive_ensemble = NaiveEnsembleModel([naive, theta])
naive_ensemble.fit(self.series1 + self.series2)
forecast_naive_ensemble = naive_ensemble.predict(5)
naive.fit(self.series1 + self.series2)
theta.fit(self.series1 + self.series2)
forecast_mean = 0.5 * naive.predict(5) + 0.5 * theta.predict(5)
self.assertTrue(
np.array_equal(forecast_naive_ensemble.values(), forecast_mean.values())
)
@unittest.skipUnless(TORCH_AVAILABLE, "requires torch")
def test_input_models_global_models(self):
NaiveEnsembleModel([RNNModel(), TCNModel(10, 2), NBEATSModel(10, 2)])
@unittest.skipUnless(TORCH_AVAILABLE, "requires torch")
def test_call_predict_global_models_univariate_input_no_covariates(self):
naive_ensemble = NaiveEnsembleModel(
[
RNNModel(n_epochs=1),
TCNModel(10, 2, n_epochs=1),
NBEATSModel(10, 2, n_epochs=1),
]
)
with self.assertRaises(Exception):
naive_ensemble.predict(5)
naive_ensemble.fit(self.series1)
naive_ensemble.predict(5)
@unittest.skipUnless(TORCH_AVAILABLE, "requires torch")
def test_call_predict_global_models_multivariate_input_no_covariates(self):
naive_ensemble = NaiveEnsembleModel(
[
RNNModel(n_epochs=1),
TCNModel(10, 2, n_epochs=1),
NBEATSModel(10, 2, n_epochs=1),
]
)
naive_ensemble.fit(self.seq1)
naive_ensemble.predict(n=5, series=self.seq1)
@unittest.skipUnless(TORCH_AVAILABLE, "requires torch")
def test_call_predict_global_models_multivariate_input_with_covariates(self):
naive_ensemble = NaiveEnsembleModel(
[
RNNModel(n_epochs=1),
TCNModel(10, 2, n_epochs=1),
NBEATSModel(10, 2, n_epochs=1),
]
)
naive_ensemble.fit(self.seq1, self.cov1)
predict_series = [s[:12] for s in self.seq1]
predict_covariates = [c[:14] for c in self.cov1]
naive_ensemble.predict(
n=2, series=predict_series, past_covariates=predict_covariates
)
@unittest.skipUnless(TORCH_AVAILABLE, "requires torch")
def test_input_models_mixed(self):
with self.assertRaises(ValueError):
NaiveEnsembleModel([NaiveDrift(), Theta(), RNNModel()])
def test_fit_multivar_ts_with_local_models(self):
naive = NaiveEnsembleModel(
[NaiveDrift(), NaiveSeasonal(), Theta(), ExponentialSmoothing()]
)
with self.assertRaises(ValueError):
naive.fit(self.seq1)
def test_fit_univar_ts_with_covariates_for_local_models(self):
naive = NaiveEnsembleModel(
[NaiveDrift(), NaiveSeasonal(), Theta(), ExponentialSmoothing()]
)
with self.assertRaises(ValueError):
naive.fit(self.series1, self.series2)
if __name__ == "__main__":
import unittest
unittest.main()