dfm-python 0.3.1__py3-none-any.whl → 0.4.2__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 +94 -115
- dfm_python/config/__init__.py +42 -12
- dfm_python/config/{io.py → adapter.py} +188 -198
- dfm_python/{core → config}/results.py +130 -80
- dfm_python/config/schema.py +585 -430
- dfm_python/{core/structure.py → config/utils.py} +103 -13
- dfm_python/data/__init__.py +52 -0
- dfm_python/data/dataloader.py +97 -0
- dfm_python/data/dataset.py +154 -0
- dfm_python/data/transformation.py +313 -0
- dfm_python/data/utils.py +339 -0
- dfm_python/encoder/__init__.py +39 -0
- dfm_python/encoder/base.py +111 -0
- dfm_python/encoder/pca.py +296 -0
- dfm_python/encoder/vae.py +550 -0
- dfm_python/lightning/__init__.py +50 -0
- dfm_python/lightning/callbacks.py +0 -0
- dfm_python/lightning/data_module.py +558 -0
- dfm_python/lightning/ddfm_module.py +580 -0
- dfm_python/lightning/dfm_module.py +466 -0
- dfm_python/lightning/utils.py +0 -0
- dfm_python/logger/__init__.py +53 -0
- dfm_python/logger/inference_logger.py +313 -0
- dfm_python/logger/logger.py +120 -0
- dfm_python/logger/train_logger.py +533 -0
- dfm_python/models/__init__.py +13 -8
- dfm_python/models/base.py +185 -48
- dfm_python/models/ddfm.py +1381 -765
- dfm_python/models/dfm.py +1078 -119
- dfm_python/models/estimation.py +372 -0
- dfm_python/nowcast/__init__.py +28 -0
- dfm_python/nowcast/dataview.py +143 -0
- dfm_python/nowcast/helpers.py +358 -0
- dfm_python/{nowcasting → nowcast}/nowcast.py +55 -537
- dfm_python/nowcast/utils.py +289 -0
- dfm_python/ssm/__init__.py +47 -0
- dfm_python/ssm/em.py +775 -0
- dfm_python/ssm/kalman.py +604 -0
- dfm_python/ssm/utils.py +380 -0
- dfm_python/trainer/__init__.py +739 -0
- dfm_python/trainer/ddfm.py +177 -0
- dfm_python/trainer/dfm.py +155 -0
- dfm_python/utils/__init__.py +159 -26
- dfm_python/utils/data.py +542 -0
- dfm_python/{core → utils}/diagnostics.py +11 -87
- dfm_python/utils/helpers.py +454 -0
- dfm_python/utils/statespace.py +1297 -0
- dfm_python/{core → utils}/time.py +373 -0
- {dfm_python-0.3.1.dist-info → dfm_python-0.4.2.dist-info}/METADATA +17 -9
- dfm_python-0.4.2.dist-info/RECORD +52 -0
- dfm_python/api/__init__.py +0 -44
- dfm_python/api/model_api.py +0 -1148
- dfm_python/api/session_api.py +0 -402
- dfm_python/core/__init__.py +0 -139
- dfm_python/core/em.py +0 -1385
- dfm_python/core/estimation.py +0 -553
- dfm_python/core/helpers.py +0 -1338
- dfm_python/core/state_space.py +0 -993
- dfm_python/dataloader/__init__.py +0 -30
- dfm_python/dataloader/loader.py +0 -763
- dfm_python/dataloader/preprocess.py +0 -11
- dfm_python/nowcasting/__init__.py +0 -13
- dfm_python/utils/convert.py +0 -342
- dfm_python/utils/loss.py +0 -184
- dfm_python-0.3.1.dist-info/RECORD +0 -32
- {dfm_python-0.3.1.dist-info → dfm_python-0.4.2.dist-info}/WHEEL +0 -0
- {dfm_python-0.3.1.dist-info → dfm_python-0.4.2.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,47 +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 - package applies internal transformations automatically
|
|
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
|
-
>>>
|
|
28
|
+
Example (Standard Lightning Pattern):
|
|
29
|
+
>>> from dfm_python import DFM, DFMDataModule, DFMTrainer
|
|
30
|
+
>>> import polars as pl
|
|
31
|
+
>>>
|
|
32
|
+
>>> # Step 1: Load and preprocess data
|
|
33
|
+
>>> df = pl.read_csv('data/sample_data.csv')
|
|
34
|
+
>>> df_processed = df.select([col for col in df.columns if col != 'date'])
|
|
35
|
+
>>>
|
|
36
|
+
>>> # Step 2: Create DataModule
|
|
37
|
+
>>> dm = DFMDataModule(config_path='config/default.yaml', data=df_processed)
|
|
38
|
+
>>> dm.setup()
|
|
39
|
+
>>>
|
|
40
|
+
>>> # Step 3: Create model and load config
|
|
41
|
+
>>> model = DFM()
|
|
31
42
|
>>> model.load_config('config/default.yaml')
|
|
32
|
-
>>>
|
|
33
|
-
>>>
|
|
43
|
+
>>>
|
|
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
|
|
34
49
|
>>> Xf, Zf = model.predict(horizon=6)
|
|
35
50
|
>>>
|
|
36
|
-
>>> # Or use DDFM (
|
|
37
|
-
>>>
|
|
51
|
+
>>> # Or use DDFM (same pattern)
|
|
52
|
+
>>> from dfm_python import DDFM, DDFMTrainer
|
|
53
|
+
>>>
|
|
54
|
+
>>> dm_ddfm = DFMDataModule(config_path='config/default.yaml', data=df_processed)
|
|
55
|
+
>>> dm_ddfm.setup()
|
|
56
|
+
>>>
|
|
57
|
+
>>> ddfm_model = DDFM(encoder_layers=[64, 32], num_factors=2)
|
|
38
58
|
>>> ddfm_model.load_config('config/default.yaml')
|
|
39
|
-
>>>
|
|
40
|
-
>>>
|
|
59
|
+
>>>
|
|
60
|
+
>>> trainer_ddfm = DDFMTrainer(max_epochs=100)
|
|
61
|
+
>>> trainer_ddfm.fit(ddfm_model, dm_ddfm)
|
|
41
62
|
>>> Xf, Zf = ddfm_model.predict(horizon=6)
|
|
42
63
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
>>> from dfm_python.dataloader import load_data # Preferred import
|
|
46
|
-
>>> # Option 1: Load from YAML
|
|
47
|
-
>>> config = load_config('config.yaml')
|
|
48
|
-
>>> # Option 2: Create directly
|
|
49
|
-
>>> config = DFMConfig(
|
|
50
|
-
... series=[SeriesConfig(frequency='m', transformation='lin', blocks=[1], series_id='series1')],
|
|
51
|
-
... block_names=['Global']
|
|
52
|
-
... )
|
|
53
|
-
>>> X, Time, _ = load_data('data.csv', config) # or use database adapter
|
|
54
|
-
>>> model = DFM()
|
|
55
|
-
>>> result = model.fit(X, config)
|
|
56
|
-
>>> factors = result.Z # Extract estimated factors
|
|
64
|
+
Note: DFMConfig and SeriesConfig are internal implementation details.
|
|
65
|
+
Users should use Hydra YAML configuration files instead.
|
|
57
66
|
|
|
58
67
|
For detailed documentation, see the README.md file and the tutorial notebooks/scripts.
|
|
59
68
|
"""
|
|
60
69
|
|
|
61
|
-
__version__ = "0.
|
|
70
|
+
__version__ = "0.4.2"
|
|
62
71
|
|
|
63
72
|
# ============================================================================
|
|
64
73
|
# PUBLIC API DEFINITION
|
|
@@ -68,126 +77,96 @@ __version__ = "0.3.1"
|
|
|
68
77
|
# Internal reorganization should not break these imports.
|
|
69
78
|
#
|
|
70
79
|
# Public API categories:
|
|
71
|
-
# 1. Configuration: DFMConfig, SeriesConfig,
|
|
80
|
+
# 1. Configuration: DFMConfig, SeriesConfig, config sources
|
|
72
81
|
# 2. High-level API: DFM, DDFM, module-level convenience functions
|
|
73
|
-
# 3. Core utilities:
|
|
82
|
+
# 3. Core utilities: DFMLinear, TimeIndex, diagnostics
|
|
74
83
|
# 4. Models: BaseFactorModel, DFMLinear, DDFM (low-level)
|
|
75
84
|
# 5. Nowcasting: Nowcast, result classes, para_const
|
|
76
|
-
# 6. Data & Results: DFMResult
|
|
85
|
+
# 6. Data & Results: DFMResult
|
|
77
86
|
# ============================================================================
|
|
78
87
|
|
|
79
88
|
# Configuration (from config/ subpackage)
|
|
80
89
|
from .config import (
|
|
81
|
-
|
|
90
|
+
DEFAULT_BLOCK_NAME,
|
|
82
91
|
ConfigSource, YamlSource, DictSource, HydraSource,
|
|
83
92
|
MergedConfigSource, make_config_source,
|
|
84
93
|
)
|
|
94
|
+
# Internal imports (for backward compatibility, but not recommended)
|
|
95
|
+
from .config import DFMConfig, SeriesConfig # Internal use only
|
|
85
96
|
|
|
86
97
|
# Data utilities
|
|
87
|
-
from .dataloader import transform_data
|
|
88
98
|
|
|
89
99
|
# Results
|
|
90
|
-
from .
|
|
91
|
-
|
|
92
|
-
#
|
|
93
|
-
from .
|
|
94
|
-
from .
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
from .config.results import DFMResult, DDFMResult, BaseResult
|
|
101
|
+
|
|
102
|
+
# Utilities (from utils/ subpackage)
|
|
103
|
+
from .utils.diagnostics import diagnose_series, print_series_diagnosis
|
|
104
|
+
from .utils.time import calculate_rmse
|
|
105
|
+
|
|
106
|
+
# PyTorch Lightning modules (mandatory dependency)
|
|
107
|
+
# Users can import these directly from dfm_python
|
|
108
|
+
from .lightning import (
|
|
109
|
+
DFMDataModule,
|
|
110
|
+
DFMDataset, # Dataset class (usually not needed directly)
|
|
111
|
+
KalmanFilter, # Module class
|
|
112
|
+
EMAlgorithm, # Module class
|
|
113
|
+
)
|
|
98
114
|
|
|
99
|
-
# Nowcasting (
|
|
100
|
-
from .
|
|
115
|
+
# Nowcasting (from nowcast/ subpackage)
|
|
116
|
+
from .nowcast import (
|
|
101
117
|
Nowcast,
|
|
102
|
-
para_const,
|
|
103
118
|
NowcastResult,
|
|
119
|
+
)
|
|
120
|
+
from .nowcast.helpers import (
|
|
121
|
+
para_const,
|
|
104
122
|
NewsDecompResult,
|
|
105
123
|
BacktestResult,
|
|
106
124
|
)
|
|
107
125
|
|
|
108
|
-
# High-level API (from api/ subpackage)
|
|
109
|
-
from .api import (
|
|
110
|
-
DFM, _dfm_instance, from_yaml, from_spec, from_spec_df, from_dict,
|
|
111
|
-
load_config, load_data, load_pickle, train, predict, plot, reset, create_model
|
|
112
|
-
)
|
|
113
|
-
|
|
114
126
|
# Model implementations
|
|
115
127
|
from .models.base import BaseFactorModel
|
|
116
|
-
from .models.dfm import DFMLinear
|
|
117
|
-
|
|
118
|
-
# DDFM high-level API and low-level model (
|
|
119
|
-
|
|
120
|
-
from .api import DDFM as DDFMAPI, _ddfm_instance
|
|
121
|
-
from .api import load_config_ddfm, load_data_ddfm, train_ddfm, predict_ddfm, plot_ddfm, reset_ddfm
|
|
122
|
-
from .models.ddfm import DDFM as DDFMModel
|
|
123
|
-
_has_ddfm = True
|
|
124
|
-
# Export high-level API as DDFM
|
|
125
|
-
DDFM = DDFMAPI
|
|
126
|
-
except ImportError:
|
|
127
|
-
_has_ddfm = False
|
|
128
|
-
DDFM = None # type: ignore
|
|
129
|
-
DDFMModel = None # type: ignore
|
|
130
|
-
load_config_ddfm = None # type: ignore
|
|
131
|
-
load_data_ddfm = None # type: ignore
|
|
132
|
-
train_ddfm = None # type: ignore
|
|
133
|
-
predict_ddfm = None # type: ignore
|
|
134
|
-
plot_ddfm = None # type: ignore
|
|
135
|
-
reset_ddfm = None # type: ignore
|
|
136
|
-
|
|
137
|
-
# Expose properties as module-level attributes
|
|
138
|
-
# Use property-like access via functions or direct attribute access
|
|
139
|
-
# Since 'config' conflicts with the config module, we'll use a different approach
|
|
140
|
-
# Users can access: dfm.get_config(), dfm.get_data(), dfm.get_result()
|
|
141
|
-
def get_config():
|
|
142
|
-
"""Get current configuration."""
|
|
143
|
-
return _dfm_instance.config
|
|
144
|
-
|
|
145
|
-
def get_data():
|
|
146
|
-
"""Get current data matrix."""
|
|
147
|
-
return _dfm_instance.data
|
|
148
|
-
|
|
149
|
-
def get_time():
|
|
150
|
-
"""Get current time index."""
|
|
151
|
-
return _dfm_instance.time
|
|
152
|
-
|
|
153
|
-
def get_result():
|
|
154
|
-
"""Get training result."""
|
|
155
|
-
return _dfm_instance.result
|
|
156
|
-
|
|
157
|
-
def get_original_data():
|
|
158
|
-
"""Get original (untransformed) data matrix."""
|
|
159
|
-
return _dfm_instance.original_data
|
|
128
|
+
from .models.dfm import DFMLinear, DFM
|
|
129
|
+
|
|
130
|
+
# DDFM high-level API and low-level model (PyTorch is mandatory)
|
|
131
|
+
from .models.ddfm import DDFM, DDFMModel
|
|
160
132
|
|
|
161
133
|
__all__ = [
|
|
162
134
|
# Core classes
|
|
163
|
-
'
|
|
135
|
+
'DFM', 'DFMLinear', 'Nowcast',
|
|
164
136
|
# Model base and implementations
|
|
165
|
-
'BaseFactorModel',
|
|
137
|
+
'BaseFactorModel',
|
|
166
138
|
# Nowcast result classes
|
|
167
139
|
'NowcastResult', 'NewsDecompResult', 'BacktestResult',
|
|
168
140
|
# Constants
|
|
169
|
-
'
|
|
141
|
+
'DEFAULT_BLOCK_NAME',
|
|
170
142
|
# Config sources
|
|
171
143
|
'ConfigSource', 'YamlSource', 'DictSource', 'HydraSource',
|
|
172
144
|
'MergedConfigSource', 'make_config_source',
|
|
173
|
-
# High-level API (module-level - recommended)
|
|
174
|
-
'load_config',
|
|
175
|
-
'load_data', 'load_pickle', 'train', 'predict', 'plot', 'reset', 'create_model',
|
|
176
|
-
'get_config', 'get_data', 'get_time', 'get_result', 'get_original_data',
|
|
177
|
-
# Convenience constructors (cleaner API)
|
|
178
|
-
'from_yaml', 'from_spec', 'from_spec_df', 'from_dict',
|
|
179
145
|
# Low-level API (functional interface - advanced usage)
|
|
180
|
-
'
|
|
181
|
-
'
|
|
182
|
-
'run_kf', 'skf', 'fis', 'miss_data',
|
|
183
|
-
'para_const', # Internal utility, kept for backward compatibility
|
|
146
|
+
'BaseResult', 'DFMResult', 'DDFMResult', 'calculate_rmse', 'diagnose_series', 'print_series_diagnosis',
|
|
147
|
+
'para_const', # Internal utility for nowcasting
|
|
184
148
|
]
|
|
185
149
|
|
|
186
|
-
#
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
150
|
+
# DDFM high-level API (PyTorch is mandatory)
|
|
151
|
+
__all__.extend([
|
|
152
|
+
'DDFM', # High-level API class
|
|
153
|
+
'DDFMModel', # Low-level implementation (used internally)
|
|
154
|
+
])
|
|
155
|
+
|
|
156
|
+
# Lightning modules (mandatory dependency)
|
|
157
|
+
__all__.extend([
|
|
158
|
+
'DFMDataModule',
|
|
159
|
+
'DFMDataset', # Dataset class (usually not needed directly)
|
|
160
|
+
'KalmanFilter', # Module class
|
|
161
|
+
'EMAlgorithm', # Module class
|
|
162
|
+
])
|
|
163
|
+
|
|
164
|
+
# Trainer classes (mandatory dependency)
|
|
165
|
+
from .trainer import DFMTrainer, DDFMTrainer
|
|
166
|
+
|
|
167
|
+
__all__.extend([
|
|
168
|
+
'DFMTrainer',
|
|
169
|
+
'DDFMTrainer',
|
|
170
|
+
])
|
|
171
|
+
|
|
193
172
|
|
dfm_python/config/__init__.py
CHANGED
|
@@ -1,35 +1,65 @@
|
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
validate_frequency, validate_transformation,
|
|
9
|
+
BaseModelConfig, DFMConfig, DDFMConfig, SeriesConfig,
|
|
10
|
+
DEFAULT_BLOCK_NAME,
|
|
12
11
|
)
|
|
13
|
-
from .
|
|
12
|
+
from .results import BaseResult, DFMResult, DDFMResult, FitParams
|
|
13
|
+
from .utils import validate_frequency, validate_transformation
|
|
14
|
+
from .adapter import (
|
|
14
15
|
ConfigSource,
|
|
15
16
|
YamlSource,
|
|
16
17
|
DictSource,
|
|
17
18
|
HydraSource,
|
|
18
19
|
MergedConfigSource,
|
|
19
20
|
make_config_source,
|
|
20
|
-
from_spec,
|
|
21
|
-
_load_config_from_dataframe,
|
|
22
|
-
|
|
21
|
+
# Note: from_spec is in models/dfm.py, not in adapter
|
|
22
|
+
# Note: Private functions (_load_config_from_dataframe, _write_series_blocks_yaml)
|
|
23
|
+
# are available from adapter module but not exported as public API
|
|
24
|
+
)
|
|
25
|
+
from .utils import (
|
|
26
|
+
FREQUENCY_HIERARCHY,
|
|
27
|
+
PERIODS_PER_YEAR,
|
|
28
|
+
get_periods_per_year,
|
|
29
|
+
get_annual_factor,
|
|
30
|
+
compute_idio_chain_lengths,
|
|
31
|
+
get_tent_weights_for_pair,
|
|
32
|
+
generate_tent_weights,
|
|
33
|
+
generate_R_mat,
|
|
34
|
+
get_aggregation_structure,
|
|
35
|
+
group_series_by_frequency,
|
|
23
36
|
)
|
|
24
37
|
|
|
25
38
|
__all__ = [
|
|
26
39
|
# Schema
|
|
27
|
-
'
|
|
28
|
-
'
|
|
40
|
+
'BaseModelConfig', 'DFMConfig', 'DDFMConfig', 'SeriesConfig',
|
|
41
|
+
'DEFAULT_BLOCK_NAME',
|
|
42
|
+
# Parameter overrides
|
|
43
|
+
'FitParams',
|
|
44
|
+
# Results
|
|
45
|
+
'BaseResult', 'DFMResult', 'DDFMResult',
|
|
46
|
+
# Utilities
|
|
29
47
|
'validate_frequency', 'validate_transformation',
|
|
30
48
|
# IO
|
|
31
49
|
'ConfigSource', 'YamlSource', 'DictSource',
|
|
32
50
|
'HydraSource', 'MergedConfigSource', 'make_config_source',
|
|
33
|
-
|
|
51
|
+
# Frequency and aggregation utilities
|
|
52
|
+
'FREQUENCY_HIERARCHY',
|
|
53
|
+
'PERIODS_PER_YEAR',
|
|
54
|
+
'get_periods_per_year',
|
|
55
|
+
'get_annual_factor',
|
|
56
|
+
'compute_idio_chain_lengths',
|
|
57
|
+
'get_tent_weights_for_pair',
|
|
58
|
+
'generate_tent_weights',
|
|
59
|
+
'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 adapter module but not exported as public API
|
|
34
64
|
]
|
|
35
65
|
|