dfm-python 0.4.6__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.
Files changed (170) hide show
  1. {dfm_python-0.4.6 → dfm_python-0.4.7}/PKG-INFO +9 -110
  2. {dfm_python-0.4.6 → dfm_python-0.4.7}/README.md +8 -109
  3. {dfm_python-0.4.6 → dfm_python-0.4.7}/pyproject.toml +1 -1
  4. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/__init__.py +13 -25
  5. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/models/base.py +0 -2
  6. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/models/ddfm.py +29 -259
  7. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/models/dfm.py +58 -1
  8. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/ssm/em.py +103 -13
  9. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/ssm/kalman.py +267 -28
  10. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/trainer/__init__.py +10 -3
  11. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/trainer/ddfm.py +5 -4
  12. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/utils/__init__.py +28 -14
  13. dfm_python-0.4.6/src/dfm_python/nowcast/__init__.py +0 -37
  14. dfm_python-0.4.6/src/dfm_python/nowcast/dataview.py +0 -143
  15. dfm_python-0.4.6/src/dfm_python/nowcast/helpers.py +0 -356
  16. dfm_python-0.4.6/src/dfm_python/nowcast/nowcast.py +0 -1263
  17. dfm_python-0.4.6/src/dfm_python/nowcast/splitters.py +0 -441
  18. dfm_python-0.4.6/src/dfm_python/nowcast/transformers.py +0 -330
  19. dfm_python-0.4.6/src/dfm_python/nowcast/utils.py +0 -281
  20. {dfm_python-0.4.6 → dfm_python-0.4.7}/.git +0 -0
  21. {dfm_python-0.4.6 → dfm_python-0.4.7}/.gitignore +0 -0
  22. {dfm_python-0.4.6 → dfm_python-0.4.7}/.python-version +0 -0
  23. {dfm_python-0.4.6 → dfm_python-0.4.7}/LICENSE +0 -0
  24. {dfm_python-0.4.6 → dfm_python-0.4.7}/MANIFEST.in +0 -0
  25. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/experiment/test_finance.yaml +0 -0
  26. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/experiment/test_macro.yaml +0 -0
  27. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/model/ddfm.yaml +0 -0
  28. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/model/dfm.yaml +0 -0
  29. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KO3YEARC.yaml +0 -0
  30. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBFDSAAF.yaml +0 -0
  31. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBFINAAF.yaml +0 -0
  32. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBFXSAAF.yaml +0 -0
  33. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBSESI_R.yaml +0 -0
  34. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBSIBCEQ.yaml +0 -0
  35. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBSIBCOQ.yaml +0 -0
  36. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBSIBNER.yaml +0 -0
  37. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBSIBNMR.yaml +0 -0
  38. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBSIEMAR.yaml +0 -0
  39. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBSIHAPR.yaml +0 -0
  40. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBSIIMER.yaml +0 -0
  41. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBSIIMPR.yaml +0 -0
  42. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBSIXMER.yaml +0 -0
  43. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOBUSINVR.yaml +0 -0
  44. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCALL_.yaml +0 -0
  45. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCNFBUSR.yaml +0 -0
  46. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCNFCONR.yaml +0 -0
  47. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCNGOV_D.yaml +0 -0
  48. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCNPER_D.yaml +0 -0
  49. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCOBUSIR.yaml +0 -0
  50. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCONPMTH.yaml +0 -0
  51. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCONPRCF.yaml +0 -0
  52. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCONSTRP.yaml +0 -0
  53. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCPCOREF.yaml +0 -0
  54. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCPEXFEF.yaml +0 -0
  55. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCREU__A.yaml +0 -0
  56. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCSECDMR.yaml +0 -0
  57. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCSECEMR.yaml +0 -0
  58. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCSEMEMR.yaml +0 -0
  59. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCSEOHDR.yaml +0 -0
  60. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCSEOHSR.yaml +0 -0
  61. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCSHHEMR.yaml +0 -0
  62. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCSHHLMR.yaml +0 -0
  63. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCSMTTOA.yaml +0 -0
  64. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCSPHIMR.yaml +0 -0
  65. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCSPSPMR.yaml +0 -0
  66. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOCYLEADR.yaml +0 -0
  67. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KODBLNEQA.yaml +0 -0
  68. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KODBLNHSA.yaml +0 -0
  69. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEMPCONF.yaml +0 -0
  70. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEMPMANF.yaml +0 -0
  71. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEMPTOTO.yaml +0 -0
  72. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEMPWREP.yaml +0 -0
  73. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEQUIMAE.yaml +0 -0
  74. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEQUIPTE.yaml +0 -0
  75. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEQUITTE.yaml +0 -0
  76. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEXCHINA.yaml +0 -0
  77. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEXNGS_D.yaml +0 -0
  78. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEXPGDSA.yaml +0 -0
  79. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOEXPPRCF.yaml +0 -0
  80. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOGCFCNSD.yaml +0 -0
  81. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOGCFFNVD.yaml +0 -0
  82. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOGDP___D.yaml +0 -0
  83. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOGFCF__D.yaml +0 -0
  84. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOHWRWEMP.yaml +0 -0
  85. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOIMNGS_D.yaml +0 -0
  86. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOIMPCONA.yaml +0 -0
  87. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOIMPGDDA.yaml +0 -0
  88. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOIMPGDSA.yaml +0 -0
  89. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOIMPPRCF.yaml +0 -0
  90. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOIPALL_G.yaml +0 -0
  91. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOIPMIMAG.yaml +0 -0
  92. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOLRLTCO.yaml +0 -0
  93. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOLRLTHH.yaml +0 -0
  94. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOMPCAPGG.yaml +0 -0
  95. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOMPCONDG.yaml +0 -0
  96. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOMPCONGG.yaml +0 -0
  97. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOMPCONNG.yaml +0 -0
  98. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOMPRI30G.yaml +0 -0
  99. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOMSCAPGG.yaml +0 -0
  100. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOMSCONGG.yaml +0 -0
  101. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KONETTRDF.yaml +0 -0
  102. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KONEWCONA.yaml +0 -0
  103. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOPICAPGG.yaml +0 -0
  104. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOPICONGG.yaml +0 -0
  105. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOPIMANUG.yaml +0 -0
  106. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOPOPACTE.yaml +0 -0
  107. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOPPSRM_F.yaml +0 -0
  108. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOPROPRCF.yaml +0 -0
  109. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOPSMANUG.yaml +0 -0
  110. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KORCNST.yaml +0 -0
  111. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KORELEC.yaml +0 -0
  112. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KORFBEV.yaml +0 -0
  113. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KORMACH.yaml +0 -0
  114. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KORMCMP.yaml +0 -0
  115. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOROCOINF.yaml +0 -0
  116. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KORWHLS.yaml +0 -0
  117. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOSHRPRCF.yaml +0 -0
  118. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOSIAHOTE.yaml +0 -0
  119. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOSIAI__E.yaml +0 -0
  120. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOSIARRLE.yaml +0 -0
  121. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOSIAWRTE.yaml +0 -0
  122. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOSSBFMBE.yaml +0 -0
  123. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOUN_TOTQ.yaml +0 -0
  124. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOUS____.yaml +0 -0
  125. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOVALCONA.yaml +0 -0
  126. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOWRCCNSE.yaml +0 -0
  127. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOWRCDURE.yaml +0 -0
  128. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOWRCNODE.yaml +0 -0
  129. {dfm_python-0.4.6 → dfm_python-0.4.7}/config/series/KOWRCSEME.yaml +0 -0
  130. {dfm_python-0.4.6 → dfm_python-0.4.7}/data/finance.csv +0 -0
  131. {dfm_python-0.4.6 → dfm_python-0.4.7}/data/macro.csv +0 -0
  132. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/config/__init__.py +0 -0
  133. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/config/adapter.py +0 -0
  134. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/config/results.py +0 -0
  135. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/config/schema.py +0 -0
  136. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/config/utils.py +0 -0
  137. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/data/__init__.py +0 -0
  138. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/data/dataloader.py +0 -0
  139. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/data/dataset.py +0 -0
  140. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/data/utils.py +0 -0
  141. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/encoder/__init__.py +0 -0
  142. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/encoder/base.py +0 -0
  143. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/encoder/pca.py +0 -0
  144. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/encoder/vae.py +0 -0
  145. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/lightning/__init__.py +0 -0
  146. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/lightning/data_module.py +0 -0
  147. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/lightning/scaling.py +0 -0
  148. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/logger/__init__.py +0 -0
  149. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/logger/inference_logger.py +0 -0
  150. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/logger/logger.py +0 -0
  151. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/logger/train_logger.py +0 -0
  152. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/models/__init__.py +0 -0
  153. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/ssm/__init__.py +0 -0
  154. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/ssm/utils.py +0 -0
  155. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/trainer/dfm.py +0 -0
  156. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/utils/data.py +0 -0
  157. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/utils/diagnostics.py +0 -0
  158. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/utils/helpers.py +0 -0
  159. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/utils/statespace.py +0 -0
  160. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/dfm_python/utils/time.py +0 -0
  161. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/test/test_config.py +0 -0
  162. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/test/test_helpers.py +0 -0
  163. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/test/test_logger.py +0 -0
  164. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/test/test_models.py +0 -0
  165. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/test/test_nowcast.py +0 -0
  166. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/test/test_sktime_integration.py +0 -0
  167. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/test/test_ssm.py +0 -0
  168. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/test/test_trainer.py +0 -0
  169. {dfm_python-0.4.6 → dfm_python-0.4.7}/src/test/test_utils.py +0 -0
  170. {dfm_python-0.4.6 → dfm_python-0.4.7}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dfm-python
3
- Version: 0.4.6
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
  [![PyPI version](https://img.shields.io/pypi/v/dfm-python.svg)](https://pypi.org/project/dfm-python/)
60
60
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
61
61
 
62
- A comprehensive Python implementation of **Dynamic Factor Models (DFM)** for nowcasting and forecasting high-dimensional time series. Built for economists, researchers, and data scientists working with mixed-frequency macroeconomic data.
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
- - ✅ **News decomposition**: Attribute forecast changes to specific data releases
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/nowcasting without
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
- gdp_nowcast = model.nowcast(
276
- target_series='gdp',
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 nowcasting/news
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 API
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
- #### Pseudo Real-Time Evaluation (Alternative Method)
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
  [![PyPI version](https://img.shields.io/pypi/v/dfm-python.svg)](https://pypi.org/project/dfm-python/)
4
4
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
5
5
 
6
- A comprehensive Python implementation of **Dynamic Factor Models (DFM)** for nowcasting and forecasting high-dimensional time series. Built for economists, researchers, and data scientists working with mixed-frequency macroeconomic data.
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
- - ✅ **News decomposition**: Attribute forecast changes to specific data releases
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/nowcasting without
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
- gdp_nowcast = model.nowcast(
220
- target_series='gdp',
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 nowcasting/news
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 API
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
- #### Pseudo Real-Time Evaluation (Alternative Method)
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
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dfm-python"
3
- version = "0.4.6"
3
+ version = "0.4.7"
4
4
  description = "Dynamic Factor Model (DFM) estimation and nowcasting in Python"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -6,7 +6,6 @@ This package implements a comprehensive Dynamic Factor Model framework with supp
6
6
  - Tent kernel aggregation for low-to-high frequency mapping
7
7
  - Expectation-Maximization (EM) algorithm for parameter estimation
8
8
  - Kalman filtering and smoothing for factor extraction
9
- - News decomposition for nowcasting
10
9
  - Deep Dynamic Factor Models (DDFM) with nonlinear encoders (requires PyTorch)
11
10
 
12
11
  The package implements a clock-based approach to mixed-frequency DFMs, where all latent
@@ -23,7 +22,6 @@ Key Features:
23
22
  - Flexible block structure for factor modeling
24
23
  - Robust handling of missing data (internal spline interpolation)
25
24
  - Automatic standardization and data clipping
26
- - News decomposition for forecast updates
27
25
 
28
26
  Example (Standard Lightning Pattern):
29
27
  >>> from dfm_python import DFM, DFMDataModule, DFMTrainer
@@ -67,7 +65,7 @@ Note: DFMConfig and SeriesConfig are internal implementation details.
67
65
  For detailed documentation, see the README.md file and the tutorial notebooks/scripts.
68
66
  """
69
67
 
70
- __version__ = "0.4.6"
68
+ __version__ = "0.4.7"
71
69
 
72
70
  # ============================================================================
73
71
  # PUBLIC API DEFINITION
@@ -81,7 +79,7 @@ __version__ = "0.4.6"
81
79
  # 2. High-level API: DFM, DDFM, module-level convenience functions
82
80
  # 3. Core utilities: TimeIndex, diagnostics
83
81
  # 4. Models: BaseFactorModel, DDFM (low-level)
84
- # 5. Nowcasting: Nowcast, result classes, para_const
82
+ # 5. Data & Results: DFMResult
85
83
  # 6. Data & Results: DFMResult
86
84
  # ============================================================================
87
85
 
@@ -90,8 +88,9 @@ from .config import (
90
88
  DEFAULT_BLOCK_NAME,
91
89
  ConfigSource, YamlSource, DictSource, HydraSource,
92
90
  MergedConfigSource, make_config_source,
93
- DFMConfig, SeriesConfig, # Internal use - prefer Hydra YAML configs
94
91
  )
92
+ # Internal imports (for backward compatibility, but not recommended)
93
+ from .config import DFMConfig, SeriesConfig # Internal use only
95
94
 
96
95
  # Results
97
96
  from .config.results import DFMResult, DDFMResult, BaseResult
@@ -101,23 +100,15 @@ from .utils.diagnostics import diagnose_series, print_series_diagnosis
101
100
  from .utils.time import calculate_rmse
102
101
 
103
102
  # PyTorch Lightning modules (mandatory dependency)
103
+ # Users can import these directly from dfm_python
104
104
  from .lightning import (
105
105
  DFMDataModule,
106
- DFMDataset,
107
- KalmanFilter,
108
- EMAlgorithm,
106
+ DFMDataset, # Dataset class (usually not needed directly)
107
+ KalmanFilter, # Module class
108
+ EMAlgorithm, # Module class
109
109
  )
110
110
 
111
- # Nowcasting (from nowcast/ subpackage)
112
- from .nowcast import (
113
- Nowcast,
114
- NowcastResult,
115
- )
116
- from .nowcast.helpers import (
117
- para_const,
118
- NewsDecompResult,
119
- BacktestResult,
120
- )
111
+ # Nowcasting removed - use src.nowcast instead
121
112
 
122
113
  # Model implementations
123
114
  from .models.base import BaseFactorModel
@@ -128,11 +119,9 @@ from .models.ddfm import DDFM, DDFMModel
128
119
 
129
120
  __all__ = [
130
121
  # Core classes
131
- 'DFM', 'Nowcast',
122
+ 'DFM',
132
123
  # Model base and implementations
133
124
  'BaseFactorModel',
134
- # Nowcast result classes
135
- 'NowcastResult', 'NewsDecompResult', 'BacktestResult',
136
125
  # Constants
137
126
  'DEFAULT_BLOCK_NAME',
138
127
  # Config sources
@@ -140,7 +129,6 @@ __all__ = [
140
129
  'MergedConfigSource', 'make_config_source',
141
130
  # Low-level API (functional interface - advanced usage)
142
131
  'BaseResult', 'DFMResult', 'DDFMResult', 'calculate_rmse', 'diagnose_series', 'print_series_diagnosis',
143
- 'para_const',
144
132
  ]
145
133
 
146
134
  # DDFM high-level API (PyTorch is mandatory)
@@ -152,9 +140,9 @@ __all__.extend([
152
140
  # Lightning modules (mandatory dependency)
153
141
  __all__.extend([
154
142
  'DFMDataModule',
155
- 'DFMDataset',
156
- 'KalmanFilter',
157
- 'EMAlgorithm',
143
+ 'DFMDataset', # Dataset class (usually not needed directly)
144
+ 'KalmanFilter', # Module class
145
+ 'EMAlgorithm', # Module class
158
146
  ])
159
147
 
160
148
  # Trainer classes (mandatory dependency)
@@ -91,7 +91,6 @@ class BaseFactorModel(pl.LightningModule):
91
91
  self._result: Optional[BaseResult] = None
92
92
  self.training_state: Optional[Any] = None
93
93
  self._data_module: Optional[Any] = None
94
- self._nowcast: Optional[Any] = None
95
94
 
96
95
  @property
97
96
  def config(self) -> DFMConfig:
@@ -494,7 +493,6 @@ class BaseFactorModel(pl.LightningModule):
494
493
  self._config = None
495
494
  self._data_module = None
496
495
  self._result = None
497
- self._nowcast = None
498
496
  if hasattr(self, 'training_state'):
499
497
  self.training_state = None
500
498
  return self