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.
- dfm_python/__init__.py +79 -145
- dfm_python/config/__init__.py +23 -28
- dfm_python/config/{io.py → adapter.py} +188 -396
- dfm_python/config/results.py +54 -21
- dfm_python/config/schema.py +400 -209
- dfm_python/config/utils.py +479 -25
- dfm_python/data/__init__.py +28 -0
- dfm_python/data/dataloader.py +140 -0
- dfm_python/data/dataset.py +154 -0
- dfm_python/{transformations → data}/utils.py +30 -32
- dfm_python/encoder/__init__.py +8 -2
- dfm_python/encoder/base.py +111 -0
- dfm_python/encoder/pca.py +142 -3
- dfm_python/encoder/vae.py +264 -4
- dfm_python/lightning/__init__.py +28 -13
- dfm_python/lightning/data_module.py +512 -190
- dfm_python/lightning/scaling.py +432 -0
- dfm_python/logger/__init__.py +2 -0
- dfm_python/logger/inference_logger.py +60 -17
- dfm_python/logger/logger.py +13 -3
- dfm_python/logger/train_logger.py +269 -45
- dfm_python/models/__init__.py +10 -22
- dfm_python/models/base.py +498 -28
- dfm_python/models/ddfm.py +1955 -665
- dfm_python/models/dfm.py +580 -679
- dfm_python/models/estimation.py +54 -35
- dfm_python/nowcast/__init__.py +17 -8
- dfm_python/nowcast/dataview.py +7 -7
- dfm_python/nowcast/helpers.py +32 -228
- dfm_python/nowcast/nowcast.py +274 -29
- dfm_python/nowcast/splitters.py +431 -0
- dfm_python/nowcast/transformers.py +330 -0
- dfm_python/nowcast/utils.py +20 -21
- dfm_python/ssm/em.py +395 -108
- dfm_python/ssm/kalman.py +14 -28
- dfm_python/ssm/utils.py +5 -2
- dfm_python/trainer/__init__.py +727 -8
- dfm_python/trainer/ddfm.py +149 -168
- dfm_python/trainer/dfm.py +130 -128
- dfm_python/utils/__init__.py +26 -56
- dfm_python/utils/data.py +44 -211
- dfm_python/utils/diagnostics.py +28 -23
- dfm_python/utils/helpers.py +26 -105
- dfm_python/utils/statespace.py +83 -142
- dfm_python/utils/time.py +148 -249
- {dfm_python-0.4.0.dist-info → dfm_python-0.4.3.dist-info}/METADATA +30 -64
- dfm_python-0.4.3.dist-info/RECORD +52 -0
- dfm_python/config/params.py +0 -202
- dfm_python/config/structure.py +0 -457
- dfm_python/lightning/ddfm_module.py +0 -553
- dfm_python/lightning/dfm_module.py +0 -466
- dfm_python/transformations/__init__.py +0 -35
- dfm_python/transformations/sktime.py +0 -40
- dfm_python/transformations/transformers.py +0 -320
- dfm_python-0.4.0.dist-info/RECORD +0 -53
- {dfm_python-0.4.0.dist-info → dfm_python-0.4.3.dist-info}/WHEEL +0 -0
- {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 (
|
|
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
|
-
-
|
|
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
|
-
-
|
|
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 (
|
|
28
|
-
>>>
|
|
29
|
-
>>>
|
|
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
|
-
>>> #
|
|
33
|
-
>>>
|
|
34
|
-
>>>
|
|
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
|
-
>>> #
|
|
37
|
-
>>>
|
|
36
|
+
>>> # Step 2: Create DataModule
|
|
37
|
+
>>> dm = DFMDataModule(config_path='config/default.yaml', data=df_processed)
|
|
38
|
+
>>> dm.setup()
|
|
38
39
|
>>>
|
|
39
|
-
>>> # Create
|
|
40
|
-
>>>
|
|
41
|
-
>>>
|
|
40
|
+
>>> # Step 3: Create model and load config
|
|
41
|
+
>>> model = DFM()
|
|
42
|
+
>>> model.load_config('config/default.yaml')
|
|
42
43
|
>>>
|
|
43
|
-
>>> #
|
|
44
|
-
>>>
|
|
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 (
|
|
48
|
-
>>>
|
|
49
|
-
>>> ddfm_model.load_config('config/default.yaml')
|
|
51
|
+
>>> # Or use DDFM (same pattern)
|
|
52
|
+
>>> from dfm_python import DDFM, DDFMTrainer
|
|
50
53
|
>>>
|
|
51
|
-
>>>
|
|
52
|
-
>>>
|
|
53
|
-
>>> data_module_ddfm.setup()
|
|
54
|
+
>>> dm_ddfm = DFMDataModule(config_path='config/default.yaml', data=df_processed)
|
|
55
|
+
>>> dm_ddfm.setup()
|
|
54
56
|
>>>
|
|
55
|
-
>>>
|
|
56
|
-
>>> ddfm_model.
|
|
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
|
-
|
|
60
|
-
|
|
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.
|
|
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,
|
|
80
|
+
# 1. Configuration: DFMConfig, SeriesConfig, config sources
|
|
98
81
|
# 2. High-level API: DFM, DDFM, module-level convenience functions
|
|
99
|
-
# 3. Core utilities:
|
|
100
|
-
# 4. Models: BaseFactorModel,
|
|
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
|
|
85
|
+
# 6. Data & Results: DFMResult
|
|
103
86
|
# ============================================================================
|
|
104
87
|
|
|
105
88
|
# Configuration (from config/ subpackage)
|
|
106
89
|
from .config import (
|
|
107
|
-
|
|
90
|
+
DEFAULT_BLOCK_NAME,
|
|
108
91
|
ConfigSource, YamlSource, DictSource, HydraSource,
|
|
109
92
|
MergedConfigSource, make_config_source,
|
|
110
93
|
)
|
|
111
|
-
|
|
112
|
-
#
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
-
'
|
|
133
|
+
'DFM', 'Nowcast',
|
|
183
134
|
# Model base and implementations
|
|
184
|
-
'BaseFactorModel',
|
|
135
|
+
'BaseFactorModel',
|
|
185
136
|
# Nowcast result classes
|
|
186
137
|
'NowcastResult', 'NewsDecompResult', 'BacktestResult',
|
|
187
138
|
# Constants
|
|
188
|
-
'
|
|
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
|
-
#
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
#
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
|
dfm_python/config/__init__.py
CHANGED
|
@@ -1,65 +1,60 @@
|
|
|
1
1
|
"""Configuration subpackage for DFM.
|
|
2
2
|
|
|
3
3
|
This subpackage provides:
|
|
4
|
-
- Schema (DFMConfig, SeriesConfig
|
|
5
|
-
- IO (ConfigSource, YamlSource, etc.) in
|
|
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,
|
|
10
|
-
|
|
9
|
+
BaseModelConfig, DFMConfig, DDFMConfig, SeriesConfig,
|
|
10
|
+
DEFAULT_BLOCK_NAME,
|
|
11
11
|
)
|
|
12
|
-
from .
|
|
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 .
|
|
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 .
|
|
22
|
+
from .utils import (
|
|
27
23
|
FREQUENCY_HIERARCHY,
|
|
28
24
|
PERIODS_PER_YEAR,
|
|
29
25
|
get_periods_per_year,
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
get_annual_factor,
|
|
27
|
+
compute_idio_lengths,
|
|
28
|
+
get_tent_weights,
|
|
32
29
|
generate_tent_weights,
|
|
33
30
|
generate_R_mat,
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
get_agg_structure,
|
|
32
|
+
group_by_freq,
|
|
36
33
|
)
|
|
37
34
|
|
|
38
35
|
__all__ = [
|
|
39
36
|
# Schema
|
|
40
|
-
'BaseModelConfig', 'DFMConfig', 'DDFMConfig', 'SeriesConfig',
|
|
41
|
-
'
|
|
42
|
-
#
|
|
43
|
-
'
|
|
37
|
+
'BaseModelConfig', 'DFMConfig', 'DDFMConfig', 'SeriesConfig',
|
|
38
|
+
'DEFAULT_BLOCK_NAME',
|
|
39
|
+
# Parameter overrides
|
|
40
|
+
'FitParams',
|
|
44
41
|
# Results
|
|
45
|
-
'BaseResult', 'DFMResult', 'DDFMResult',
|
|
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
|
-
|
|
52
|
-
# Structure utilities
|
|
48
|
+
# Frequency and aggregation utilities
|
|
53
49
|
'FREQUENCY_HIERARCHY',
|
|
54
50
|
'PERIODS_PER_YEAR',
|
|
55
51
|
'get_periods_per_year',
|
|
56
|
-
'
|
|
57
|
-
'
|
|
52
|
+
'get_annual_factor',
|
|
53
|
+
'compute_idio_lengths',
|
|
54
|
+
'get_tent_weights',
|
|
58
55
|
'generate_tent_weights',
|
|
59
56
|
'generate_R_mat',
|
|
60
|
-
'
|
|
61
|
-
'
|
|
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
|
|