dfm-python 0.4.0__py3-none-any.whl → 0.4.3__py3-none-any.whl

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 (57) hide show
  1. dfm_python/__init__.py +79 -145
  2. dfm_python/config/__init__.py +23 -28
  3. dfm_python/config/{io.py → adapter.py} +188 -396
  4. dfm_python/config/results.py +54 -21
  5. dfm_python/config/schema.py +400 -209
  6. dfm_python/config/utils.py +479 -25
  7. dfm_python/data/__init__.py +28 -0
  8. dfm_python/data/dataloader.py +140 -0
  9. dfm_python/data/dataset.py +154 -0
  10. dfm_python/{transformations → data}/utils.py +30 -32
  11. dfm_python/encoder/__init__.py +8 -2
  12. dfm_python/encoder/base.py +111 -0
  13. dfm_python/encoder/pca.py +142 -3
  14. dfm_python/encoder/vae.py +264 -4
  15. dfm_python/lightning/__init__.py +28 -13
  16. dfm_python/lightning/data_module.py +512 -190
  17. dfm_python/lightning/scaling.py +432 -0
  18. dfm_python/logger/__init__.py +2 -0
  19. dfm_python/logger/inference_logger.py +60 -17
  20. dfm_python/logger/logger.py +13 -3
  21. dfm_python/logger/train_logger.py +269 -45
  22. dfm_python/models/__init__.py +10 -22
  23. dfm_python/models/base.py +498 -28
  24. dfm_python/models/ddfm.py +1955 -665
  25. dfm_python/models/dfm.py +580 -679
  26. dfm_python/models/estimation.py +54 -35
  27. dfm_python/nowcast/__init__.py +17 -8
  28. dfm_python/nowcast/dataview.py +7 -7
  29. dfm_python/nowcast/helpers.py +32 -228
  30. dfm_python/nowcast/nowcast.py +274 -29
  31. dfm_python/nowcast/splitters.py +431 -0
  32. dfm_python/nowcast/transformers.py +330 -0
  33. dfm_python/nowcast/utils.py +20 -21
  34. dfm_python/ssm/em.py +395 -108
  35. dfm_python/ssm/kalman.py +14 -28
  36. dfm_python/ssm/utils.py +5 -2
  37. dfm_python/trainer/__init__.py +727 -8
  38. dfm_python/trainer/ddfm.py +149 -168
  39. dfm_python/trainer/dfm.py +130 -128
  40. dfm_python/utils/__init__.py +26 -56
  41. dfm_python/utils/data.py +44 -211
  42. dfm_python/utils/diagnostics.py +28 -23
  43. dfm_python/utils/helpers.py +26 -105
  44. dfm_python/utils/statespace.py +83 -142
  45. dfm_python/utils/time.py +148 -249
  46. {dfm_python-0.4.0.dist-info → dfm_python-0.4.3.dist-info}/METADATA +30 -64
  47. dfm_python-0.4.3.dist-info/RECORD +52 -0
  48. dfm_python/config/params.py +0 -202
  49. dfm_python/config/structure.py +0 -457
  50. dfm_python/lightning/ddfm_module.py +0 -553
  51. dfm_python/lightning/dfm_module.py +0 -466
  52. dfm_python/transformations/__init__.py +0 -35
  53. dfm_python/transformations/sktime.py +0 -40
  54. dfm_python/transformations/transformers.py +0 -320
  55. dfm_python-0.4.0.dist-info/RECORD +0 -53
  56. {dfm_python-0.4.0.dist-info → dfm_python-0.4.3.dist-info}/WHEEL +0 -0
  57. {dfm_python-0.4.0.dist-info → dfm_python-0.4.3.dist-info}/licenses/LICENSE +0 -0
dfm_python/__init__.py CHANGED
@@ -7,7 +7,7 @@ This package implements a comprehensive Dynamic Factor Model framework with supp
7
7
  - Expectation-Maximization (EM) algorithm for parameter estimation
8
8
  - Kalman filtering and smoothing for factor extraction
9
9
  - News decomposition for nowcasting
10
- - Deep Dynamic Factor Models (DDFM) with nonlinear encoders (optional, requires PyTorch)
10
+ - Deep Dynamic Factor Models (DDFM) with nonlinear encoders (requires PyTorch)
11
11
 
12
12
  The package implements a clock-based approach to mixed-frequency DFMs, where all latent
13
13
  factors (global and block-level) are synchronized to a common "clock" frequency, typically
@@ -18,73 +18,56 @@ Note: Higher frequencies (daily, weekly) than the clock are not supported. If an
18
18
  has a frequency faster than the clock, a ValueError will be raised.
19
19
 
20
20
  Key Features:
21
- - Unified configuration system (YAML with Hydra/OmegaConf, or direct DFMConfig objects)
21
+ - Hydra-based configuration (YAML files) - primary configuration method
22
+ - Expects preprocessed data from users - users handle all preprocessing, package extracts statistics from pipeline
22
23
  - Flexible block structure for factor modeling
23
- - Robust handling of missing data
24
- - Comprehensive transformation support
24
+ - Robust handling of missing data (internal spline interpolation)
25
+ - Automatic standardization and data clipping
25
26
  - News decomposition for forecast updates
26
27
 
27
- Example (High-level API - Recommended):
28
- >>> import dfm_python as dfm
29
- >>> from dfm_python.lightning import DFMDataModule
30
- >>> from sktime.transformations.compose import ColumnTransformer
28
+ Example (Standard Lightning Pattern):
29
+ >>> from dfm_python import DFM, DFMDataModule, DFMTrainer
30
+ >>> import pandas as pd
31
31
  >>>
32
- >>> # Linear DFM
33
- >>> model = dfm.DFM()
34
- >>> model.load_config('config/default.yaml')
32
+ >>> # Step 1: Load and preprocess data
33
+ >>> df = pd.read_csv('data/sample_data.csv')
34
+ >>> df_processed = df[[col for col in df.columns if col != 'date']]
35
35
  >>>
36
- >>> # Create transformer (user must provide)
37
- >>> transformer = ColumnTransformer([...]) # User-defined sktime transformer
36
+ >>> # Step 2: Create DataModule
37
+ >>> dm = DFMDataModule(config_path='config/default.yaml', data=df_processed)
38
+ >>> dm.setup()
38
39
  >>>
39
- >>> # Create DataModule
40
- >>> data_module = DFMDataModule(config=model.config, transformer=transformer, data_path='data/sample_data.csv')
41
- >>> data_module.setup()
40
+ >>> # Step 3: Create model and load config
41
+ >>> model = DFM()
42
+ >>> model.load_config('config/default.yaml')
42
43
  >>>
43
- >>> # Train
44
- >>> model.train(data_module, max_iter=100)
44
+ >>> # Step 4: Create trainer and fit (standard Lightning pattern)
45
+ >>> trainer = DFMTrainer(max_epochs=100)
46
+ >>> trainer.fit(model, dm)
47
+ >>>
48
+ >>> # Step 5: Predict
45
49
  >>> Xf, Zf = model.predict(horizon=6)
46
50
  >>>
47
- >>> # Or use DDFM (separate class)
48
- >>> ddfm_model = dfm.DDFM(encoder_layers=[64, 32], num_factors=2)
49
- >>> ddfm_model.load_config('config/default.yaml')
51
+ >>> # Or use DDFM (same pattern)
52
+ >>> from dfm_python import DDFM, DDFMTrainer
50
53
  >>>
51
- >>> # Create DataModule for DDFM
52
- >>> data_module_ddfm = DFMDataModule(config=ddfm_model.config, transformer=transformer, data_path='data/sample_data.csv')
53
- >>> data_module_ddfm.setup()
54
+ >>> dm_ddfm = DFMDataModule(config_path='config/default.yaml', data=df_processed)
55
+ >>> dm_ddfm.setup()
54
56
  >>>
55
- >>> # Train
56
- >>> ddfm_model.train(data_module_ddfm, epochs=100)
57
+ >>> ddfm_model = DDFM(encoder_layers=[64, 32], num_factors=2)
58
+ >>> ddfm_model.load_config('config/default.yaml')
59
+ >>>
60
+ >>> trainer_ddfm = DDFMTrainer(max_epochs=100)
61
+ >>> trainer_ddfm.fit(ddfm_model, dm_ddfm)
57
62
  >>> Xf, Zf = ddfm_model.predict(horizon=6)
58
63
 
59
- Example (Low-level API - For advanced usage):
60
- >>> from dfm_python import DFM, DFMConfig, SeriesConfig
61
- >>> from dfm_python.transformations.utils import read_data # Preferred import
62
- >>> # Option 1: Load from YAML
63
- >>> config = load_config('config.yaml')
64
- >>> # Option 2: Create directly
65
- >>> config = DFMConfig(
66
- ... series=[SeriesConfig(frequency='m', transformation='lin', blocks=[1], series_id='series1')],
67
- ... block_names=['Global']
68
- ... )
69
- >>> from dfm_python.lightning import DFMDataModule
70
- >>> from sktime.transformations.compose import ColumnTransformer
71
- >>>
72
- >>> # Create transformer (user must provide)
73
- >>> transformer = ColumnTransformer([...]) # User-defined
74
- >>>
75
- >>> # Create DataModule
76
- >>> data_module = DFMDataModule(config=config, transformer=transformer, data_path='data.csv')
77
- >>> data_module.setup()
78
- >>>
79
- >>> # Fit model
80
- >>> model = DFM()
81
- >>> result = model.fit(data_module, config)
82
- >>> factors = result.Z # Extract estimated factors
64
+ Note: DFMConfig and SeriesConfig are internal implementation details.
65
+ Users should use Hydra YAML configuration files instead.
83
66
 
84
67
  For detailed documentation, see the README.md file and the tutorial notebooks/scripts.
85
68
  """
86
69
 
87
- __version__ = "0.4.0"
70
+ __version__ = "0.4.3"
88
71
 
89
72
  # ============================================================================
90
73
  # PUBLIC API DEFINITION
@@ -94,23 +77,22 @@ __version__ = "0.4.0"
94
77
  # Internal reorganization should not break these imports.
95
78
  #
96
79
  # Public API categories:
97
- # 1. Configuration: DFMConfig, SeriesConfig, BlockConfig, Params, config sources
80
+ # 1. Configuration: DFMConfig, SeriesConfig, config sources
98
81
  # 2. High-level API: DFM, DDFM, module-level convenience functions
99
- # 3. Core utilities: DFMCore, run_kf, TimeIndex, diagnostics
100
- # 4. Models: BaseFactorModel, DFMLinear, DDFM (low-level)
82
+ # 3. Core utilities: TimeIndex, diagnostics
83
+ # 4. Models: BaseFactorModel, DDFM (low-level)
101
84
  # 5. Nowcasting: Nowcast, result classes, para_const
102
- # 6. Data & Results: DFMResult, transform_data
85
+ # 6. Data & Results: DFMResult
103
86
  # ============================================================================
104
87
 
105
88
  # Configuration (from config/ subpackage)
106
89
  from .config import (
107
- DFMConfig, SeriesConfig, BlockConfig, Params, DEFAULT_GLOBAL_BLOCK_NAME,
90
+ DEFAULT_BLOCK_NAME,
108
91
  ConfigSource, YamlSource, DictSource, HydraSource,
109
92
  MergedConfigSource, make_config_source,
110
93
  )
111
-
112
- # Data utilities
113
- # Note: transform_data and DFMScaler have been removed - users must provide their own sktime transformers to DFMDataModule
94
+ # Internal imports (for backward compatibility, but not recommended)
95
+ from .config import DFMConfig, SeriesConfig # Internal use only
114
96
 
115
97
  # Results
116
98
  from .config.results import DFMResult, DDFMResult, BaseResult
@@ -118,27 +100,15 @@ from .config.results import DFMResult, DDFMResult, BaseResult
118
100
  # Utilities (from utils/ subpackage)
119
101
  from .utils.diagnostics import diagnose_series, print_series_diagnosis
120
102
  from .utils.time import calculate_rmse
121
- # DFMCore is an alias for DFMLinear (backward compatibility)
122
- from .models.dfm import DFMLinear
123
- DFMCore = DFMLinear
124
-
125
- # PyTorch Lightning modules (recommended)
126
- try:
127
- from .lightning import (
128
- DFMLightningModule,
129
- DDFMLightningModule,
130
- DFMDataModule,
131
- KalmanFilter, # New module class
132
- EMAlgorithm, # New module class
133
- )
134
- _has_lightning = True
135
- except ImportError:
136
- _has_lightning = False
137
- DFMLightningModule = None # type: ignore
138
- DDFMLightningModule = None # type: ignore
139
- DFMDataModule = None # type: ignore
140
- KalmanFilter = None # type: ignore
141
- EMAlgorithm = None # type: ignore
103
+
104
+ # PyTorch Lightning modules (mandatory dependency)
105
+ # Users can import these directly from dfm_python
106
+ from .lightning import (
107
+ DFMDataModule,
108
+ DFMDataset, # Dataset class (usually not needed directly)
109
+ KalmanFilter, # Module class
110
+ EMAlgorithm, # Module class
111
+ )
142
112
 
143
113
  # Nowcasting (from nowcast/ subpackage)
144
114
  from .nowcast import (
@@ -153,84 +123,48 @@ from .nowcast.helpers import (
153
123
 
154
124
  # Model implementations
155
125
  from .models.base import BaseFactorModel
156
- from .models.dfm import DFMLinear, DFM
157
- from .models.dfm import (
158
- from_yaml, from_spec, from_spec_df, from_dict,
159
- load_config, load_pickle, train, predict, plot, reset, create_model
160
- )
161
- # Note: load_data has been removed - use DFMDataModule instead
162
-
163
- # DDFM high-level API and low-level model (both optional, requires PyTorch)
164
- try:
165
- from .models.ddfm import DDFM, DDFMModel
166
- from .models.ddfm import load_config_ddfm, load_data_ddfm, train_ddfm, predict_ddfm, plot_ddfm, reset_ddfm
167
- _has_ddfm = True
168
- except ImportError:
169
- _has_ddfm = False
170
- DDFM = None # type: ignore
171
- DDFMModel = None # type: ignore
172
- load_config_ddfm = None # type: ignore
173
- load_data_ddfm = None # type: ignore
174
- train_ddfm = None # type: ignore
175
- predict_ddfm = None # type: ignore
176
- plot_ddfm = None # type: ignore
177
- reset_ddfm = None # type: ignore
178
- # DDFM module-level functions removed - create DDFM() instance directly
126
+ from .models.dfm import DFM
127
+
128
+ # DDFM high-level API and low-level model (PyTorch is mandatory)
129
+ from .models.ddfm import DDFM, DDFMModel
179
130
 
180
131
  __all__ = [
181
132
  # Core classes
182
- 'DFMConfig', 'SeriesConfig', 'BlockConfig', 'Params', 'DFM', 'DFMCore', 'Nowcast',
133
+ 'DFM', 'Nowcast',
183
134
  # Model base and implementations
184
- 'BaseFactorModel', 'DFMLinear',
135
+ 'BaseFactorModel',
185
136
  # Nowcast result classes
186
137
  'NowcastResult', 'NewsDecompResult', 'BacktestResult',
187
138
  # Constants
188
- 'DEFAULT_GLOBAL_BLOCK_NAME',
139
+ 'DEFAULT_BLOCK_NAME',
189
140
  # Config sources
190
141
  'ConfigSource', 'YamlSource', 'DictSource', 'HydraSource',
191
142
  'MergedConfigSource', 'make_config_source',
192
- # High-level API (module-level - recommended)
193
- 'load_config',
194
- 'load_pickle', 'train', 'predict', 'plot', 'reset', 'create_model',
195
- # Convenience constructors (cleaner API)
196
- 'from_yaml', 'from_spec', 'from_spec_df', 'from_dict',
197
143
  # Low-level API (functional interface - advanced usage)
198
144
  'BaseResult', 'DFMResult', 'DDFMResult', 'calculate_rmse', 'diagnose_series', 'print_series_diagnosis',
199
145
  'para_const', # Internal utility for nowcasting
200
146
  ]
201
147
 
202
- # Add DDFM high-level API and convenience functions if available
203
- if _has_ddfm:
204
- __all__.extend([
205
- 'DDFM', # High-level API class
206
- 'DDFMModel', # Low-level implementation
207
- 'load_config_ddfm', 'train_ddfm',
208
- 'predict_ddfm', 'plot_ddfm', 'reset_ddfm'
209
- # Note: load_data_ddfm has been removed - use DFMDataModule instead
210
- ])
211
-
212
- # Add Lightning modules if available
213
- if _has_lightning:
214
- __all__.extend([
215
- 'DFMLightningModule',
216
- 'DDFMLightningModule',
217
- 'DFMDataModule',
218
- 'KalmanFilter', # New module class
219
- 'EMAlgorithm', # New module class
220
- ])
221
-
222
- # Add Trainer classes if available
223
- try:
224
- from .trainer import DFMTrainer, DDFMTrainer
225
- _has_trainers = True
226
- except ImportError:
227
- _has_trainers = False
228
- DFMTrainer = None # type: ignore
229
- DDFMTrainer = None # type: ignore
230
-
231
- if _has_trainers:
232
- __all__.extend([
233
- 'DFMTrainer',
234
- 'DDFMTrainer',
235
- ])
148
+ # DDFM high-level API (PyTorch is mandatory)
149
+ __all__.extend([
150
+ 'DDFM', # High-level API class
151
+ 'DDFMModel', # Low-level implementation (used internally)
152
+ ])
153
+
154
+ # Lightning modules (mandatory dependency)
155
+ __all__.extend([
156
+ 'DFMDataModule',
157
+ 'DFMDataset', # Dataset class (usually not needed directly)
158
+ 'KalmanFilter', # Module class
159
+ 'EMAlgorithm', # Module class
160
+ ])
161
+
162
+ # Trainer classes (mandatory dependency)
163
+ from .trainer import DFMTrainer, DDFMTrainer
164
+
165
+ __all__.extend([
166
+ 'DFMTrainer',
167
+ 'DDFMTrainer',
168
+ ])
169
+
236
170
 
@@ -1,65 +1,60 @@
1
1
  """Configuration subpackage for DFM.
2
2
 
3
3
  This subpackage provides:
4
- - Schema (DFMConfig, SeriesConfig, BlockConfig, Params) in schema.py
5
- - IO (ConfigSource, YamlSource, etc.) in io.py
4
+ - Schema (DFMConfig, SeriesConfig) in schema.py
5
+ - IO (ConfigSource, YamlSource, etc.) in adapter.py
6
6
  """
7
7
 
8
8
  from .schema import (
9
- BaseModelConfig, DFMConfig, DDFMConfig, SeriesConfig, BlockConfig,
10
- DEFAULT_GLOBAL_BLOCK_NAME,
9
+ BaseModelConfig, DFMConfig, DDFMConfig, SeriesConfig,
10
+ DEFAULT_BLOCK_NAME,
11
11
  )
12
- from .params import Params, FitParams
13
- from .results import BaseResult, DFMResult, DDFMResult, DFMParams
12
+ from .results import BaseResult, DFMResult, DDFMResult, FitParams
14
13
  from .utils import validate_frequency, validate_transformation
15
- from .io import (
14
+ from .adapter import (
16
15
  ConfigSource,
17
16
  YamlSource,
18
17
  DictSource,
19
18
  HydraSource,
20
19
  MergedConfigSource,
21
20
  make_config_source,
22
- from_spec,
23
- # Note: Private functions (_load_config_from_dataframe, _write_series_blocks_yaml)
24
- # are available from io module but not exported as public API
25
21
  )
26
- from .structure import (
22
+ from .utils import (
27
23
  FREQUENCY_HIERARCHY,
28
24
  PERIODS_PER_YEAR,
29
25
  get_periods_per_year,
30
- compute_idio_chain_lengths,
31
- get_tent_weights_for_pair,
26
+ get_annual_factor,
27
+ compute_idio_lengths,
28
+ get_tent_weights,
32
29
  generate_tent_weights,
33
30
  generate_R_mat,
34
- get_aggregation_structure,
35
- group_series_by_frequency,
31
+ get_agg_structure,
32
+ group_by_freq,
36
33
  )
37
34
 
38
35
  __all__ = [
39
36
  # Schema
40
- 'BaseModelConfig', 'DFMConfig', 'DDFMConfig', 'SeriesConfig', 'BlockConfig',
41
- 'DEFAULT_GLOBAL_BLOCK_NAME',
42
- # Parameters
43
- 'Params', 'FitParams',
37
+ 'BaseModelConfig', 'DFMConfig', 'DDFMConfig', 'SeriesConfig',
38
+ 'DEFAULT_BLOCK_NAME',
39
+ # Parameter overrides
40
+ 'FitParams',
44
41
  # Results
45
- 'BaseResult', 'DFMResult', 'DDFMResult', 'DFMParams',
42
+ 'BaseResult', 'DFMResult', 'DDFMResult',
46
43
  # Utilities
47
44
  'validate_frequency', 'validate_transformation',
48
45
  # IO
49
46
  'ConfigSource', 'YamlSource', 'DictSource',
50
47
  'HydraSource', 'MergedConfigSource', 'make_config_source',
51
- 'from_spec',
52
- # Structure utilities
48
+ # Frequency and aggregation utilities
53
49
  'FREQUENCY_HIERARCHY',
54
50
  'PERIODS_PER_YEAR',
55
51
  'get_periods_per_year',
56
- 'compute_idio_chain_lengths',
57
- 'get_tent_weights_for_pair',
52
+ 'get_annual_factor',
53
+ 'compute_idio_lengths',
54
+ 'get_tent_weights',
58
55
  'generate_tent_weights',
59
56
  'generate_R_mat',
60
- 'get_aggregation_structure',
61
- 'group_series_by_frequency',
62
- # Note: Private functions (_load_config_from_dataframe, _write_series_blocks_yaml)
63
- # are available from io module but not exported as public API
57
+ 'get_agg_structure',
58
+ 'group_by_freq',
64
59
  ]
65
60