metafilm 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,37 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+
5
+ # Editor / backups
6
+ *.bak
7
+
8
+ # Large regenerable prediction binaries (rebuild via experiments/bench_*.py)
9
+ *_preds.npz
10
+
11
+ # Run logs
12
+ *.log
13
+ results/**/*.log
14
+
15
+ # LaTeX build artifacts
16
+ *.aux
17
+ *.bbl
18
+ *.blg
19
+ *.out
20
+ *.synctex.gz
21
+ *.fls
22
+ *.fdb_latexmk
23
+ *.toc
24
+
25
+ # Downloaded dataset archives (keep the extracted .tsf, not the zip)
26
+ data/**/*.zip
27
+
28
+ # Large raw M5 data (re-download via datasetsforecast.M5)
29
+ data/m5_dl/
30
+ data/m5/
31
+
32
+ # Packaging and test artefacts
33
+ dist/
34
+ build/
35
+ *.egg-info/
36
+ .pytest_cache/
37
+ .venv/
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (2026-10-29)
4
+
5
+ First public release, accompanying the CENTERIS 2026 paper
6
+ "MetaFiLM: Metadata-Conditioned FiLM Modulation for Cold-Start Demand
7
+ Forecasting".
8
+
9
+ - `metafilm` package: `MetaFiLMConfig`, `MetaFiLMForecaster` (fit, predict,
10
+ save, load) and the `MetaFiLMModel` network, with the ablation switches used
11
+ in the paper (`film_mode`, `film_init`, `use_level`, `use_history`,
12
+ `use_residual`, `loss`).
13
+ - Early stopping restores the weights of the best validation epoch by default
14
+ (`restore_best_weights=True`). The paper's experiments kept the final-epoch
15
+ weights; the experiment scripts set `restore_best_weights=False` so every
16
+ published number reproduces exactly.
17
+ - `MetaFiLMForecaster.load` works with PyTorch 2.6 and later.
18
+ - Works with pandas 2 and pandas 3 (including the pandas 3 string dtype);
19
+ metadata values unseen at fit time still map to the reserved "unknown" code.
20
+ - Test suite (including the parameter counts reported in the paper),
21
+ documentation, and the experiment scripts and results for the public
22
+ benchmarks (M5 weekly and Monash CarParts).
@@ -0,0 +1,55 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use MetaFiLM, please cite the paper below."
3
+ title: "MetaFiLM: metadata-conditioned FiLM modulation for cold-start demand forecasting"
4
+ type: software
5
+ version: 0.1.0
6
+ date-released: 2026-10-29
7
+ license: MIT
8
+ repository-code: "https://github.com/FH-Prevail/MetaFilm"
9
+ url: "https://pypi.org/project/metafilm/"
10
+ keywords:
11
+ - demand forecasting
12
+ - cold start
13
+ - feature-wise linear modulation
14
+ - metadata
15
+ - time series
16
+ authors:
17
+ - family-names: Mirshahi
18
+ given-names: Sina
19
+ email: sina.mirshahi@fh-steyr.at
20
+ affiliation: "University of Applied Sciences Upper Austria"
21
+ - family-names: Falatouri
22
+ given-names: Taha
23
+ affiliation: "University of Applied Sciences Upper Austria"
24
+ - family-names: Brandtner
25
+ given-names: Patrick
26
+ affiliation: "University of Applied Sciences Upper Austria"
27
+ - family-names: Nasseri
28
+ given-names: Mehran
29
+ affiliation: "University of Applied Sciences Upper Austria"
30
+ - family-names: Kominkova Oplatkova
31
+ given-names: Zuzana
32
+ affiliation: "Tomas Bata University in Zlin"
33
+ preferred-citation:
34
+ type: conference-paper
35
+ title: "MetaFiLM: Metadata-Conditioned FiLM Modulation for Cold-Start Demand Forecasting"
36
+ authors:
37
+ - family-names: Mirshahi
38
+ given-names: Sina
39
+ - family-names: Falatouri
40
+ given-names: Taha
41
+ - family-names: Brandtner
42
+ given-names: Patrick
43
+ - family-names: Nasseri
44
+ given-names: Mehran
45
+ - family-names: Kominkova Oplatkova
46
+ given-names: Zuzana
47
+ collection-title: "CENTERIS 2026: International Conference on ENTERprise Information Systems"
48
+ conference:
49
+ name: "CENTERIS 2026"
50
+ city: Seville
51
+ country: ES
52
+ date-start: 2026-11-11
53
+ date-end: 2026-11-13
54
+ year: 2026
55
+ notes: "To appear in Procedia Computer Science."
metafilm-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sina Mirshahi, Taha Falatouri, Patrick Brandtner, Mehran Nasseri and Zuzana Kominkova Oplatkova
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.4
2
+ Name: metafilm
3
+ Version: 0.1.0
4
+ Summary: Metadata-conditioned FiLM modulation for cold-start demand forecasting
5
+ Project-URL: Homepage, https://github.com/FH-Prevail/MetaFilm
6
+ Project-URL: Repository, https://github.com/FH-Prevail/MetaFilm
7
+ Project-URL: Issues, https://github.com/FH-Prevail/MetaFilm/issues
8
+ Project-URL: Changelog, https://github.com/FH-Prevail/MetaFilm/blob/main/CHANGELOG.md
9
+ Author: Taha Falatouri, Patrick Brandtner, Mehran Nasseri, Zuzana Kominkova Oplatkova
10
+ Author-email: Sina Mirshahi <sina.mirshahi@fh-steyr.at>
11
+ Maintainer-email: Sina Mirshahi <sina.mirshahi@fh-steyr.at>
12
+ License-Expression: MIT
13
+ License-File: LICENSE
14
+ Keywords: FiLM,cold start,deep learning,demand forecasting,feature-wise linear modulation,metadata,pytorch,retail,supply chain,time series
15
+ Classifier: Development Status :: 4 - Beta
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Science/Research
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3 :: Only
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
26
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
27
+ Classifier: Typing :: Typed
28
+ Requires-Python: >=3.10
29
+ Requires-Dist: numpy>=1.23
30
+ Requires-Dist: pandas>=1.5
31
+ Requires-Dist: scikit-learn>=1.1
32
+ Requires-Dist: torch>=2.0
33
+ Provides-Extra: dev
34
+ Requires-Dist: build>=1.0; extra == 'dev'
35
+ Requires-Dist: pytest>=7; extra == 'dev'
36
+ Requires-Dist: twine>=6.1; extra == 'dev'
37
+ Provides-Extra: experiments
38
+ Requires-Dist: pyarrow>=10; extra == 'experiments'
39
+ Requires-Dist: xgboost>=1.7; extra == 'experiments'
40
+ Description-Content-Type: text/markdown
41
+
42
+ # MetaFiLM
43
+
44
+ [![PyPI](https://img.shields.io/pypi/v/metafilm.svg)](https://pypi.org/project/metafilm/)
45
+ [![Python](https://img.shields.io/pypi/pyversions/metafilm.svg)](https://pypi.org/project/metafilm/)
46
+ [![Tests](https://github.com/FH-Prevail/MetaFilm/actions/workflows/tests.yml/badge.svg)](https://github.com/FH-Prevail/MetaFilm/actions/workflows/tests.yml)
47
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/FH-Prevail/MetaFilm/blob/main/LICENSE)
48
+
49
+ **Metadata-conditioned FiLM modulation for cold-start demand forecasting.**
50
+
51
+ MetaFiLM forecasts demand for products, stores and item-location pairs that a
52
+ model has never seen, by conditioning a compact neural forecaster on the
53
+ metadata that is known at launch: category, department, store, location. It is
54
+ the reference implementation of the paper *MetaFiLM: Metadata-Conditioned FiLM
55
+ Modulation for Cold-Start Demand Forecasting* (CENTERIS 2026).
56
+
57
+ - **Two metadata pathways.** A level head sets the demand scale; a bounded
58
+ FiLM block modulates how the forecaster reads the calendar and history.
59
+ - **Built for cold start.** Forecasts new series from a short history, or from
60
+ metadata alone. Unseen category values map to a reserved "unknown" code.
61
+ - **Small and fast.** 78,722 parameters in the paper's company configuration;
62
+ trains and serves on a CPU, about 50 microseconds per series in batches on
63
+ one thread.
64
+ - **Familiar API.** `fit`, `predict`, `save` and `load` on a long-format
65
+ pandas frame.
66
+
67
+ ## Installation
68
+
69
+ ```bash
70
+ pip install metafilm
71
+ ```
72
+
73
+ Requires Python 3.10 or newer and PyTorch 2.0 or newer. If you need a specific
74
+ PyTorch build (CPU-only or a particular CUDA version), install it first as
75
+ described on [pytorch.org](https://pytorch.org/get-started/locally/).
76
+
77
+ ## Quickstart
78
+
79
+ The input is a long-format frame with one row per series and period: an id, a
80
+ date, the target and the metadata columns (constant within a series).
81
+
82
+ ```python
83
+ import pandas as pd
84
+ from metafilm import MetaFiLMConfig, MetaFiLMForecaster
85
+
86
+ config = MetaFiLMConfig(
87
+ n_steps_lag=8, # history window
88
+ forecast_horizon=4, # steps forecast at once
89
+ context_features=["category", "store"],
90
+ item_id_col="item", date_col="week", target_col="sales",
91
+ freq="W-SUN", # weekly; use "MS" for monthly data
92
+ )
93
+
94
+ model = MetaFiLMForecaster(config).fit(train_df)
95
+
96
+ forecasts = model.predict(new_items_df) # {item: array of 4 forecasts}
97
+ model.save("metafilm.pt")
98
+ model = MetaFiLMForecaster.load("metafilm.pt")
99
+ ```
100
+
101
+ A series with at least `n_steps_lag` rows is forecast from its latest history;
102
+ a shorter one from its metadata and the calendar. For items with **no sales
103
+ history at all**, train with `use_history=False` so the model learns to forecast
104
+ from metadata alone. [`examples/quickstart.py`](https://github.com/FH-Prevail/MetaFilm/blob/main/examples/quickstart.py)
105
+ runs both cases end to end on synthetic data:
106
+
107
+ ```text
108
+ New items, 8 weeks of history (MAE 1.12)
109
+ item50 forecast [30.9 28.7 26.3 25.4] actual [34.4 27.5 27.9 25.4]
110
+ item52 forecast [9.5 7.3 4.9 4. ] actual [8.8 7.1 5.5 6.8]
111
+ New items, metadata only (MAE 1.42)
112
+ item50 forecast [32.5 31.1 27.1 26.7] actual [34.4 27.5 27.9 25.4]
113
+ item52 forecast [11. 9.6 5.6 5.2] actual [8.8 7.1 5.5 6.8]
114
+ ```
115
+
116
+ ## How it works
117
+
118
+ ![MetaFiLM architecture](https://raw.githubusercontent.com/FH-Prevail/MetaFilm/main/docs/architecture.png)
119
+
120
+ For a series with metadata `c`, recent history `y` and future calendar
121
+ features `phi_k` (k = 1 ... H):
122
+
123
+ ```text
124
+ level l(c) = MLP(c) base demand level
125
+ history h_enc = LSTM_2(y, calendar)[final state] zero if no history
126
+ decoder d_k = LSTM_1(phi_k), zero initial state
127
+ fusion g_k = d_k + 0.3 * h_enc
128
+ FiLM z(c) = ReLU(W_1 c)
129
+ gamma = 1 + 0.1 * tanh(W_g z(c)), beta = 0.1 * tanh(W_b z(c))
130
+ h_k = gamma * g_k + beta + 0.5 * g_k
131
+ output y_hat_k = w . h_k + b + l(c)
132
+ ```
133
+
134
+ FiLM (Feature-wise Linear Modulation) comes from computer vision, where a
135
+ question about an image scales and shifts the image network's features
136
+ ([Perez et al., AAAI 2018](https://doi.org/10.1609/aaai.v32i1.11671)). MetaFiLM
137
+ applies the same mechanism with product metadata in place of the question. The
138
+ modulation is bounded to stay close to the identity, so conditioning starts as
139
+ almost no change and grows only where training supports it.
140
+
141
+ ## Configuration
142
+
143
+ `MetaFiLMConfig` fields, with defaults:
144
+
145
+ | Field | Default | Meaning |
146
+ |---|---|---|
147
+ | `n_steps_lag` | 12 | history window fed to the encoder |
148
+ | `forecast_horizon` | 12 | steps forecast at once |
149
+ | `context_features` | `[]` | metadata columns (categorical or numeric) |
150
+ | `temporal_features` | `[]` | optional extra per-step inputs for the encoder |
151
+ | `item_id_col`, `date_col`, `target_col` | `compoundkey`, `orderweek_dt`, `quantity` | column names |
152
+ | `freq` | `"W-SUN"` | pandas frequency of the series (`"MS"` for monthly) |
153
+ | `hidden_dim`, `num_lstm_layers`, `dropout` | 128, 2, 0.3 | network size |
154
+ | `loss` | `"mse"` | training loss: `"mse"`, `"l1"` (absolute error) or `"huber"` |
155
+ | `film_mode` | `"bounded"` | `"bounded"`, `"unbounded"`, `"concat"` or `"off"` |
156
+ | `use_level`, `use_history`, `use_residual` | `True` | switch individual pathways off |
157
+ | `batch_size`, `learning_rate`, `weight_decay` | 32, 0.001, 0.01 | optimiser settings |
158
+ | `num_epochs`, `patience` | 100, 10 | training length and early stopping |
159
+ | `restore_best_weights` | `True` | keep the best-validation epoch after early stopping |
160
+ | `random_seed`, `device` | 42, CUDA if available | reproducibility and placement |
161
+
162
+ **Match the loss to how you are measured.** If forecasts are judged by mean
163
+ absolute error, train with `loss="l1"` or `loss="huber"`. In the paper this
164
+ lowered cold-start MAE by up to about 5% and moved accuracy more reliably than
165
+ any architectural change; `"huber"` is the more balanced choice for
166
+ intermittent demand, because `"l1"` tends to under-forecast.
167
+
168
+ ## Results from the paper
169
+
170
+ Cold-start MAE on series held out from training, mean ± standard deviation over
171
+ five seeds (lower is better):
172
+
173
+ | Method | M5 weekly (Walmart) | Company partner | Monash CarParts |
174
+ |---|---|---|---|
175
+ | Zero forecast | 61.33 ± 6.13 | 124.75 ± 9.11 | 0.364 ± 0.019 |
176
+ | Persistence | 20.69 ± 2.21 | 95.95 ± 6.68 | 0.512 ± 0.019 |
177
+ | Ridge | 19.19 ± 1.85 | 87.18 ± 5.07 | 0.439 ± 0.025 |
178
+ | XGBoost (global) | 20.69 ± 2.34 | 80.97 ± 5.97 | 0.387 ± 0.020 |
179
+ | **MetaFiLM** | 19.64 ± 2.20 | **79.71 ± 4.37** | **0.377 ± 0.021** |
180
+
181
+ MetaFiLM has the lowest error of all learned models on the company and CarParts
182
+ panels, and is on par with the strongest baseline on M5 and the company panel
183
+ (paired tests over five seeds: p = .172 against Ridge, p = .328 against
184
+ XGBoost). On CarParts, where 81% of the test values are zero, the constant zero
185
+ forecast is hard to beat under squared-error training; trained with the Huber
186
+ loss, MetaFiLM reaches 0.359.
187
+
188
+ The benchmarks: M5 weekly (1,000 Walmart item-store series, 150 held out,
189
+ horizon 4), an industrial company-partner panel (3,000 item-location pairs,
190
+ monthly, horizon 6; proprietary and not distributed) and Monash CarParts
191
+ (2,674 intermittent monthly series, horizon 6, no categorical metadata, used
192
+ as a control).
193
+
194
+ ## Reproducing the paper
195
+
196
+ The experiment scripts, the CarParts data and the results for the public
197
+ benchmarks are in this repository. See
198
+ [docs/reproducing.md](https://github.com/FH-Prevail/MetaFilm/blob/main/docs/reproducing.md).
199
+
200
+ ## Citation
201
+
202
+ If you use MetaFiLM, please cite:
203
+
204
+ ```bibtex
205
+ @inproceedings{mirshahi2026metafilm,
206
+ title = {{MetaFiLM}: Metadata-Conditioned {FiLM} Modulation for Cold-Start Demand Forecasting},
207
+ author = {Mirshahi, Sina and Falatouri, Taha and Brandtner, Patrick and Nasseri, Mehran and Kominkova Oplatkova, Zuzana},
208
+ booktitle = {CENTERIS 2026: International Conference on ENTERprise Information Systems},
209
+ series = {Procedia Computer Science},
210
+ year = {2026},
211
+ note = {To appear}
212
+ }
213
+ ```
214
+
215
+ GitHub also offers this citation through "Cite this repository"
216
+ ([CITATION.cff](https://github.com/FH-Prevail/MetaFilm/blob/main/CITATION.cff)).
217
+
218
+ ## Authors and acknowledgements
219
+
220
+ - Sina Mirshahi: University of Applied Sciences Upper Austria (Steyr), Josef
221
+ Ressel Centre for Predictive Value Network Intelligence, and Tomas Bata
222
+ University in Zlin
223
+ - Taha Falatouri, Patrick Brandtner and Mehran Nasseri: University of Applied
224
+ Sciences Upper Austria (Steyr) and Josef Ressel Centre for Predictive Value
225
+ Network Intelligence
226
+ - Zuzana Kominkova Oplatkova: Tomas Bata University in Zlin
227
+
228
+ This research was funded by the Christian Doppler Research Association as part
229
+ of the Josef Ressel Centre for Predictive Value Network Intelligence (JRC
230
+ PREVAIL), and partially supported by the Internal Grant Agency of Tomas Bata
231
+ University in Zlin under project number IGA/CebiaTech/2026/004.
232
+
233
+ ## License
234
+
235
+ MIT. See [LICENSE](https://github.com/FH-Prevail/MetaFilm/blob/main/LICENSE).
@@ -0,0 +1,194 @@
1
+ # MetaFiLM
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/metafilm.svg)](https://pypi.org/project/metafilm/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/metafilm.svg)](https://pypi.org/project/metafilm/)
5
+ [![Tests](https://github.com/FH-Prevail/MetaFilm/actions/workflows/tests.yml/badge.svg)](https://github.com/FH-Prevail/MetaFilm/actions/workflows/tests.yml)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/FH-Prevail/MetaFilm/blob/main/LICENSE)
7
+
8
+ **Metadata-conditioned FiLM modulation for cold-start demand forecasting.**
9
+
10
+ MetaFiLM forecasts demand for products, stores and item-location pairs that a
11
+ model has never seen, by conditioning a compact neural forecaster on the
12
+ metadata that is known at launch: category, department, store, location. It is
13
+ the reference implementation of the paper *MetaFiLM: Metadata-Conditioned FiLM
14
+ Modulation for Cold-Start Demand Forecasting* (CENTERIS 2026).
15
+
16
+ - **Two metadata pathways.** A level head sets the demand scale; a bounded
17
+ FiLM block modulates how the forecaster reads the calendar and history.
18
+ - **Built for cold start.** Forecasts new series from a short history, or from
19
+ metadata alone. Unseen category values map to a reserved "unknown" code.
20
+ - **Small and fast.** 78,722 parameters in the paper's company configuration;
21
+ trains and serves on a CPU, about 50 microseconds per series in batches on
22
+ one thread.
23
+ - **Familiar API.** `fit`, `predict`, `save` and `load` on a long-format
24
+ pandas frame.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ pip install metafilm
30
+ ```
31
+
32
+ Requires Python 3.10 or newer and PyTorch 2.0 or newer. If you need a specific
33
+ PyTorch build (CPU-only or a particular CUDA version), install it first as
34
+ described on [pytorch.org](https://pytorch.org/get-started/locally/).
35
+
36
+ ## Quickstart
37
+
38
+ The input is a long-format frame with one row per series and period: an id, a
39
+ date, the target and the metadata columns (constant within a series).
40
+
41
+ ```python
42
+ import pandas as pd
43
+ from metafilm import MetaFiLMConfig, MetaFiLMForecaster
44
+
45
+ config = MetaFiLMConfig(
46
+ n_steps_lag=8, # history window
47
+ forecast_horizon=4, # steps forecast at once
48
+ context_features=["category", "store"],
49
+ item_id_col="item", date_col="week", target_col="sales",
50
+ freq="W-SUN", # weekly; use "MS" for monthly data
51
+ )
52
+
53
+ model = MetaFiLMForecaster(config).fit(train_df)
54
+
55
+ forecasts = model.predict(new_items_df) # {item: array of 4 forecasts}
56
+ model.save("metafilm.pt")
57
+ model = MetaFiLMForecaster.load("metafilm.pt")
58
+ ```
59
+
60
+ A series with at least `n_steps_lag` rows is forecast from its latest history;
61
+ a shorter one from its metadata and the calendar. For items with **no sales
62
+ history at all**, train with `use_history=False` so the model learns to forecast
63
+ from metadata alone. [`examples/quickstart.py`](https://github.com/FH-Prevail/MetaFilm/blob/main/examples/quickstart.py)
64
+ runs both cases end to end on synthetic data:
65
+
66
+ ```text
67
+ New items, 8 weeks of history (MAE 1.12)
68
+ item50 forecast [30.9 28.7 26.3 25.4] actual [34.4 27.5 27.9 25.4]
69
+ item52 forecast [9.5 7.3 4.9 4. ] actual [8.8 7.1 5.5 6.8]
70
+ New items, metadata only (MAE 1.42)
71
+ item50 forecast [32.5 31.1 27.1 26.7] actual [34.4 27.5 27.9 25.4]
72
+ item52 forecast [11. 9.6 5.6 5.2] actual [8.8 7.1 5.5 6.8]
73
+ ```
74
+
75
+ ## How it works
76
+
77
+ ![MetaFiLM architecture](https://raw.githubusercontent.com/FH-Prevail/MetaFilm/main/docs/architecture.png)
78
+
79
+ For a series with metadata `c`, recent history `y` and future calendar
80
+ features `phi_k` (k = 1 ... H):
81
+
82
+ ```text
83
+ level l(c) = MLP(c) base demand level
84
+ history h_enc = LSTM_2(y, calendar)[final state] zero if no history
85
+ decoder d_k = LSTM_1(phi_k), zero initial state
86
+ fusion g_k = d_k + 0.3 * h_enc
87
+ FiLM z(c) = ReLU(W_1 c)
88
+ gamma = 1 + 0.1 * tanh(W_g z(c)), beta = 0.1 * tanh(W_b z(c))
89
+ h_k = gamma * g_k + beta + 0.5 * g_k
90
+ output y_hat_k = w . h_k + b + l(c)
91
+ ```
92
+
93
+ FiLM (Feature-wise Linear Modulation) comes from computer vision, where a
94
+ question about an image scales and shifts the image network's features
95
+ ([Perez et al., AAAI 2018](https://doi.org/10.1609/aaai.v32i1.11671)). MetaFiLM
96
+ applies the same mechanism with product metadata in place of the question. The
97
+ modulation is bounded to stay close to the identity, so conditioning starts as
98
+ almost no change and grows only where training supports it.
99
+
100
+ ## Configuration
101
+
102
+ `MetaFiLMConfig` fields, with defaults:
103
+
104
+ | Field | Default | Meaning |
105
+ |---|---|---|
106
+ | `n_steps_lag` | 12 | history window fed to the encoder |
107
+ | `forecast_horizon` | 12 | steps forecast at once |
108
+ | `context_features` | `[]` | metadata columns (categorical or numeric) |
109
+ | `temporal_features` | `[]` | optional extra per-step inputs for the encoder |
110
+ | `item_id_col`, `date_col`, `target_col` | `compoundkey`, `orderweek_dt`, `quantity` | column names |
111
+ | `freq` | `"W-SUN"` | pandas frequency of the series (`"MS"` for monthly) |
112
+ | `hidden_dim`, `num_lstm_layers`, `dropout` | 128, 2, 0.3 | network size |
113
+ | `loss` | `"mse"` | training loss: `"mse"`, `"l1"` (absolute error) or `"huber"` |
114
+ | `film_mode` | `"bounded"` | `"bounded"`, `"unbounded"`, `"concat"` or `"off"` |
115
+ | `use_level`, `use_history`, `use_residual` | `True` | switch individual pathways off |
116
+ | `batch_size`, `learning_rate`, `weight_decay` | 32, 0.001, 0.01 | optimiser settings |
117
+ | `num_epochs`, `patience` | 100, 10 | training length and early stopping |
118
+ | `restore_best_weights` | `True` | keep the best-validation epoch after early stopping |
119
+ | `random_seed`, `device` | 42, CUDA if available | reproducibility and placement |
120
+
121
+ **Match the loss to how you are measured.** If forecasts are judged by mean
122
+ absolute error, train with `loss="l1"` or `loss="huber"`. In the paper this
123
+ lowered cold-start MAE by up to about 5% and moved accuracy more reliably than
124
+ any architectural change; `"huber"` is the more balanced choice for
125
+ intermittent demand, because `"l1"` tends to under-forecast.
126
+
127
+ ## Results from the paper
128
+
129
+ Cold-start MAE on series held out from training, mean ± standard deviation over
130
+ five seeds (lower is better):
131
+
132
+ | Method | M5 weekly (Walmart) | Company partner | Monash CarParts |
133
+ |---|---|---|---|
134
+ | Zero forecast | 61.33 ± 6.13 | 124.75 ± 9.11 | 0.364 ± 0.019 |
135
+ | Persistence | 20.69 ± 2.21 | 95.95 ± 6.68 | 0.512 ± 0.019 |
136
+ | Ridge | 19.19 ± 1.85 | 87.18 ± 5.07 | 0.439 ± 0.025 |
137
+ | XGBoost (global) | 20.69 ± 2.34 | 80.97 ± 5.97 | 0.387 ± 0.020 |
138
+ | **MetaFiLM** | 19.64 ± 2.20 | **79.71 ± 4.37** | **0.377 ± 0.021** |
139
+
140
+ MetaFiLM has the lowest error of all learned models on the company and CarParts
141
+ panels, and is on par with the strongest baseline on M5 and the company panel
142
+ (paired tests over five seeds: p = .172 against Ridge, p = .328 against
143
+ XGBoost). On CarParts, where 81% of the test values are zero, the constant zero
144
+ forecast is hard to beat under squared-error training; trained with the Huber
145
+ loss, MetaFiLM reaches 0.359.
146
+
147
+ The benchmarks: M5 weekly (1,000 Walmart item-store series, 150 held out,
148
+ horizon 4), an industrial company-partner panel (3,000 item-location pairs,
149
+ monthly, horizon 6; proprietary and not distributed) and Monash CarParts
150
+ (2,674 intermittent monthly series, horizon 6, no categorical metadata, used
151
+ as a control).
152
+
153
+ ## Reproducing the paper
154
+
155
+ The experiment scripts, the CarParts data and the results for the public
156
+ benchmarks are in this repository. See
157
+ [docs/reproducing.md](https://github.com/FH-Prevail/MetaFilm/blob/main/docs/reproducing.md).
158
+
159
+ ## Citation
160
+
161
+ If you use MetaFiLM, please cite:
162
+
163
+ ```bibtex
164
+ @inproceedings{mirshahi2026metafilm,
165
+ title = {{MetaFiLM}: Metadata-Conditioned {FiLM} Modulation for Cold-Start Demand Forecasting},
166
+ author = {Mirshahi, Sina and Falatouri, Taha and Brandtner, Patrick and Nasseri, Mehran and Kominkova Oplatkova, Zuzana},
167
+ booktitle = {CENTERIS 2026: International Conference on ENTERprise Information Systems},
168
+ series = {Procedia Computer Science},
169
+ year = {2026},
170
+ note = {To appear}
171
+ }
172
+ ```
173
+
174
+ GitHub also offers this citation through "Cite this repository"
175
+ ([CITATION.cff](https://github.com/FH-Prevail/MetaFilm/blob/main/CITATION.cff)).
176
+
177
+ ## Authors and acknowledgements
178
+
179
+ - Sina Mirshahi: University of Applied Sciences Upper Austria (Steyr), Josef
180
+ Ressel Centre for Predictive Value Network Intelligence, and Tomas Bata
181
+ University in Zlin
182
+ - Taha Falatouri, Patrick Brandtner and Mehran Nasseri: University of Applied
183
+ Sciences Upper Austria (Steyr) and Josef Ressel Centre for Predictive Value
184
+ Network Intelligence
185
+ - Zuzana Kominkova Oplatkova: Tomas Bata University in Zlin
186
+
187
+ This research was funded by the Christian Doppler Research Association as part
188
+ of the Josef Ressel Centre for Predictive Value Network Intelligence (JRC
189
+ PREVAIL), and partially supported by the Internal Grant Agency of Tomas Bata
190
+ University in Zlin under project number IGA/CebiaTech/2026/004.
191
+
192
+ ## License
193
+
194
+ MIT. See [LICENSE](https://github.com/FH-Prevail/MetaFilm/blob/main/LICENSE).
@@ -0,0 +1,26 @@
1
+ # Data
2
+
3
+ ## Monash CarParts (included)
4
+
5
+ `carparts/car_parts_dataset_without_missing_values.tsf`: 2,674 intermittent
6
+ monthly series of car-part sales (January 1998 to March 2002), from the Monash
7
+ Time Series Forecasting Archive (Zenodo record 4656021), distributed there under
8
+ the CC BY 4.0 licence. Missing values were replaced by zeros by the archive.
9
+
10
+ - R. Godahewa, C. Bergmeir, G. I. Webb, R. J. Hyndman and P. Montero-Manso
11
+ (2021). Monash Time Series Forecasting Archive. NeurIPS Datasets and
12
+ Benchmarks Track.
13
+ - R. J. Hyndman (2015). expsmooth: Data Sets from "Forecasting with
14
+ Exponential Smoothing". R package version 2.3.
15
+
16
+ CarParts has no categorical metadata; in the paper it serves as a control
17
+ panel on which metadata conditioning should have no effect.
18
+
19
+ ## M5 (download)
20
+
21
+ The Walmart M5 sales data is not redistributed here. See
22
+ [docs/reproducing.md](../docs/reproducing.md) for the download command.
23
+
24
+ ## Company partner (not public)
25
+
26
+ The industrial panel used in the paper is proprietary and is not distributed.
@@ -0,0 +1,58 @@
1
+ """Train MetaFiLM on a synthetic panel, then forecast items it has never seen.
2
+
3
+ Run: python examples/quickstart.py
4
+ """
5
+ import numpy as np
6
+ import pandas as pd
7
+
8
+ from metafilm import MetaFiLMConfig, MetaFiLMForecaster
9
+
10
+ # Long-format panel: one row per item and week, plus metadata columns.
11
+ # The demand level depends on the metadata, which is what MetaFiLM learns.
12
+ rng = np.random.default_rng(0)
13
+ weeks = pd.date_range("2024-01-07", periods=40, freq="W-SUN")
14
+ rows = []
15
+ for i in range(60):
16
+ category, store = f"cat{i % 4}", f"store{i % 3}"
17
+ level = 5 + 10 * (i % 4) + 3 * (i % 3)
18
+ for t, week in enumerate(weeks):
19
+ sales = level * (1 + 0.2 * np.sin(2 * np.pi * t / 13)) + rng.normal(0, 1)
20
+ rows.append({"item": f"item{i}", "week": week, "category": category,
21
+ "store": store, "sales": max(0.0, sales)})
22
+ panel = pd.DataFrame(rows)
23
+
24
+ # Train on items 0-49. Items 50-59 are new: never seen during training.
25
+ train = panel[panel["item"].isin([f"item{i}" for i in range(50)])]
26
+ new = panel[~panel["item"].isin(train["item"])]
27
+ start = weeks[32] # forecast weeks 33-36
28
+ actual = new[new["week"].between(start, weeks[35])].pivot(index="item", columns="week", values="sales")
29
+
30
+
31
+ def settings(**extra):
32
+ return MetaFiLMConfig(
33
+ n_steps_lag=8, forecast_horizon=4,
34
+ context_features=["category", "store"],
35
+ item_id_col="item", date_col="week", target_col="sales", freq="W-SUN",
36
+ hidden_dim=32, num_epochs=60, patience=10, device="cpu", **extra,
37
+ )
38
+
39
+
40
+ def report(title, forecasts):
41
+ mae = np.mean([np.abs(forecasts[item] - actual.loc[item].to_numpy()).mean() for item in actual.index])
42
+ print(f"\n{title} (MAE {mae:.2f})")
43
+ for item in actual.index:
44
+ print(f" {item:7s} forecast {np.array2string(forecasts[item], precision=1):26s}"
45
+ f" actual {np.array2string(actual.loc[item].to_numpy(), precision=1)}")
46
+
47
+
48
+ # 1. New items with a short sales history (the paper's cold-start setting):
49
+ # the last 8 weeks are available, the item itself was never trained on.
50
+ model = MetaFiLMForecaster(settings()).fit(train)
51
+ history = new[new["week"] < start]
52
+ report("New items, 8 weeks of history", model.predict(history))
53
+
54
+ # 2. Items with no sales history at all: train without the history pathway,
55
+ # so the forecast comes from metadata and the calendar alone.
56
+ metadata_model = MetaFiLMForecaster(settings(use_history=False)).fit(train)
57
+ metadata_only = new.groupby("item").head(1) # one row each: just the metadata
58
+ report("New items, metadata only", metadata_model.predict(metadata_only, forecast_start_date=start))