azulgarza commited on
Commit
a217ce1
1 Parent(s): 68740d5

feat: add nixtla pp

Browse files
Files changed (6) hide show
  1. .gitignore +131 -0
  2. app.py +374 -0
  3. requirements.txt +11 -0
  4. src/model_descriptions.py +522 -0
  5. src/nf.py +211 -0
  6. src/st_deploy.py +16 -0
.gitignore ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+ # pyenv
85
+ .python-version
86
+
87
+ # pipenv
88
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
90
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
91
+ # install all needed dependencies.
92
+ #Pipfile.lock
93
+
94
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95
+ __pypackages__/
96
+
97
+ # Celery stuff
98
+ celerybeat-schedule
99
+ celerybeat.pid
100
+
101
+ # SageMath parsed files
102
+ *.sage.py
103
+
104
+ # Environments
105
+ .env
106
+ .venv
107
+ env/
108
+ venv/
109
+ ENV/
110
+ env.bak/
111
+ venv.bak/
112
+
113
+ # Spyder project settings
114
+ .spyderproject
115
+ .spyproject
116
+
117
+ # Rope project settings
118
+ .ropeproject
119
+
120
+ # mkdocs documentation
121
+ /site
122
+
123
+ # mypy
124
+ .mypy_cache/
125
+ .dmypy.json
126
+ dmypy.json
127
+
128
+ # Pyre type checker
129
+ .pyre/
130
+
131
+ models/
app.py ADDED
@@ -0,0 +1,374 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from time import time
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+ import plotly.express as px
6
+ import plotly.graph_objects as go
7
+ import streamlit as st
8
+ from datasetsforecast.losses import rmse, mae, smape, mse, mape
9
+ from st_aggrid import AgGrid
10
+
11
+ from src.nf import MODELS, forecast_pretrained_model
12
+ from src.model_descriptions import model_cards
13
+
14
+ DATASETS = {
15
+ "Electricity (Ercot COAST)": "https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/ercot_COAST.csv",
16
+ #"Electriciy (ERCOT, multiple markets)": "https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/ercot_multiple_ts.csv",
17
+ "Web Traffic (Peyton Manning)": "https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/peyton_manning.csv",
18
+ "Demand (AirPassengers)": "https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/air_passengers.csv",
19
+ "Finance (Exchange USD-EUR)": "https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/usdeur.csv",
20
+ }
21
+
22
+
23
+ @st.cache_data
24
+ def convert_df(df):
25
+ # IMPORTANT: Cache the conversion to prevent computation on every rerun
26
+ return df.to_csv(index=False).encode("utf-8")
27
+
28
+
29
+ def plot(df, uid, df_forecast, model):
30
+ figs = []
31
+ figs += [
32
+ go.Scatter(
33
+ x=df["ds"],
34
+ y=df["y"],
35
+ mode="lines",
36
+ marker=dict(color="#236796"),
37
+ legendrank=1,
38
+ name=uid,
39
+ ),
40
+ ]
41
+ if df_forecast is not None:
42
+ ds_f = df_forecast["ds"].to_list()
43
+ lo = df_forecast["forecast_lo_90"].to_list()
44
+ hi = df_forecast["forecast_hi_90"].to_list()
45
+ figs += [
46
+ go.Scatter(
47
+ x=ds_f + ds_f[::-1],
48
+ y=hi + lo[::-1],
49
+ fill="toself",
50
+ fillcolor="#E7C4C0",
51
+ mode="lines",
52
+ line=dict(color="#E7C4C0"),
53
+ name="Prediction Intervals (90%)",
54
+ legendrank=5,
55
+ opacity=0.5,
56
+ hoverinfo="skip",
57
+ ),
58
+ go.Scatter(
59
+ x=ds_f,
60
+ y=df_forecast["forecast"],
61
+ mode="lines",
62
+ legendrank=4,
63
+ marker=dict(color="#E7C4C0"),
64
+ name=f"Forecast {uid}",
65
+ ),
66
+ ]
67
+ fig = go.Figure(figs)
68
+ fig.update_layout(
69
+ {"plot_bgcolor": "rgba(0, 0, 0, 0)", "paper_bgcolor": "rgba(0, 0, 0, 0)"}
70
+ )
71
+ fig.update_layout(
72
+ title=f"Forecasts for {uid} using Transfer Learning (from {model})",
73
+ legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
74
+ margin=dict(l=20, b=20),
75
+ xaxis=dict(rangeslider=dict(visible=True)),
76
+ )
77
+ initial_range = [df.tail(200)["ds"].iloc[0], ds_f[-1]]
78
+ fig["layout"]["xaxis"].update(range=initial_range)
79
+ return fig
80
+
81
+
82
+ def st_transfer_learning():
83
+ st.set_page_config(
84
+ page_title="Time Series Visualization",
85
+ page_icon="🔮",
86
+ layout="wide",
87
+ initial_sidebar_state="expanded",
88
+ )
89
+
90
+ st.title(
91
+ "Transfer Learning: Revolutionizing Time Series by Nixtla"
92
+ )
93
+ st.write(
94
+ "<style>div.block-container{padding-top:2rem;}</style>", unsafe_allow_html=True
95
+ )
96
+
97
+ intro = """
98
+ The success of startups like Open AI and Stability highlights the potential for transfer learning (TL) techniques to have a similar impact on the field of time series forecasting.
99
+
100
+ TL can achieve lightning-fast predictions with a fraction of the computational cost by pre-training a flexible model on a large dataset and then using it on another dataset with little to no additional training.
101
+
102
+ In this live demo, you can use pre-trained models by Nixtla (trained on the M4 dataset) to predict your own datasets. You can also see how the models perform on unseen example datasets.
103
+ """
104
+ st.write(intro)
105
+
106
+ required_cols = ["ds", "y"]
107
+
108
+ with st.sidebar.expander("Dataset", expanded=False):
109
+ data_selection = st.selectbox("Select example dataset", DATASETS.keys())
110
+ data_url = DATASETS[data_selection]
111
+ url_json = st.text_input("Data (you can pass your own url here)", data_url)
112
+ st.write(
113
+ "You can also upload a CSV file like [this one](https://github.com/Nixtla/transfer-learning-time-series/blob/main/datasets/air_passengers.csv)."
114
+ )
115
+
116
+ uploaded_file = st.file_uploader("Upload CSV")
117
+ with st.form("Data"):
118
+
119
+ if uploaded_file is not None:
120
+ df = pd.read_csv(uploaded_file)
121
+ cols = df.columns
122
+ timestamp_col = st.selectbox("Timestamp column", options=cols)
123
+ value_col = st.selectbox("Value column", options=cols)
124
+ else:
125
+ timestamp_col = st.text_input("Timestamp column", value="timestamp")
126
+ value_col = st.text_input("Value column", value="value")
127
+ st.write("You must press Submit each time you want to forecast.")
128
+ submitted = st.form_submit_button("Submit")
129
+ if submitted:
130
+ if uploaded_file is None:
131
+ st.write("Please provide a dataframe.")
132
+ if url_json.endswith("json"):
133
+ df = pd.read_json(url_json)
134
+ else:
135
+ df = pd.read_csv(url_json)
136
+ df = df.rename(
137
+ columns=dict(zip([timestamp_col, value_col], required_cols))
138
+ )
139
+ else:
140
+ # df = pd.read_csv(uploaded_file)
141
+ df = df.rename(
142
+ columns=dict(zip([timestamp_col, value_col], required_cols))
143
+ )
144
+ else:
145
+ if url_json.endswith("json"):
146
+ df = pd.read_json(url_json)
147
+ else:
148
+ df = pd.read_csv(url_json)
149
+ cols = df.columns
150
+ if "unique_id" in cols:
151
+ cols = cols[-2:]
152
+ df = df.rename(columns=dict(zip(cols, required_cols)))
153
+
154
+ if "unique_id" not in df:
155
+ df.insert(0, "unique_id", "ts_0")
156
+
157
+ df["ds"] = pd.to_datetime(df["ds"])
158
+ df = df.sort_values(["unique_id", "ds"])
159
+
160
+ with st.sidebar:
161
+ st.write("Define the pretrained model you want to use to forecast your data")
162
+ model_name = st.selectbox("Select your model", tuple(MODELS.keys()))
163
+ model_file = MODELS[model_name]["model"]
164
+ st.write("Choose how many steps you want to forecast")
165
+ fh = st.number_input("Forecast horizon", value=18)
166
+ st.write(
167
+ "Choose for how many steps the pretrained model will be updated using your data (use 0 for fast computation)"
168
+ )
169
+ max_steps = st.number_input("N-shot inference", value=0)
170
+
171
+ # tabs
172
+ tab_fcst, tab_cv, tab_docs, tab_nixtla = st.tabs(
173
+ [
174
+ "📈 Forecast",
175
+ "🔎 Cross Validation",
176
+ "📚 Documentation",
177
+ "🔮 Nixtlaverse",
178
+ ]
179
+ )
180
+
181
+ uids = df["unique_id"].unique()
182
+ fcst_cols = ["forecast_lo_90", "forecast", "forecast_hi_90"]
183
+
184
+ with tab_fcst:
185
+ uid = uids[0]#st.selectbox("Dataset", options=uids)
186
+ col1, col2 = st.columns([2, 4])
187
+ with col1:
188
+ tab_insample, tab_forecast = st.tabs(
189
+ ["Modify input data", "Modify forecasts"]
190
+ )
191
+ with tab_insample:
192
+ df_grid = df.query("unique_id == @uid").drop(columns="unique_id")
193
+ grid_table = AgGrid(
194
+ df_grid,
195
+ editable=True,
196
+ theme="streamlit",
197
+ fit_columns_on_grid_load=True,
198
+ height=360,
199
+ )
200
+ df.loc[df["unique_id"] == uid, "y"] = (
201
+ grid_table["data"].sort_values("ds")["y"].values
202
+ )
203
+ # forecast code
204
+ init = time()
205
+ df_forecast = forecast_pretrained_model(df, model_file, fh, max_steps)
206
+ end = time()
207
+ df_forecast = df_forecast.rename(
208
+ columns=dict(zip(["y_5", "y_50", "y_95"], fcst_cols))
209
+ )
210
+ with tab_forecast:
211
+ df_fcst_grid = df_forecast.query("unique_id == @uid").filter(
212
+ ["ds", "forecast"]
213
+ )
214
+ grid_fcst_table = AgGrid(
215
+ df_fcst_grid,
216
+ editable=True,
217
+ theme="streamlit",
218
+ fit_columns_on_grid_load=True,
219
+ height=360,
220
+ )
221
+ changes = (
222
+ df_forecast.query("unique_id == @uid")["forecast"].values
223
+ - grid_fcst_table["data"].sort_values("ds")["forecast"].values
224
+ )
225
+ for col in fcst_cols:
226
+ df_forecast.loc[df_forecast["unique_id"] == uid, col] = (
227
+ df_forecast.loc[df_forecast["unique_id"] == uid, col] - changes
228
+ )
229
+ with col2:
230
+ st.plotly_chart(
231
+ plot(
232
+ df.query("unique_id == @uid"),
233
+ uid,
234
+ df_forecast.query("unique_id == @uid"),
235
+ model_name,
236
+ ),
237
+ use_container_width=True,
238
+ )
239
+ st.success(f'Done! Approximate inference time CPU: {0.7*(end-init):.2f} seconds.')
240
+
241
+ with tab_cv:
242
+ col_uid, col_n_windows = st.columns(2)
243
+ uid = uids[0]
244
+ #with col_uid:
245
+ # uid = st.selectbox("Time series to analyse", options=uids, key="uid_cv")
246
+ with col_n_windows:
247
+ n_windows = st.number_input("Cross validation windows", value=1)
248
+ df_forecast = []
249
+ for i_window in range(n_windows, 0, -1):
250
+ test = df.groupby("unique_id").tail(i_window * fh)
251
+ df_forecast_w = forecast_pretrained_model(
252
+ df.drop(test.index), model_file, fh, max_steps
253
+ )
254
+ df_forecast_w = df_forecast_w.rename(
255
+ columns=dict(zip(["y_5", "y_50", "y_95"], fcst_cols))
256
+ )
257
+ df_forecast_w.insert(2, "window", i_window)
258
+ df_forecast.append(df_forecast_w)
259
+ df_forecast = pd.concat(df_forecast)
260
+ df_forecast["ds"] = pd.to_datetime(df_forecast["ds"])
261
+ df_forecast = df_forecast.merge(df, how="left", on=["unique_id", "ds"])
262
+ metrics = [mae, mape, rmse, smape]
263
+ evaluation = df_forecast.groupby(["unique_id", "window"]).apply(
264
+ lambda df: [f'{fn(df["y"].values, df["forecast"]):.2f}' for fn in metrics]
265
+ )
266
+ evaluation = evaluation.rename("eval").reset_index()
267
+ evaluation["eval"] = evaluation["eval"].str.join(",")
268
+ evaluation[["MAE", "MAPE", "RMSE", "sMAPE"]] = evaluation["eval"].str.split(
269
+ ",", expand=True
270
+ )
271
+ col_eval, col_plot = st.columns([2, 4])
272
+ with col_eval:
273
+ st.write("Evaluation metrics for each cross validation window")
274
+ st.dataframe(
275
+ evaluation.query("unique_id == @uid")
276
+ .drop(columns=["unique_id", "eval"])
277
+ .set_index("window")
278
+ )
279
+ with col_plot:
280
+ st.plotly_chart(
281
+ plot(
282
+ df.query("unique_id == @uid"),
283
+ uid,
284
+ df_forecast.query("unique_id == @uid").drop(columns="y"),
285
+ model_name,
286
+ ),
287
+ use_container_width=True,
288
+ )
289
+ with tab_docs:
290
+ tab_transfer, tab_desc, tab_ref = st.tabs(
291
+ [
292
+ "🚀 Transfer Learning",
293
+ "🔎 Description of the model",
294
+ "📚 References",
295
+ ]
296
+ )
297
+
298
+ with tab_desc:
299
+ model_card_name = MODELS[model_name]["card"]
300
+ st.subheader("Abstract")
301
+ st.write(f"""{model_cards[model_card_name]['Abstract']}""")
302
+ st.subheader("Intended use")
303
+ st.write(f"""{model_cards[model_card_name]['Intended use']}""")
304
+ st.subheader("Secondary use")
305
+ st.write(f"""{model_cards[model_card_name]['Secondary use']}""")
306
+ st.subheader("Limitations")
307
+ st.write(f"""{model_cards[model_card_name]['Limitations']}""")
308
+ st.subheader("Training data")
309
+ st.write(f"""{model_cards[model_card_name]['Training data']}""")
310
+ st.subheader("BibTex/Citation Info")
311
+ st.code(f"""{model_cards[model_card_name]['Citation Info']}""")
312
+
313
+ with tab_transfer:
314
+ transfer_text = """
315
+ Transfer learning refers to the process of pre-training a flexible model on a large dataset and using it later on other data with little to no training. It is one of the most outstanding 🚀 achievements in Machine Learning 🧠 and has many practical applications.
316
+
317
+ For time series forecasting, the technique allows you to get lightning-fast predictions ⚡ bypassing the tradeoff between accuracy and speed.
318
+
319
+ [This notebook](https://colab.research.google.com/drive/1uFCO2UBpH-5l2fk3KmxfU0oupsOC6v2n?authuser=0&pli=1#cell-5=) shows how to generate a pre-trained model and store it in a checkpoint to make it available for public use to forecast new time series never seen by the model.
320
+ **You can contribute with your pre-trained models by following [this Notebook](https://github.com/Nixtla/transfer-learning-time-series/blob/main/nbs/Transfer_Learning.ipynb) and sending us an email at federico[at]nixtla.io**
321
+
322
+ You can also take a look at list of pretrained models here. Currently we have this ones avaiable in our [API](https://docs.nixtla.io/reference/neural_transfer_neural_transfer_post) or [Demo](http://nixtla.io/transfer-learning/). You can also download the `.ckpt`:
323
+ - [Pretrained N-HiTS M4 Hourly](https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/nhits_m4_hourly.ckpt)
324
+ - [Pretrained N-HiTS M4 Hourly (Tiny)](https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/nhits_m4_hourly_tiny.ckpt)
325
+ - [Pretrained N-HiTS M4 Daily](https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/nhits_m4_daily.ckpt)
326
+ - [Pretrained N-HiTS M4 Monthly](https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/nhits_m4_monthly.ckpt)
327
+ - [Pretrained N-HiTS M4 Yearly](https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/nhits_m4_yearly.ckpt)
328
+ - [Pretrained N-BEATS M4 Hourly](https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/nbeats_m4_hourly.ckpt)
329
+ - [Pretrained N-BEATS M4 Daily](https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/nbeats_m4_daily.ckpt)
330
+ - [Pretrained N-BEATS M4 Weekly](https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/nbeats_m4_weekly.ckpt)
331
+ - [Pretrained N-BEATS M4 Monthly](https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/nbeats_m4_monthly.ckpt)
332
+ - [Pretrained N-BEATS M4 Yearly](https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/nbeats_m4_yearly.ckpt)
333
+ """
334
+ st.write(transfer_text)
335
+
336
+ with tab_ref:
337
+ ref_text = """
338
+ If you are interested in the transfer learning literature applied to time series forecasting, take a look at these papers:
339
+ - [Meta-learning framework with applications to zero-shot time-series forecasting](https://arxiv.org/abs/2002.02887)
340
+ - [N-HiTS: Neural Hierarchical Interpolation for Time Series Forecasting](https://arxiv.org/abs/2201.12886)
341
+ """
342
+ st.write(ref_text)
343
+
344
+ with tab_nixtla:
345
+ nixtla_text = """
346
+ Nixtla is a startup that is building forecasting software for Data Scientists and Devs.
347
+
348
+ We have been developing different open source libraries for machine learning, statistical and deep learning forecasting.
349
+
350
+ In our [GitHub repo](https://github.com/Nixtla), you can find the projects that support this APP.
351
+ """
352
+ st.write(nixtla_text)
353
+ st.image(
354
+ "https://files.readme.io/168cdb2-Screen_Shot_2022-09-30_at_10.40.09.png",
355
+ width=800,
356
+ )
357
+
358
+ with st.sidebar:
359
+ st.download_button(
360
+ label="Download historical data as CSV",
361
+ data=convert_df(df),
362
+ file_name="history.csv",
363
+ mime="text/csv",
364
+ )
365
+ st.download_button(
366
+ label="Download forecasts as CSV",
367
+ data=convert_df(df_forecast),
368
+ file_name="forecasts.csv",
369
+ mime="text/csv",
370
+ )
371
+
372
+
373
+ if __name__ == "__main__":
374
+ st_transfer_learning()
requirements.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ datasetsforecast
2
+ fire
3
+ neuralforecast<1.0.0
4
+ pandas
5
+ plotly
6
+ python-dotenv
7
+ pytorch-lightning==1.6.3
8
+ statsforecast
9
+ streamlit
10
+ streamlit-aggrid
11
+ torch==1.11.0
src/model_descriptions.py ADDED
@@ -0,0 +1,522 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ model_cards = dict(
2
+ nhitsm={
3
+ "Abstract": (
4
+ "The N-HiTS_M incorporates hierarchical interpolation and multi-rate data sampling "
5
+ "techniques. It assembles its predictions sequentially, selectively emphasizing "
6
+ "components with different frequencies and scales, while decomposing the input signal "
7
+ " and synthesizing the forecast [Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, "
8
+ "Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski. N-HiTS: Neural "
9
+ "Hierarchical Interpolation for Time Series Forecasting, Submitted working paper.]"
10
+ "(https://arxiv.org/abs/2201.12886)"
11
+ ),
12
+ "Intended use": (
13
+ "The N-HiTS_M model specializes in monthly long-horizon forecasting by improving "
14
+ "accuracy and reducing the training time and memory requirements of the model."
15
+ ),
16
+ "Secondary use": (
17
+ "The interpretable predictions of the model produce a natural frequency time "
18
+ "series signal decomposition."
19
+ ),
20
+ "Limitations": (
21
+ "The transferability across different frequencies has not yet been tested, it is "
22
+ "advisable to restrict the use of N-HiTS_{M} to monthly data were it was pre-trained. "
23
+ "This model purely autorregresive, transferability of models with exogenous variables "
24
+ "is yet to be done."
25
+ ),
26
+ "Training data": (
27
+ "N-HiTS_M was trained on 48,000 monthly series from the M4 competition "
28
+ "[Spyros Makridakis, Evangelos Spiliotis, and Vassilios Assimakopoulos. The "
29
+ " M4 competition: 100,000 time series and 61 forecasting methods. International "
30
+ "Journal of Forecasting, 36(1):54–74, 2020. ISSN 0169-2070.]"
31
+ "(https://www.sciencedirect.com/science/article/pii/S0169207019301128)"
32
+ ),
33
+ "Citation Info": (
34
+ "@article{challu2022nhits,\n "
35
+ "author = {Cristian Challu and \n"
36
+ " Kin G. Olivares and \n"
37
+ " Boris N. Oreshkin and \n"
38
+ " Federico Garza and \n"
39
+ " Max Mergenthaler and \n"
40
+ " Artur Dubrawski}, \n "
41
+ "title = {N-HiTS: Neural Hierarchical Interpolation for Time Series Forecasting},\n "
42
+ "journal = {Computing Research Repository},\n "
43
+ "volume = {abs/2201.12886},\n "
44
+ "year = {2022},\n "
45
+ "url = {https://arxiv.org/abs/2201.12886},\n "
46
+ "eprinttype = {arXiv},\n "
47
+ "eprint = {2201.12886},\n "
48
+ "biburl = {https://dblp.org/rec/journals/corr/abs-2201-12886.bib}\n}"
49
+ ),
50
+ },
51
+ nhitsh={
52
+ "Abstract": (
53
+ "The N-HiTS_{H} incorporates hierarchical interpolation and multi-rate data sampling "
54
+ "techniques. It assembles its predictions sequentially, selectively emphasizing "
55
+ "components with different frequencies and scales, while decomposing the input signal "
56
+ " and synthesizing the forecast [Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, "
57
+ "Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski. N-HiTS: Neural "
58
+ "Hierarchical Interpolation for Time Series Forecasting, Submitted working paper.]"
59
+ "(https://arxiv.org/abs/2201.12886)"
60
+ ),
61
+ "Intended use": (
62
+ "The N-HiTS_{H} model specializes in hourly long-horizon forecasting by improving "
63
+ "accuracy and reducing the training time and memory requirements of the model."
64
+ ),
65
+ "Secondary use": (
66
+ "The interpretable predictions of the model produce a natural frequency time "
67
+ "series signal decomposition."
68
+ ),
69
+ "Limitations": (
70
+ "The transferability across different frequencies has not yet been tested, it is "
71
+ "advisable to restrict the use of N-HiTS_{H} to hourly data were it was pre-trained. "
72
+ "This model purely autorregresive, transferability of models with exogenous variables "
73
+ "is yet to be done."
74
+ ),
75
+ "Training data": (
76
+ "N-HiTS_{H} was trained on 414 hourly series from the M4 competition "
77
+ "[Spyros Makridakis, Evangelos Spiliotis, and Vassilios Assimakopoulos. The "
78
+ " M4 competition: 100,000 time series and 61 forecasting methods. International "
79
+ "Journal of Forecasting, 36(1):54–74, 2020. ISSN 0169-2070.]"
80
+ "(https://www.sciencedirect.com/science/article/pii/S0169207019301128)"
81
+ ),
82
+ "Citation Info": (
83
+ "@article{challu2022nhits,\n "
84
+ "author = {Cristian Challu and \n"
85
+ " Kin G. Olivares and \n"
86
+ " Boris N. Oreshkin and \n"
87
+ " Federico Garza and \n"
88
+ " Max Mergenthaler and \n"
89
+ " Artur Dubrawski}, \n "
90
+ "title = {N-HiTS: Neural Hierarchical Interpolation for Time Series Forecasting},\n "
91
+ "journal = {Computing Research Repository},\n "
92
+ "volume = {abs/2201.12886},\n "
93
+ "year = {2022},\n "
94
+ "url = {https://arxiv.org/abs/2201.12886},\n "
95
+ "eprinttype = {arXiv},\n "
96
+ "eprint = {2201.12886},\n "
97
+ "biburl = {https://dblp.org/rec/journals/corr/abs-2201-12886.bib}\n}"
98
+ ),
99
+ },
100
+ nhitsd={
101
+ "Abstract": (
102
+ "The N-HiTS_D incorporates hierarchical interpolation and multi-rate data sampling "
103
+ "techniques. It assembles its predictions sequentially, selectively emphasizing "
104
+ "components with different frequencies and scales, while decomposing the input signal "
105
+ " and synthesizing the forecast [Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, "
106
+ "Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski. N-HiTS: Neural "
107
+ "Hierarchical Interpolation for Time Series Forecasting, Submitted working paper.]"
108
+ "(https://arxiv.org/abs/2201.12886)"
109
+ ),
110
+ "Intended use": (
111
+ "The N-HiTS_D model specializes in daily long-horizon forecasting by improving "
112
+ "accuracy and reducing the training time and memory requirements of the model."
113
+ ),
114
+ "Secondary use": (
115
+ "The interpretable predictions of the model produce a natural frequency time "
116
+ "series signal decomposition."
117
+ ),
118
+ "Limitations": (
119
+ "The transferability across different frequencies has not yet been tested, it is "
120
+ "advisable to restrict the use of N-HiTS_D to daily data were it was pre-trained. "
121
+ "This model purely autorregresive, transferability of models with exogenous variables "
122
+ "is yet to be done."
123
+ ),
124
+ "Training data": (
125
+ "N-HiTS_D was trained on 4,227 daily series from the M4 competition "
126
+ "[Spyros Makridakis, Evangelos Spiliotis, and Vassilios Assimakopoulos. The "
127
+ " M4 competition: 100,000 time series and 61 forecasting methods. International "
128
+ "Journal of Forecasting, 36(1):54–74, 2020. ISSN 0169-2070.]"
129
+ "(https://www.sciencedirect.com/science/article/pii/S0169207019301128)"
130
+ ),
131
+ "Citation Info": (
132
+ "@article{challu2022nhits,\n "
133
+ "author = {Cristian Challu and \n"
134
+ " Kin G. Olivares and \n"
135
+ " Boris N. Oreshkin and \n"
136
+ " Federico Garza and \n"
137
+ " Max Mergenthaler and \n"
138
+ " Artur Dubrawski}, \n "
139
+ "title = {N-HiTS: Neural Hierarchical Interpolation for Time Series Forecasting},\n "
140
+ "journal = {Computing Research Repository},\n "
141
+ "volume = {abs/2201.12886},\n "
142
+ "year = {2022},\n "
143
+ "url = {https://arxiv.org/abs/2201.12886},\n "
144
+ "eprinttype = {arXiv},\n "
145
+ "eprint = {2201.12886},\n "
146
+ "biburl = {https://dblp.org/rec/journals/corr/abs-2201-12886.bib}\n}"
147
+ ),
148
+ },
149
+ nhitsy={
150
+ "Abstract": (
151
+ "The N-HiTS_Y incorporates hierarchical interpolation and multi-rate data sampling "
152
+ "techniques. It assembles its predictions sequentially, selectively emphasizing "
153
+ "components with different frequencies and scales, while decomposing the input signal "
154
+ " and synthesizing the forecast [Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, "
155
+ "Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski. N-HiTS: Neural "
156
+ "Hierarchical Interpolation for Time Series Forecasting, Submitted working paper.]"
157
+ "(https://arxiv.org/abs/2201.12886)"
158
+ ),
159
+ "Intended use": (
160
+ "The N-HiTS_Y model specializes in yearly long-horizon forecasting by improving "
161
+ "accuracy and reducing the training time and memory requirements of the model."
162
+ ),
163
+ "Secondary use": (
164
+ "The interpretable predictions of the model produce a natural frequency time "
165
+ "series signal decomposition."
166
+ ),
167
+ "Limitations": (
168
+ "The transferability across different frequencies has not yet been tested, it is "
169
+ "advisable to restrict the use of N-HiTS_Y to yearly data were it was pre-trained. "
170
+ "This model purely autorregresive, transferability of models with exogenous variables "
171
+ "is yet to be done."
172
+ ),
173
+ "Training data": (
174
+ "N-HiTS_{H} was trained on 23,000 yearly series from the M4 competition "
175
+ "[Spyros Makridakis, Evangelos Spiliotis, and Vassilios Assimakopoulos. The "
176
+ " M4 competition: 100,000 time series and 61 forecasting methods. International "
177
+ "Journal of Forecasting, 36(1):54–74, 2020. ISSN 0169-2070.]"
178
+ "(https://www.sciencedirect.com/science/article/pii/S0169207019301128)"
179
+ ),
180
+ "Citation Info": (
181
+ "@article{challu2022nhits,\n "
182
+ "author = {Cristian Challu and \n"
183
+ " Kin G. Olivares and \n"
184
+ " Boris N. Oreshkin and \n"
185
+ " Federico Garza and \n"
186
+ " Max Mergenthaler and \n"
187
+ " Artur Dubrawski}, \n "
188
+ "title = {N-HiTS: Neural Hierarchical Interpolation for Time Series Forecasting},\n "
189
+ "journal = {Computing Research Repository},\n "
190
+ "volume = {abs/2201.12886},\n "
191
+ "year = {2022},\n "
192
+ "url = {https://arxiv.org/abs/2201.12886},\n "
193
+ "eprinttype = {arXiv},\n "
194
+ "eprint = {2201.12886},\n "
195
+ "biburl = {https://dblp.org/rec/journals/corr/abs-2201-12886.bib}\n}"
196
+ ),
197
+ },
198
+ nbeatsm={
199
+ "Abstract": (
200
+ "The N-BEATS_M models is a model based on a deep stack multi-layer percentrons connected"
201
+ "with doubly residual connections. The model combines a multi-step forecasting strategy "
202
+ "with projections unto piecewise functions for its generic version or polynomials and "
203
+ "harmonics for its interpretable version. [Boris N. Oreshkin, Dmitri Carpov, Nicolas "
204
+ "Chapados, Yoshua Bengio. N-BEATS: Neural basis expansion analysis for interpretable "
205
+ "time series forecasting. 8th International Conference on Learning Representations, "
206
+ "ICLR 2020.](https://arxiv.org/abs/1905.10437)"
207
+ ),
208
+ "Intended use": (
209
+ "The N-BEATS_M is an efficient univariate forecasting model specialized in monthly "
210
+ "data, that uses the multi-step forecasting strategy."
211
+ ),
212
+ "Secondary use": (
213
+ "The interpretable variant of N-BEATSi_M produces a trend and seasonality "
214
+ "decomposition."
215
+ ),
216
+ "Limitations": (
217
+ "The transferability across different frequencies has not yet been tested, it is "
218
+ "advisable to restrict the use of N-BEATS_M to monthly data were it was pre-trained."
219
+ "This model purely autorregresive, transferability of models with exogenous variables "
220
+ "is yet to be done."
221
+ ),
222
+ "Training data": (
223
+ "N-BEATS_M was trained on 48,000 monthly series from the M4 competition "
224
+ "[Spyros Makridakis, Evangelos Spiliotis, and Vassilios Assimakopoulos. The "
225
+ " M4 competition: 100,000 time series and 61 forecasting methods. International "
226
+ "Journal of Forecasting, 36(1):54–74, 2020. ISSN 0169-2070.]"
227
+ "(https://www.sciencedirect.com/science/article/pii/S0169207019301128)"
228
+ ),
229
+ "Citation Info": (
230
+ "@inproceedings{oreshkin2020nbeats,\n "
231
+ "author = {Boris N. Oreshkin and \n"
232
+ " Dmitri Carpov and \n"
233
+ " Nicolas Chapados and\n"
234
+ " Yoshua Bengio},\n "
235
+ "title = {{N-BEATS:} Neural basis expansion analysis for interpretable time series forecasting},\n "
236
+ "booktitle = {8th International Conference on Learning Representations, {ICLR} 2020},\n "
237
+ "year = {2020},\n "
238
+ "url = {https://openreview.net/forum?id=r1ecqn4YwB}\n }"
239
+ ),
240
+ },
241
+ nbeatsh={
242
+ "Abstract": (
243
+ "The N-BEATS_H models is a model based on a deep stack multi-layer percentrons connected"
244
+ "with doubly residual connections. The model combines a multi-step forecasting strategy "
245
+ "with projections unto piecewise functions for its generic version or polynomials and "
246
+ "harmonics for its interpretable version. [Boris N. Oreshkin, Dmitri Carpov, Nicolas "
247
+ "Chapados, Yoshua Bengio. N-BEATS: Neural basis expansion analysis for interpretable "
248
+ "time series forecasting. 8th International Conference on Learning Representations, "
249
+ "ICLR 2020.](https://arxiv.org/abs/1905.10437)"
250
+ ),
251
+ "Intended use": (
252
+ "The N-BEATS_H is an efficient univariate forecasting model specialized in hourly "
253
+ "data, that uses the multi-step forecasting strategy."
254
+ ),
255
+ "Secondary use": (
256
+ "The interpretable variant of N-BEATSi_H produces a trend and seasonality "
257
+ "decomposition."
258
+ ),
259
+ "Limitations": (
260
+ "The transferability across different frequencies has not yet been tested, it is "
261
+ "advisable to restrict the use of N-BEATS_H to hourly data were it was pre-trained."
262
+ "This model purely autorregresive, transferability of models with exogenous variables "
263
+ "is yet to be done."
264
+ ),
265
+ "Training data": (
266
+ "N-BEATS_H was trained on 414 hourly series from the M4 competition "
267
+ "[Spyros Makridakis, Evangelos Spiliotis, and Vassilios Assimakopoulos. The "
268
+ " M4 competition: 100,000 time series and 61 forecasting methods. International "
269
+ "Journal of Forecasting, 36(1):54–74, 2020. ISSN 0169-2070.]"
270
+ "(https://www.sciencedirect.com/science/article/pii/S0169207019301128)"
271
+ ),
272
+ "Citation Info": (
273
+ "@inproceedings{oreshkin2020nbeats,\n "
274
+ "author = {Boris N. Oreshkin and \n"
275
+ " Dmitri Carpov and \n"
276
+ " Nicolas Chapados and\n"
277
+ " Yoshua Bengio},\n "
278
+ "title = {{N-BEATS:} Neural basis expansion analysis for interpretable time series forecasting},\n "
279
+ "booktitle = {8th International Conference on Learning Representations, {ICLR} 2020},\n "
280
+ "year = {2020},\n "
281
+ "url = {https://openreview.net/forum?id=r1ecqn4YwB}\n }"
282
+ ),
283
+ },
284
+ nbeatsd={
285
+ "Abstract": (
286
+ "The N-BEATS_D models is a model based on a deep stack multi-layer percentrons connected"
287
+ "with doubly residual connections. The model combines a multi-step forecasting strategy "
288
+ "with projections unto piecewise functions for its generic version or polynomials and "
289
+ "harmonics for its interpretable version. [Boris N. Oreshkin, Dmitri Carpov, Nicolas "
290
+ "Chapados, Yoshua Bengio. N-BEATS: Neural basis expansion analysis for interpretable "
291
+ "time series forecasting. 8th International Conference on Learning Representations, "
292
+ "ICLR 2020.](https://arxiv.org/abs/1905.10437)"
293
+ ),
294
+ "Intended use": (
295
+ "The N-BEATS_D is an efficient univariate forecasting model specialized in hourly "
296
+ "data, that uses the multi-step forecasting strategy."
297
+ ),
298
+ "Secondary use": (
299
+ "The interpretable variant of N-BEATSi_D produces a trend and seasonality "
300
+ "decomposition."
301
+ ),
302
+ "Limitations": (
303
+ "The transferability across different frequencies has not yet been tested, it is "
304
+ "advisable to restrict the use of N-BEATS_D to daily data were it was pre-trained."
305
+ "This model purely autorregresive, transferability of models with exogenous variables "
306
+ "is yet to be done."
307
+ ),
308
+ "Training data": (
309
+ "N-BEATS_D was trained on 4,227 daily series from the M4 competition "
310
+ "[Spyros Makridakis, Evangelos Spiliotis, and Vassilios Assimakopoulos. The "
311
+ " M4 competition: 100,000 time series and 61 forecasting methods. International "
312
+ "Journal of Forecasting, 36(1):54–74, 2020. ISSN 0169-2070.]"
313
+ "(https://www.sciencedirect.com/science/article/pii/S0169207019301128)"
314
+ ),
315
+ "Citation Info": (
316
+ "@inproceedings{oreshkin2020nbeats,\n "
317
+ "author = {Boris N. Oreshkin and \n"
318
+ " Dmitri Carpov and \n"
319
+ " Nicolas Chapados and\n"
320
+ " Yoshua Bengio},\n "
321
+ "title = {{N-BEATS:} Neural basis expansion analysis for interpretable time series forecasting},\n "
322
+ "booktitle = {8th International Conference on Learning Representations, {ICLR} 2020},\n "
323
+ "year = {2020},\n "
324
+ "url = {https://openreview.net/forum?id=r1ecqn4YwB}\n }"
325
+ ),
326
+ },
327
+ nbeatsw={
328
+ "Abstract": (
329
+ "The N-BEATS_W models is a model based on a deep stack multi-layer percentrons connected"
330
+ "with doubly residual connections. The model combines a multi-step forecasting strategy "
331
+ "with projections unto piecewise functions for its generic version or polynomials and "
332
+ "harmonics for its interpretable version. [Boris N. Oreshkin, Dmitri Carpov, Nicolas "
333
+ "Chapados, Yoshua Bengio. N-BEATS: Neural basis expansion analysis for interpretable "
334
+ "time series forecasting. 8th International Conference on Learning Representations, "
335
+ "ICLR 2020.](https://arxiv.org/abs/1905.10437)"
336
+ ),
337
+ "Intended use": (
338
+ "The N-BEATS_W is an efficient univariate forecasting model specialized in weekly "
339
+ "data, that uses the multi-step forecasting strategy."
340
+ ),
341
+ "Secondary use": (
342
+ "The interpretable variant of N-BEATSi_W produces a trend and seasonality "
343
+ "decomposition."
344
+ ),
345
+ "Limitations": (
346
+ "The transferability across different frequencies has not yet been tested, it is "
347
+ "advisable to restrict the use of N-BEATS_W to weekly data were it was pre-trained."
348
+ "This model purely autorregresive, transferability of models with exogenous variables "
349
+ "is yet to be done."
350
+ ),
351
+ "Training data": (
352
+ "N-BEATS_W was trained on 359 weekly series from the M4 competition "
353
+ "[Spyros Makridakis, Evangelos Spiliotis, and Vassilios Assimakopoulos. The "
354
+ " M4 competition: 100,000 time series and 61 forecasting methods. International "
355
+ "Journal of Forecasting, 36(1):54–74, 2020. ISSN 0169-2070.]"
356
+ "(https://www.sciencedirect.com/science/article/pii/S0169207019301128)"
357
+ ),
358
+ "Citation Info": (
359
+ "@inproceedings{oreshkin2020nbeats,\n "
360
+ "author = {Boris N. Oreshkin and \n"
361
+ " Dmitri Carpov and \n"
362
+ " Nicolas Chapados and\n"
363
+ " Yoshua Bengio},\n "
364
+ "title = {{N-BEATS:} Neural basis expansion analysis for interpretable time series forecasting},\n "
365
+ "booktitle = {8th International Conference on Learning Representations, {ICLR} 2020},\n "
366
+ "year = {2020},\n "
367
+ "url = {https://openreview.net/forum?id=r1ecqn4YwB}\n }"
368
+ ),
369
+ },
370
+ nbeatsy={
371
+ "Abstract": (
372
+ "The N-BEATS_Y models is a model based on a deep stack multi-layer percentrons connected"
373
+ "with doubly residual connections. The model combines a multi-step forecasting strategy "
374
+ "with projections unto piecewise functions for its generic version or polynomials and "
375
+ "harmonics for its interpretable version. [Boris N. Oreshkin, Dmitri Carpov, Nicolas "
376
+ "Chapados, Yoshua Bengio. N-BEATS: Neural basis expansion analysis for interpretable "
377
+ "time series forecasting. 8th International Conference on Learning Representations, "
378
+ "ICLR 2020.](https://arxiv.org/abs/1905.10437)"
379
+ ),
380
+ "Intended use": (
381
+ "The N-BEATS_Y is an efficient univariate forecasting model specialized in hourly "
382
+ "data, that uses the multi-step forecasting strategy."
383
+ ),
384
+ "Secondary use": (
385
+ "The interpretable variant of N-BEATSi_Y produces a trend and seasonality "
386
+ "decomposition."
387
+ ),
388
+ "Limitations": (
389
+ "The transferability across different frequencies has not yet been tested, it is "
390
+ "advisable to restrict the use of N-BEATS_Y to yearly data were it was pre-trained."
391
+ "This model purely autorregresive, transferability of models with exogenous variables "
392
+ "is yet to be done."
393
+ ),
394
+ "Training data": (
395
+ "N-BEATS_Y was trained on 23,000 yearly series from the M4 competition "
396
+ "[Spyros Makridakis, Evangelos Spiliotis, and Vassilios Assimakopoulos. The "
397
+ " M4 competition: 100,000 time series and 61 forecasting methods. International "
398
+ "Journal of Forecasting, 36(1):54–74, 2020. ISSN 0169-2070.]"
399
+ "(https://www.sciencedirect.com/science/article/pii/S0169207019301128)"
400
+ ),
401
+ "Citation Info": (
402
+ "@inproceedings{oreshkin2020nbeats,\n "
403
+ "author = {Boris N. Oreshkin and \n"
404
+ " Dmitri Carpov and \n"
405
+ " Nicolas Chapados and\n"
406
+ " Yoshua Bengio},\n "
407
+ "title = {{N-BEATS:} Neural basis expansion analysis for interpretable time series forecasting},\n "
408
+ "booktitle = {8th International Conference on Learning Representations, {ICLR} 2020},\n "
409
+ "year = {2020},\n "
410
+ "url = {https://openreview.net/forum?id=r1ecqn4YwB}\n }"
411
+ ),
412
+ },
413
+ arima={
414
+ "Abstract": (
415
+ "The AutoARIMA model is a classic autoregressive model that automatically explores ARIMA"
416
+ "models with a step-wise algorithm using Akaike Information Criterion. It applies to "
417
+ "seasonal and non-seasonal data and has a proven record in the M3 forecasting competition. "
418
+ "An efficient open-source version of the model was only available in R but is now also "
419
+ "available in Python. [StatsForecast: Lightning fast forecasting with statistical and "
420
+ "econometric models](https://github.com/Nixtla/statsforecast)."
421
+ ),
422
+ "Intended use": (
423
+ "The AutoARIMA is an univariate forecasting model, intended to produce automatic "
424
+ "predictions for large numbers of time series."
425
+ ),
426
+ "Secondary use": (
427
+ "It is a classical model and is an almost obligated forecasting baseline."
428
+ ),
429
+ "Limitations": (
430
+ "ARIMA model uses a recurrent prediction strategy. It concatenates errors on long "
431
+ "horizon forecasting settings. It is a fairly simple model that does not model "
432
+ "non-linear relationships."
433
+ ),
434
+ "Training data": (
435
+ "The AutoARIMA is a univariate model that uses only autorregresive data from "
436
+ "the target variable."
437
+ ),
438
+ "Citation Info": (
439
+ "@article{hyndman2008auto_arima,"
440
+ "title={Automatic Time Series Forecasting: The forecast Package for R},\n"
441
+ "author={Hyndman, Rob J. and Khandakar, Yeasmin},\n"
442
+ "volume={27},\n"
443
+ "url={https://www.jstatsoft.org/index.php/jss/article/view/v027i03},\n"
444
+ "doi={10.18637/jss.v027.i03},\n"
445
+ "number={3},\n"
446
+ "journal={Journal of Statistical Software},\n"
447
+ "year={2008},\n"
448
+ "pages={1–22}\n"
449
+ "}"
450
+ ),
451
+ },
452
+ exp_smoothing={
453
+ "Abstract": (
454
+ "Exponential smoothing is a classic technique using exponential window functions, "
455
+ "and one of the most successful forecasting methods. It has a long history, the "
456
+ "name was coined by Charles C. Holt. [Holt, Charles C. (1957). Forecasting Trends "
457
+ 'and Seasonal by Exponentially Weighted Averages". Office of Naval Research '
458
+ "Memorandum.](https://www.sciencedirect.com/science/article/abs/pii/S0169207003001134)."
459
+ ),
460
+ "Intended use": (
461
+ "Simple variants of exponential smoothing can serve as an efficient baseline method."
462
+ ),
463
+ "Secondary use": (
464
+ "The exponential smoothing method can also act as a low-pass filter removing "
465
+ "high-frequency noise. "
466
+ ),
467
+ "Limitations": (
468
+ "The method can face limitations if the series show strong discontinuities, or if "
469
+ "the high-frequency components are an important part of the predicted signal."
470
+ ),
471
+ "Training data": (
472
+ "Just like the ARIMA method, exponential smoothing uses only autorregresive data "
473
+ " from the target variable."
474
+ ),
475
+ "Citation Info": (
476
+ "@article{holt1957exponential_smoothing, \n"
477
+ "title = {Forecasting seasonals and trends by exponentially weighted moving averages},\n"
478
+ "author = {Charles C. Holt},\n"
479
+ "journal = {International Journal of Forecasting},\n"
480
+ "volume = {20},\n"
481
+ "number = {1},\n"
482
+ "pages = {5-10}\n,"
483
+ "year = {2004(1957)},\n"
484
+ "issn = {0169-2070},\n"
485
+ "doi = {https://doi.org/10.1016/j.ijforecast.2003.09.015},\n"
486
+ "url = {https://www.sciencedirect.com/science/article/pii/S0169207003001134},\n"
487
+ "}"
488
+ ),
489
+ },
490
+ prophet={
491
+ "Abstract": (
492
+ "Prophet is a widely used forecasting method. Prophet is a nonlinear regression model."
493
+ ),
494
+ "Intended use": ("Prophet can serve as a baseline method."),
495
+ "Secondary use": (
496
+ "The Prophet model is also useful for time series decomposition."
497
+ ),
498
+ "Limitations": (
499
+ "The method can face limitations if the series show strong discontinuities, or if "
500
+ "the high-frequency components are an important part of the predicted signal."
501
+ ),
502
+ "Training data": (
503
+ "Just like the ARIMA method and exponential smoothing, Prophet uses only autorregresive data "
504
+ " from the target variable."
505
+ ),
506
+ "Citation Info": (
507
+ "@article{doi:10.1080/00031305.2017.1380080,\n"
508
+ "author = {Sean J. Taylor and Benjamin Letham},\n"
509
+ "title = {Forecasting at Scale},\n"
510
+ "journal = {The American Statistician},\n"
511
+ "volume = {72},\n"
512
+ "number = {1},\n"
513
+ "pages = {37-45},\n"
514
+ "year = {2018},\n"
515
+ "publisher = {Taylor & Francis},\n"
516
+ "doi = {10.1080/00031305.2017.1380080},\n"
517
+ "URL = {https://doi.org/10.1080/00031305.2017.1380080},\n"
518
+ "eprint = {https://doi.org/10.1080/00031305.2017.1380080},\n"
519
+ "}"
520
+ ),
521
+ },
522
+ )
src/nf.py ADDED
@@ -0,0 +1,211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from itertools import chain
2
+ from pathlib import Path
3
+ from typing import List, Optional
4
+
5
+ import neuralforecast as nf
6
+ import numpy as np
7
+ import pandas as pd
8
+ import pytorch_lightning as pl
9
+ from datasetsforecast.utils import download_file
10
+ from hyperopt import hp
11
+ from neuralforecast.auto import NHITS as autoNHITS
12
+ from neuralforecast.data.tsdataset import WindowsDataset
13
+ from neuralforecast.data.tsloader import TimeSeriesLoader
14
+ from neuralforecast.models.mqnhits.mqnhits import MQNHITS
15
+ from neuralforecast.models.nhits.nhits import NHITS
16
+
17
+ # GLOBAL PARAMETERS
18
+ DEFAULT_HORIZON = 30
19
+ HYPEROPT_STEPS = 10
20
+ MAX_STEPS = 1000
21
+ N_TS_VAL = 2 * 30
22
+
23
+ MODELS = {
24
+ "Pretrained N-HiTS M4 Hourly": {
25
+ "card": "nhitsh",
26
+ "max_steps": 0,
27
+ "model": "nhits_m4_hourly",
28
+ },
29
+ "Pretrained N-HiTS M4 Hourly (Tiny)": {
30
+ "card": "nhitsh",
31
+ "max_steps": 0,
32
+ "model": "nhits_m4_hourly_tiny",
33
+ },
34
+ "Pretrained N-HiTS M4 Daily": {
35
+ "card": "nhitsd",
36
+ "max_steps": 0,
37
+ "model": "nhits_m4_daily",
38
+ },
39
+ "Pretrained N-HiTS M4 Monthly": {
40
+ "card": "nhitsm",
41
+ "max_steps": 0,
42
+ "model": "nhits_m4_monthly",
43
+ },
44
+ "Pretrained N-HiTS M4 Yearly": {
45
+ "card": "nhitsy",
46
+ "max_steps": 0,
47
+ "model": "nhits_m4_yearly",
48
+ },
49
+ "Pretrained N-BEATS M4 Hourly": {
50
+ "card": "nbeatsh",
51
+ "max_steps": 0,
52
+ "model": "nbeats_m4_hourly",
53
+ },
54
+ "Pretrained N-BEATS M4 Daily": {
55
+ "card": "nbeatsd",
56
+ "max_steps": 0,
57
+ "model": "nbeats_m4_daily",
58
+ },
59
+ "Pretrained N-BEATS M4 Weekly": {
60
+ "card": "nbeatsw",
61
+ "max_steps": 0,
62
+ "model": "nbeats_m4_weekly",
63
+ },
64
+ "Pretrained N-BEATS M4 Monthly": {
65
+ "card": "nbeatsm",
66
+ "max_steps": 0,
67
+ "model": "nbeats_m4_monthly",
68
+ },
69
+ "Pretrained N-BEATS M4 Yearly": {
70
+ "card": "nbeatsy",
71
+ "max_steps": 0,
72
+ "model": "nbeats_m4_yearly",
73
+ },
74
+ }
75
+
76
+
77
+ def download_models():
78
+ for _, meta in MODELS.items():
79
+ if not Path(f'./models/{meta["model"]}.ckpt').is_file():
80
+ download_file(
81
+ "./models/",
82
+ f'https://nixtla-public.s3.amazonaws.com/transfer/pretrained_models/{meta["model"]}.ckpt',
83
+ )
84
+
85
+
86
+ download_models()
87
+
88
+
89
+ class StandardScaler:
90
+ """This class helps to standardize a dataframe with multiple time series."""
91
+
92
+ def __init__(self):
93
+ self.norm: pd.DataFrame
94
+
95
+ def fit(self, X: pd.DataFrame) -> "StandardScaler":
96
+ self.norm = X.groupby("unique_id").agg({"y": [np.mean, np.std]})
97
+ self.norm = self.norm.droplevel(0, 1).reset_index()
98
+
99
+ def transform(self, X: pd.DataFrame) -> pd.DataFrame:
100
+ transformed = X.merge(self.norm, how="left", on=["unique_id"])
101
+ transformed["y"] = (transformed["y"] - transformed["mean"]) / transformed["std"]
102
+ return transformed[["unique_id", "ds", "y"]]
103
+
104
+ def inverse_transform(self, X: pd.DataFrame, cols: List[str]) -> pd.DataFrame:
105
+ transformed = X.merge(self.norm, how="left", on=["unique_id"])
106
+ for col in cols:
107
+ transformed[col] = (
108
+ transformed[col] * transformed["std"] + transformed["mean"]
109
+ )
110
+ return transformed[["unique_id", "ds"] + cols]
111
+
112
+
113
+ def compute_ds_future(Y_df, fh):
114
+ if Y_df["unique_id"].nunique() == 1:
115
+ ds_ = pd.to_datetime(Y_df["ds"].values)
116
+ try:
117
+ freq = pd.infer_freq(ds_)
118
+ except:
119
+ freq = None
120
+ if freq is not None:
121
+ ds_future = pd.date_range(ds_[-1], periods=fh + 1, freq=freq)[1:]
122
+ else:
123
+ freq = ds_[-1] - ds_[-2]
124
+ ds_future = [ds_[-1] + (i + 1) * freq for i in range(fh)]
125
+ ds_future = list(map(str, ds_future))
126
+ return ds_future
127
+ else:
128
+ ds_future = chain(
129
+ *[compute_ds_future(df, fh) for _, df in Y_df.groupby("unique_id")]
130
+ )
131
+ return list(ds_future)
132
+
133
+
134
+ def forecast_pretrained_model(
135
+ Y_df: pd.DataFrame, model: str, fh: int, max_steps: int = 0
136
+ ):
137
+ if "unique_id" not in Y_df:
138
+ Y_df.insert(0, "unique_id", "ts_1")
139
+
140
+ scaler = StandardScaler()
141
+ scaler.fit(Y_df)
142
+ Y_df = scaler.transform(Y_df)
143
+
144
+ # Model
145
+ file_ = f"./models/{model}.ckpt"
146
+ mqnhits = MQNHITS.load_from_checkpoint(file_)
147
+
148
+ # Fit
149
+ if max_steps > 0:
150
+ train_dataset = WindowsDataset(
151
+ Y_df=Y_df,
152
+ X_df=None,
153
+ S_df=None,
154
+ mask_df=None,
155
+ f_cols=[],
156
+ input_size=mqnhits.n_time_in,
157
+ output_size=mqnhits.n_time_out,
158
+ sample_freq=1,
159
+ complete_windows=True,
160
+ verbose=False,
161
+ )
162
+
163
+ train_loader = TimeSeriesLoader(
164
+ dataset=train_dataset, batch_size=1, n_windows=32, shuffle=True
165
+ )
166
+
167
+ trainer = pl.Trainer(
168
+ max_epochs=None,
169
+ checkpoint_callback=False,
170
+ logger=False,
171
+ max_steps=max_steps,
172
+ gradient_clip_val=1.0,
173
+ progress_bar_refresh_rate=1,
174
+ log_every_n_steps=1,
175
+ )
176
+
177
+ trainer.fit(mqnhits, train_loader)
178
+
179
+ # Forecast
180
+ forecast_df = mqnhits.forecast(Y_df=Y_df)
181
+ forecast_df = scaler.inverse_transform(forecast_df, cols=["y_5", "y_50", "y_95"])
182
+
183
+ # Foreoast
184
+ n_ts = forecast_df["unique_id"].nunique()
185
+ if fh * n_ts > len(forecast_df):
186
+ forecast_df = (
187
+ forecast_df.groupby("unique_id")
188
+ .apply(lambda df: pd.concat([df] * fh).head(fh))
189
+ .reset_index(drop=True)
190
+ )
191
+ else:
192
+ forecast_df = forecast_df.groupby("unique_id").head(fh)
193
+ forecast_df["ds"] = compute_ds_future(Y_df, fh)
194
+
195
+ return forecast_df
196
+
197
+
198
+ if __name__ == "__main__":
199
+ df = pd.read_csv(
200
+ "https://raw.githubusercontent.com/Nixtla/transfer-learning-time-series/main/datasets/ercot_COAST.csv"
201
+ )
202
+ df.columns = ["ds", "y"]
203
+ multi_df = pd.concat([df.assign(unique_id=f"ts{i}") for i in range(2)])
204
+ assert len(compute_ds_future(multi_df, 80)) == 2 * 80
205
+ for _, meta in MODELS.items():
206
+ # test just a time series (without unique_id)
207
+ forecast = forecast_pretrained_model(df, model=meta["model"], fh=80)
208
+ assert forecast.shape == (80, 5)
209
+ # test multiple time series
210
+ multi_forecast = forecast_pretrained_model(multi_df, model=meta["model"], fh=80)
211
+ assert multi_forecast.shape == (80 * 2, 5)
src/st_deploy.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+
4
+ from streamlit.web import cli
5
+
6
+ if __name__ == "__main__":
7
+ sys.argv = [
8
+ "streamlit",
9
+ "run",
10
+ f"{os.path.dirname(os.path.realpath(__file__))}/st_app.py",
11
+ "--server.port=8501",
12
+ "--server.address=0.0.0.0",
13
+ "--server.baseUrlPath=transfer-learning",
14
+ "--logger.level=debug",
15
+ ]
16
+ sys.exit(cli.main())