dfm-python 0.4.5__tar.gz → 0.4.7__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.
- dfm_python-0.4.7/.git +1 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/PKG-INFO +9 -110
- {dfm_python-0.4.5 → dfm_python-0.4.7}/README.md +8 -109
- dfm_python-0.4.7/config/experiment/test_finance.yaml +0 -0
- dfm_python-0.4.7/config/experiment/test_macro.yaml +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/model/ddfm.yaml +1 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/model/dfm.yaml +1 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KO3YEARC.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBFDSAAF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBFINAAF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBFXSAAF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBSESI_R.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBSIBCEQ.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBSIBCOQ.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBSIBNER.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBSIBNMR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBSIEMAR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBSIHAPR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBSIIMER.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBSIIMPR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBSIXMER.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOBUSINVR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCALL_.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCNFBUSR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCNFCONR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCNGOV_D.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCNPER_D.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCOBUSIR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCONPMTH.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCONPRCF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCONSTRP.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCPCOREF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCPEXFEF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCREU__A.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCSECDMR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCSECEMR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCSEMEMR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCSEOHDR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCSEOHSR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCSHHEMR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCSHHLMR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCSMTTOA.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCSPHIMR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCSPSPMR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOCYLEADR.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KODBLNEQA.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KODBLNHSA.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEMPCONF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEMPMANF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEMPTOTO.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEMPWREP.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEQUIMAE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEQUIPTE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEQUITTE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEXCHINA.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEXNGS_D.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEXPGDSA.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOEXPPRCF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOGCFCNSD.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOGCFFNVD.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOGDP___D.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOGFCF__D.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOHWRWEMP.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOIMNGS_D.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOIMPCONA.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOIMPGDDA.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOIMPGDSA.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOIMPPRCF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOIPALL_G.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOIPMIMAG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOLRLTCO.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOLRLTHH.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOMPCAPGG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOMPCONDG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOMPCONGG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOMPCONNG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOMPRI30G.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOMSCAPGG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOMSCONGG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KONETTRDF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KONEWCONA.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOPICAPGG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOPICONGG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOPIMANUG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOPOPACTE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOPPSRM_F.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOPROPRCF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOPSMANUG.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KORCNST.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KORELEC.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KORFBEV.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KORMACH.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KORMCMP.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOROCOINF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KORWHLS.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOSHRPRCF.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOSIAHOTE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOSIAI__E.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOSIARRLE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOSIAWRTE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOSSBFMBE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOUN_TOTQ.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOUS____.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOVALCONA.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOWRCCNSE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOWRCDURE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOWRCNODE.yaml +0 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/config/series/KOWRCSEME.yaml +0 -1
- dfm_python-0.4.7/data/finance.csv +9022 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/pyproject.toml +1 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/__init__.py +4 -18
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/config/adapter.py +1 -2
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/config/schema.py +8 -13
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/data/dataloader.py +3 -3
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/data/utils.py +1 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/encoder/vae.py +15 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/lightning/__init__.py +2 -5
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/lightning/data_module.py +67 -24
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/lightning/scaling.py +32 -26
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/logger/inference_logger.py +1 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/logger/logger.py +30 -16
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/logger/train_logger.py +1 -1
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/models/base.py +0 -2
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/models/ddfm.py +442 -301
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/models/dfm.py +103 -6
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/ssm/em.py +509 -50
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/ssm/kalman.py +301 -27
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/ssm/utils.py +18 -15
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/trainer/__init__.py +10 -3
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/trainer/ddfm.py +5 -4
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/trainer/dfm.py +3 -3
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/utils/__init__.py +28 -14
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/utils/data.py +63 -3
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/utils/time.py +3 -3
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/test/test_config.py +7 -7
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/test/test_nowcast.py +3 -2
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/test/test_sktime_integration.py +20 -5
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/test/test_trainer.py +5 -2
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/test/test_utils.py +2 -2
- dfm_python-0.4.5/config/README.md +0 -174
- dfm_python-0.4.5/config/experiment/default.yaml +0 -82
- dfm_python-0.4.5/config/experiment/myexp_20251204233620.yaml +0 -108
- dfm_python-0.4.5/config/experiment/test_experiment_20251204170512.yaml +0 -107
- dfm_python-0.4.5/config/model/arma.yaml +0 -5
- dfm_python-0.4.5/config/model/tft.yaml +0 -7
- dfm_python-0.4.5/config/model/xgboost.yaml +0 -23
- dfm_python-0.4.5/config/preprocess/default.yaml +0 -35
- dfm_python-0.4.5/config/preprocess/test_preprocess_20251204170512.yaml +0 -41
- dfm_python-0.4.5/data/metadata.csv +0 -102
- dfm_python-0.4.5/src/dfm_python/nowcast/__init__.py +0 -37
- dfm_python-0.4.5/src/dfm_python/nowcast/dataview.py +0 -143
- dfm_python-0.4.5/src/dfm_python/nowcast/helpers.py +0 -356
- dfm_python-0.4.5/src/dfm_python/nowcast/nowcast.py +0 -1263
- dfm_python-0.4.5/src/dfm_python/nowcast/splitters.py +0 -431
- dfm_python-0.4.5/src/dfm_python/nowcast/transformers.py +0 -330
- dfm_python-0.4.5/src/dfm_python/nowcast/utils.py +0 -285
- dfm_python-0.4.5/src/test/test_pipeline_ddfm.py +0 -834
- dfm_python-0.4.5/src/test/test_pipeline_dfm.py +0 -723
- {dfm_python-0.4.5 → dfm_python-0.4.7}/.gitignore +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/.python-version +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/LICENSE +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/MANIFEST.in +0 -0
- /dfm_python-0.4.5/data/sample_data.csv → /dfm_python-0.4.7/data/macro.csv +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/config/__init__.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/config/results.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/config/utils.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/data/__init__.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/data/dataset.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/encoder/__init__.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/encoder/base.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/encoder/pca.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/logger/__init__.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/models/__init__.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/ssm/__init__.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/utils/diagnostics.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/utils/helpers.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/dfm_python/utils/statespace.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/test/test_helpers.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/test/test_logger.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/test/test_models.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/src/test/test_ssm.py +0 -0
- {dfm_python-0.4.5 → dfm_python-0.4.7}/uv.lock +0 -0
dfm_python-0.4.7/.git
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
gitdir: ../.git/modules/dfm-python
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dfm-python
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.7
|
|
4
4
|
Summary: Dynamic Factor Model (DFM) estimation and nowcasting in Python
|
|
5
5
|
Project-URL: Homepage, https://github.com/yourusername/dfm-python
|
|
6
6
|
Project-URL: Documentation, https://github.com/yourusername/dfm-python#readme
|
|
@@ -59,7 +59,7 @@ Description-Content-Type: text/markdown
|
|
|
59
59
|
[](https://pypi.org/project/dfm-python/)
|
|
60
60
|
[](https://www.python.org/downloads/)
|
|
61
61
|
|
|
62
|
-
A comprehensive Python implementation of **Dynamic Factor Models (DFM)** for
|
|
62
|
+
A comprehensive Python implementation of **Dynamic Factor Models (DFM)** for forecasting high-dimensional time series. Built for economists, researchers, and data scientists working with mixed-frequency macroeconomic data.
|
|
63
63
|
|
|
64
64
|
## What is a Dynamic Factor Model?
|
|
65
65
|
|
|
@@ -68,7 +68,6 @@ A Dynamic Factor Model is a powerful statistical framework that:
|
|
|
68
68
|
- **Extracts common factors** from many observed time series (e.g., GDP, consumption, investment, employment)
|
|
69
69
|
- **Handles mixed frequencies** seamlessly (monthly, quarterly, annual data together)
|
|
70
70
|
- **Deals with missing data** robustly (late-arriving indicators, publication delays)
|
|
71
|
-
- **Provides nowcasts** (current-quarter GDP estimates before official release)
|
|
72
71
|
- **Forecasts** future values of both factors and observed series
|
|
73
72
|
|
|
74
73
|
**Key Innovation**: All latent factors evolve at a common "clock" frequency (configurable: `'d'`, `'w'`, `'m'`, `'q'`, `'sa'`, `'a'`), while observed series can be at different frequencies. This is achieved through deterministic tent kernel aggregation, allowing quarterly GDP to be modeled using monthly latent factors, or any slower-frequency series to be modeled using higher-frequency latent factors.
|
|
@@ -81,8 +80,7 @@ A Dynamic Factor Model is a powerful statistical framework that:
|
|
|
81
80
|
- ✅ **Block structure**: Flexible factor organization (global common factor + sector-specific factors)
|
|
82
81
|
- ✅ **Idiosyncratic components**: Per-series state augmentation for better fit (AR(1) for clock-frequency, tent-length chains for slower frequencies)
|
|
83
82
|
- ✅ **Preprocessed data**: Package expects preprocessed data from users - users handle all preprocessing (imputation, scaling, feature engineering) using sktime or other tools
|
|
84
|
-
- ✅ **
|
|
85
|
-
- ✅ **Nowcasting & Forecasting**: Generate predictions for any horizon
|
|
83
|
+
- ✅ **Forecasting**: Generate predictions for any horizon
|
|
86
84
|
- ✅ **Deep Dynamic Factor Models (DDFM)**: Nonlinear encoder with PyTorch for capturing complex factor structures (optional, requires `dfm-python[deep]`)
|
|
87
85
|
|
|
88
86
|
### Technical Features
|
|
@@ -243,7 +241,7 @@ print(f"Log-likelihood: {result.loglik:.2f}")
|
|
|
243
241
|
|
|
244
242
|
### Example 4: Fast Reuse with `load_pickle`
|
|
245
243
|
|
|
246
|
-
Once a model has been trained you can reload it instantly for forecasting
|
|
244
|
+
Once a model has been trained you can reload it instantly for forecasting without
|
|
247
245
|
re-running EM:
|
|
248
246
|
|
|
249
247
|
```python
|
|
@@ -272,15 +270,12 @@ model.load_pickle(
|
|
|
272
270
|
|
|
273
271
|
# Fast inference (milliseconds instead of minutes)
|
|
274
272
|
X_forecast, Z_forecast = model.predict(horizon=12)
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
view_date='2024-03-15'
|
|
278
|
-
)
|
|
273
|
+
# Note: Nowcasting functionality has been moved to src.nowcast
|
|
274
|
+
# Use src.nowcast.Nowcast for nowcasting operations
|
|
279
275
|
```
|
|
280
276
|
|
|
281
277
|
`DFM.load_pickle()` accepts either the auto-save payload (`{'result': ..., 'config': ...}`) or a
|
|
282
|
-
raw `DFMResult`. Provide `load_data_path` or `data`/`time_index` when you need
|
|
283
|
-
decomposition abilities (which require the data view).
|
|
278
|
+
raw `DFMResult`. Provide `load_data_path` or `data`/`time_index` when you need to access model results.
|
|
284
279
|
|
|
285
280
|
## Configuration Guide
|
|
286
281
|
|
|
@@ -510,105 +505,9 @@ idio_component = result.X_sm[:, series_idx] - series_factor_component
|
|
|
510
505
|
|
|
511
506
|
## Advanced Features
|
|
512
507
|
|
|
513
|
-
### Nowcasting
|
|
514
|
-
|
|
515
|
-
The package provides a comprehensive nowcasting API for pseudo real-time evaluation and downstream model integration:
|
|
516
|
-
|
|
517
|
-
#### Basic Nowcasting
|
|
518
|
-
|
|
519
|
-
```python
|
|
520
|
-
import dfm_python as dfm
|
|
521
|
-
from dfm_python import Nowcast
|
|
522
|
-
|
|
523
|
-
# Load config and data, train model
|
|
524
|
-
dfm.from_yaml('config/default.yaml')
|
|
525
|
-
dfm.load_data('data/data.csv')
|
|
526
|
-
dfm.train()
|
|
527
|
-
|
|
528
|
-
# Get Nowcast instance
|
|
529
|
-
model = dfm.DFM()
|
|
530
|
-
nowcast = model.nowcast # or: nowcast = Nowcast(model)
|
|
531
|
-
|
|
532
|
-
# Calculate nowcast (simple callable interface)
|
|
533
|
-
value = nowcast('gdp', view_date='2024-01-15', target_period='2024Q1')
|
|
534
|
-
print(f"Nowcast value: {value:.4f}")
|
|
535
|
-
|
|
536
|
-
# Or get full result with metadata
|
|
537
|
-
result = nowcast('gdp', view_date='2024-01-15', target_period='2024Q1', return_result=True)
|
|
538
|
-
print(f"Nowcast: {result.nowcast_value:.4f}")
|
|
539
|
-
print(f"Data availability: {result.data_availability}")
|
|
540
|
-
print(f"Factors at view: {result.factors_at_view}")
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
#### News Decomposition
|
|
544
|
-
|
|
545
|
-
Decompose forecast updates into contributions from individual data releases:
|
|
546
|
-
|
|
547
|
-
```python
|
|
548
|
-
# News decomposition between two data views
|
|
549
|
-
news = nowcast.decompose(
|
|
550
|
-
target_series='gdp',
|
|
551
|
-
target_period='2024Q1',
|
|
552
|
-
view_date_old='2024-01-15',
|
|
553
|
-
view_date_new='2024-02-15'
|
|
554
|
-
)
|
|
555
|
-
|
|
556
|
-
# Access results (NewsDecompResult)
|
|
557
|
-
print(f"Old forecast: {news.y_old:.4f}")
|
|
558
|
-
print(f"New forecast: {news.y_new:.4f}")
|
|
559
|
-
print(f"Change: {news.change:.4f}")
|
|
560
|
-
print(f"Top contributors: {news.top_contributors}")
|
|
561
|
-
|
|
562
|
-
# Or get dictionary format (backward compatibility)
|
|
563
|
-
news_dict = nowcast.decompose(
|
|
564
|
-
target_series='gdp',
|
|
565
|
-
target_period='2024Q1',
|
|
566
|
-
view_date_old='2024-01-15',
|
|
567
|
-
view_date_new='2024-02-15',
|
|
568
|
-
return_dict=True
|
|
569
|
-
)
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
#### Pseudo Real-Time Backtesting
|
|
573
|
-
|
|
574
|
-
Perform backtesting to evaluate model performance in pseudo real-time:
|
|
575
|
-
|
|
576
|
-
```python
|
|
577
|
-
from datetime import datetime
|
|
578
|
-
|
|
579
|
-
# Perform backtest
|
|
580
|
-
backtest_result = nowcast.backtest(
|
|
581
|
-
target_series='gdp',
|
|
582
|
-
target_date='2024Q4',
|
|
583
|
-
backward_steps=20, # 20 backward steps
|
|
584
|
-
higher_freq=True, # Use frequency one step faster than clock
|
|
585
|
-
include_actual=True # Compare with actual values
|
|
586
|
-
)
|
|
587
|
-
|
|
588
|
-
# Access metrics
|
|
589
|
-
print(f"Overall RMSE: {backtest_result.overall_rmse:.4f}")
|
|
590
|
-
print(f"Overall MAE: {backtest_result.overall_mae:.4f}")
|
|
591
|
-
print(f"Failed steps: {backtest_result.failed_steps}")
|
|
592
|
-
|
|
593
|
-
# Access point-wise metrics
|
|
594
|
-
print(f"RMSE per step: {backtest_result.rmse_per_step}")
|
|
595
|
-
print(f"MAE per step: {backtest_result.mae_per_step}")
|
|
596
|
-
|
|
597
|
-
# Access individual nowcast results
|
|
598
|
-
for i, nowcast_result in enumerate(backtest_result.nowcast_results):
|
|
599
|
-
print(f"Step {i}: nowcast={nowcast_result.nowcast_value:.4f}, "
|
|
600
|
-
f"view_date={nowcast_result.view_date}")
|
|
601
|
-
|
|
602
|
-
# Access news decomposition between steps
|
|
603
|
-
for i, news_result in enumerate(backtest_result.news_results):
|
|
604
|
-
if news_result is not None:
|
|
605
|
-
print(f"Step {i}: forecast change={news_result.change:.4f}")
|
|
606
|
-
|
|
607
|
-
# Visualize results
|
|
608
|
-
backtest_result.plot(save_path='backtest_results.png', show=False)
|
|
609
|
-
```
|
|
508
|
+
### Nowcasting
|
|
610
509
|
|
|
611
|
-
|
|
510
|
+
Nowcasting functionality has been moved to `src.nowcast`. Use `src.nowcast.Nowcast` for nowcasting operations, news decomposition, and backtesting.
|
|
612
511
|
|
|
613
512
|
Generate datasets for model evaluation across multiple periods:
|
|
614
513
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://pypi.org/project/dfm-python/)
|
|
4
4
|
[](https://www.python.org/downloads/)
|
|
5
5
|
|
|
6
|
-
A comprehensive Python implementation of **Dynamic Factor Models (DFM)** for
|
|
6
|
+
A comprehensive Python implementation of **Dynamic Factor Models (DFM)** for forecasting high-dimensional time series. Built for economists, researchers, and data scientists working with mixed-frequency macroeconomic data.
|
|
7
7
|
|
|
8
8
|
## What is a Dynamic Factor Model?
|
|
9
9
|
|
|
@@ -12,7 +12,6 @@ A Dynamic Factor Model is a powerful statistical framework that:
|
|
|
12
12
|
- **Extracts common factors** from many observed time series (e.g., GDP, consumption, investment, employment)
|
|
13
13
|
- **Handles mixed frequencies** seamlessly (monthly, quarterly, annual data together)
|
|
14
14
|
- **Deals with missing data** robustly (late-arriving indicators, publication delays)
|
|
15
|
-
- **Provides nowcasts** (current-quarter GDP estimates before official release)
|
|
16
15
|
- **Forecasts** future values of both factors and observed series
|
|
17
16
|
|
|
18
17
|
**Key Innovation**: All latent factors evolve at a common "clock" frequency (configurable: `'d'`, `'w'`, `'m'`, `'q'`, `'sa'`, `'a'`), while observed series can be at different frequencies. This is achieved through deterministic tent kernel aggregation, allowing quarterly GDP to be modeled using monthly latent factors, or any slower-frequency series to be modeled using higher-frequency latent factors.
|
|
@@ -25,8 +24,7 @@ A Dynamic Factor Model is a powerful statistical framework that:
|
|
|
25
24
|
- ✅ **Block structure**: Flexible factor organization (global common factor + sector-specific factors)
|
|
26
25
|
- ✅ **Idiosyncratic components**: Per-series state augmentation for better fit (AR(1) for clock-frequency, tent-length chains for slower frequencies)
|
|
27
26
|
- ✅ **Preprocessed data**: Package expects preprocessed data from users - users handle all preprocessing (imputation, scaling, feature engineering) using sktime or other tools
|
|
28
|
-
- ✅ **
|
|
29
|
-
- ✅ **Nowcasting & Forecasting**: Generate predictions for any horizon
|
|
27
|
+
- ✅ **Forecasting**: Generate predictions for any horizon
|
|
30
28
|
- ✅ **Deep Dynamic Factor Models (DDFM)**: Nonlinear encoder with PyTorch for capturing complex factor structures (optional, requires `dfm-python[deep]`)
|
|
31
29
|
|
|
32
30
|
### Technical Features
|
|
@@ -187,7 +185,7 @@ print(f"Log-likelihood: {result.loglik:.2f}")
|
|
|
187
185
|
|
|
188
186
|
### Example 4: Fast Reuse with `load_pickle`
|
|
189
187
|
|
|
190
|
-
Once a model has been trained you can reload it instantly for forecasting
|
|
188
|
+
Once a model has been trained you can reload it instantly for forecasting without
|
|
191
189
|
re-running EM:
|
|
192
190
|
|
|
193
191
|
```python
|
|
@@ -216,15 +214,12 @@ model.load_pickle(
|
|
|
216
214
|
|
|
217
215
|
# Fast inference (milliseconds instead of minutes)
|
|
218
216
|
X_forecast, Z_forecast = model.predict(horizon=12)
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
view_date='2024-03-15'
|
|
222
|
-
)
|
|
217
|
+
# Note: Nowcasting functionality has been moved to src.nowcast
|
|
218
|
+
# Use src.nowcast.Nowcast for nowcasting operations
|
|
223
219
|
```
|
|
224
220
|
|
|
225
221
|
`DFM.load_pickle()` accepts either the auto-save payload (`{'result': ..., 'config': ...}`) or a
|
|
226
|
-
raw `DFMResult`. Provide `load_data_path` or `data`/`time_index` when you need
|
|
227
|
-
decomposition abilities (which require the data view).
|
|
222
|
+
raw `DFMResult`. Provide `load_data_path` or `data`/`time_index` when you need to access model results.
|
|
228
223
|
|
|
229
224
|
## Configuration Guide
|
|
230
225
|
|
|
@@ -454,105 +449,9 @@ idio_component = result.X_sm[:, series_idx] - series_factor_component
|
|
|
454
449
|
|
|
455
450
|
## Advanced Features
|
|
456
451
|
|
|
457
|
-
### Nowcasting
|
|
458
|
-
|
|
459
|
-
The package provides a comprehensive nowcasting API for pseudo real-time evaluation and downstream model integration:
|
|
460
|
-
|
|
461
|
-
#### Basic Nowcasting
|
|
462
|
-
|
|
463
|
-
```python
|
|
464
|
-
import dfm_python as dfm
|
|
465
|
-
from dfm_python import Nowcast
|
|
466
|
-
|
|
467
|
-
# Load config and data, train model
|
|
468
|
-
dfm.from_yaml('config/default.yaml')
|
|
469
|
-
dfm.load_data('data/data.csv')
|
|
470
|
-
dfm.train()
|
|
471
|
-
|
|
472
|
-
# Get Nowcast instance
|
|
473
|
-
model = dfm.DFM()
|
|
474
|
-
nowcast = model.nowcast # or: nowcast = Nowcast(model)
|
|
475
|
-
|
|
476
|
-
# Calculate nowcast (simple callable interface)
|
|
477
|
-
value = nowcast('gdp', view_date='2024-01-15', target_period='2024Q1')
|
|
478
|
-
print(f"Nowcast value: {value:.4f}")
|
|
479
|
-
|
|
480
|
-
# Or get full result with metadata
|
|
481
|
-
result = nowcast('gdp', view_date='2024-01-15', target_period='2024Q1', return_result=True)
|
|
482
|
-
print(f"Nowcast: {result.nowcast_value:.4f}")
|
|
483
|
-
print(f"Data availability: {result.data_availability}")
|
|
484
|
-
print(f"Factors at view: {result.factors_at_view}")
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
#### News Decomposition
|
|
488
|
-
|
|
489
|
-
Decompose forecast updates into contributions from individual data releases:
|
|
490
|
-
|
|
491
|
-
```python
|
|
492
|
-
# News decomposition between two data views
|
|
493
|
-
news = nowcast.decompose(
|
|
494
|
-
target_series='gdp',
|
|
495
|
-
target_period='2024Q1',
|
|
496
|
-
view_date_old='2024-01-15',
|
|
497
|
-
view_date_new='2024-02-15'
|
|
498
|
-
)
|
|
499
|
-
|
|
500
|
-
# Access results (NewsDecompResult)
|
|
501
|
-
print(f"Old forecast: {news.y_old:.4f}")
|
|
502
|
-
print(f"New forecast: {news.y_new:.4f}")
|
|
503
|
-
print(f"Change: {news.change:.4f}")
|
|
504
|
-
print(f"Top contributors: {news.top_contributors}")
|
|
505
|
-
|
|
506
|
-
# Or get dictionary format (backward compatibility)
|
|
507
|
-
news_dict = nowcast.decompose(
|
|
508
|
-
target_series='gdp',
|
|
509
|
-
target_period='2024Q1',
|
|
510
|
-
view_date_old='2024-01-15',
|
|
511
|
-
view_date_new='2024-02-15',
|
|
512
|
-
return_dict=True
|
|
513
|
-
)
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
#### Pseudo Real-Time Backtesting
|
|
517
|
-
|
|
518
|
-
Perform backtesting to evaluate model performance in pseudo real-time:
|
|
519
|
-
|
|
520
|
-
```python
|
|
521
|
-
from datetime import datetime
|
|
522
|
-
|
|
523
|
-
# Perform backtest
|
|
524
|
-
backtest_result = nowcast.backtest(
|
|
525
|
-
target_series='gdp',
|
|
526
|
-
target_date='2024Q4',
|
|
527
|
-
backward_steps=20, # 20 backward steps
|
|
528
|
-
higher_freq=True, # Use frequency one step faster than clock
|
|
529
|
-
include_actual=True # Compare with actual values
|
|
530
|
-
)
|
|
531
|
-
|
|
532
|
-
# Access metrics
|
|
533
|
-
print(f"Overall RMSE: {backtest_result.overall_rmse:.4f}")
|
|
534
|
-
print(f"Overall MAE: {backtest_result.overall_mae:.4f}")
|
|
535
|
-
print(f"Failed steps: {backtest_result.failed_steps}")
|
|
536
|
-
|
|
537
|
-
# Access point-wise metrics
|
|
538
|
-
print(f"RMSE per step: {backtest_result.rmse_per_step}")
|
|
539
|
-
print(f"MAE per step: {backtest_result.mae_per_step}")
|
|
540
|
-
|
|
541
|
-
# Access individual nowcast results
|
|
542
|
-
for i, nowcast_result in enumerate(backtest_result.nowcast_results):
|
|
543
|
-
print(f"Step {i}: nowcast={nowcast_result.nowcast_value:.4f}, "
|
|
544
|
-
f"view_date={nowcast_result.view_date}")
|
|
545
|
-
|
|
546
|
-
# Access news decomposition between steps
|
|
547
|
-
for i, news_result in enumerate(backtest_result.news_results):
|
|
548
|
-
if news_result is not None:
|
|
549
|
-
print(f"Step {i}: forecast change={news_result.change:.4f}")
|
|
550
|
-
|
|
551
|
-
# Visualize results
|
|
552
|
-
backtest_result.plot(save_path='backtest_results.png', show=False)
|
|
553
|
-
```
|
|
452
|
+
### Nowcasting
|
|
554
453
|
|
|
555
|
-
|
|
454
|
+
Nowcasting functionality has been moved to `src.nowcast`. Use `src.nowcast.Nowcast` for nowcasting operations, news decomposition, and backtesting.
|
|
556
455
|
|
|
557
456
|
Generate datasets for model evaluation across multiple periods:
|
|
558
457
|
|
|
File without changes
|
|
File without changes
|