dfm-python 0.1.5__py3-none-any.whl → 0.1.8__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 +111 -25
- dfm_python/config.py +449 -259
- dfm_python/data_loader.py +448 -152
- dfm_python/dfm.py +1616 -921
- dfm_python/dfm_api.py +328 -0
- dfm_python/kalman.py +0 -12
- dfm_python/news.py +28 -38
- dfm_python/utils/__init__.py +0 -2
- dfm_python/utils/aggregation.py +4 -11
- dfm_python/utils/data_utils.py +20 -8
- dfm_python-0.1.8.dist-info/METADATA +343 -0
- dfm_python-0.1.8.dist-info/RECORD +14 -0
- dfm_python-0.1.5.dist-info/METADATA +0 -572
- dfm_python-0.1.5.dist-info/RECORD +0 -13
- {dfm_python-0.1.5.dist-info → dfm_python-0.1.8.dist-info}/WHEEL +0 -0
- {dfm_python-0.1.5.dist-info → dfm_python-0.1.8.dist-info}/licenses/LICENSE +0 -0
dfm_python/__init__.py
CHANGED
|
@@ -1,60 +1,146 @@
|
|
|
1
1
|
"""Dynamic Factor Model (DFM) package for Python.
|
|
2
2
|
|
|
3
3
|
This package implements a comprehensive Dynamic Factor Model framework with support for:
|
|
4
|
-
- Mixed-frequency time series data (
|
|
4
|
+
- Mixed-frequency time series data (monthly, quarterly, semi-annual, annual)
|
|
5
5
|
- Clock-based synchronization of latent factors
|
|
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
9
|
- News decomposition for nowcasting
|
|
10
10
|
|
|
11
|
-
The package
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
The package implements a clock-based approach to mixed-frequency DFMs, where all latent
|
|
12
|
+
factors (global and block-level) are synchronized to a common "clock" frequency, typically
|
|
13
|
+
monthly. Lower-frequency observed variables are mapped to higher-frequency latent states
|
|
14
|
+
using deterministic tent kernels in the observation equation.
|
|
15
|
+
|
|
16
|
+
Note: Higher frequencies (daily, weekly) than the clock are not supported. If any series
|
|
17
|
+
has a frequency faster than the clock, a ValueError will be raised.
|
|
15
18
|
|
|
16
19
|
Key Features:
|
|
17
|
-
- Unified configuration system (YAML/
|
|
20
|
+
- Unified configuration system (YAML with Hydra/OmegaConf, or direct DFMConfig objects)
|
|
18
21
|
- Flexible block structure for factor modeling
|
|
19
22
|
- Robust handling of missing data
|
|
20
23
|
- Comprehensive transformation support
|
|
21
24
|
- News decomposition for forecast updates
|
|
22
25
|
|
|
23
|
-
Example:
|
|
24
|
-
>>>
|
|
26
|
+
Example (High-level API - Recommended):
|
|
27
|
+
>>> import dfm_python as dfm
|
|
28
|
+
>>> dfm.load_config('config/default.yaml')
|
|
29
|
+
>>> dfm.load_data('data/sample_data.csv')
|
|
30
|
+
>>> dfm.train()
|
|
31
|
+
>>> factors = dfm.result.Z # Direct access to results
|
|
32
|
+
|
|
33
|
+
Example (Low-level API - For advanced usage):
|
|
34
|
+
>>> from dfm_python import load_config, load_data, dfm, DFMConfig, SeriesConfig
|
|
35
|
+
>>> # Option 1: Load from YAML
|
|
25
36
|
>>> config = load_config('config.yaml')
|
|
26
|
-
>>>
|
|
37
|
+
>>> # Option 2: Create directly
|
|
38
|
+
>>> config = DFMConfig(
|
|
39
|
+
... series=[SeriesConfig(frequency='m', transformation='lin', blocks=[1], series_id='series1')],
|
|
40
|
+
... block_names=['Global']
|
|
41
|
+
... )
|
|
42
|
+
>>> X, Time, _ = load_data('data.csv', config) # or use database adapter
|
|
27
43
|
>>> result = dfm(X, config)
|
|
28
44
|
>>> factors = result.Z # Extract estimated factors
|
|
29
45
|
|
|
30
46
|
For detailed documentation, see the README.md file.
|
|
31
47
|
"""
|
|
32
48
|
|
|
33
|
-
__version__ = "0.1.
|
|
49
|
+
__version__ = "0.1.7"
|
|
34
50
|
|
|
35
|
-
from .config import DFMConfig
|
|
51
|
+
from .config import DFMConfig, SeriesConfig, BlockConfig
|
|
36
52
|
from .data_loader import (
|
|
37
|
-
|
|
53
|
+
load_config_from_yaml,
|
|
54
|
+
load_config_from_spec,
|
|
55
|
+
load_data,
|
|
56
|
+
transform_data
|
|
38
57
|
)
|
|
39
|
-
from .dfm import DFMResult, dfm, calculate_rmse
|
|
58
|
+
from .dfm import DFMResult, dfm, calculate_rmse, diagnose_series, print_series_diagnosis
|
|
40
59
|
from .kalman import run_kf, skf, fis, miss_data
|
|
41
60
|
from .news import update_nowcast, news_dfm, para_const
|
|
42
61
|
|
|
43
|
-
#
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
62
|
+
# Import high-level API
|
|
63
|
+
from .dfm_api import DFM, _dfm_instance
|
|
64
|
+
|
|
65
|
+
# Module-level API: expose singleton instance methods and properties
|
|
66
|
+
# This allows: import dfm_python as dfm; dfm.load_config(...); dfm.result
|
|
67
|
+
def load_config(config):
|
|
68
|
+
"""Load configuration (module-level convenience function)."""
|
|
69
|
+
return _dfm_instance.load_config(config)
|
|
70
|
+
|
|
71
|
+
def load_config_from_yaml(yaml_path):
|
|
72
|
+
"""Load configuration from YAML (module-level convenience function)."""
|
|
73
|
+
return _dfm_instance.load_config_from_yaml(yaml_path)
|
|
74
|
+
|
|
75
|
+
def load_config_from_spec(spec_path):
|
|
76
|
+
"""Load configuration from spec CSV (module-level convenience function)."""
|
|
77
|
+
return _dfm_instance.load_config_from_spec(spec_path)
|
|
78
|
+
|
|
79
|
+
def load_data(data_path=None, data=None, **kwargs):
|
|
80
|
+
"""Load data (module-level convenience function)."""
|
|
81
|
+
return _dfm_instance.load_data(data_path=data_path, data=data, **kwargs)
|
|
82
|
+
|
|
83
|
+
def train(threshold=None, max_iter=None, **kwargs):
|
|
84
|
+
"""Train the model (module-level convenience function)."""
|
|
85
|
+
return _dfm_instance.train(threshold=threshold, max_iter=max_iter, **kwargs)
|
|
86
|
+
|
|
87
|
+
def reset():
|
|
88
|
+
"""Reset state (module-level convenience function)."""
|
|
89
|
+
return _dfm_instance.reset()
|
|
90
|
+
|
|
91
|
+
# Expose properties as module-level attributes
|
|
92
|
+
# Use property-like access via functions or direct attribute access
|
|
93
|
+
# Since 'config' conflicts with the config module, we'll use a different approach
|
|
94
|
+
# Users can access: dfm.get_config(), dfm.get_data(), dfm.get_result()
|
|
95
|
+
def get_config():
|
|
96
|
+
"""Get current configuration."""
|
|
97
|
+
return _dfm_instance.config
|
|
98
|
+
|
|
99
|
+
def get_data():
|
|
100
|
+
"""Get current data matrix."""
|
|
101
|
+
return _dfm_instance.data
|
|
102
|
+
|
|
103
|
+
def get_time():
|
|
104
|
+
"""Get current time index."""
|
|
105
|
+
return _dfm_instance.time
|
|
106
|
+
|
|
107
|
+
def get_result():
|
|
108
|
+
"""Get training result."""
|
|
109
|
+
return _dfm_instance.result
|
|
110
|
+
|
|
111
|
+
def get_original_data():
|
|
112
|
+
"""Get original (untransformed) data matrix."""
|
|
113
|
+
return _dfm_instance.original_data
|
|
114
|
+
|
|
115
|
+
# For direct attribute access, we'll use __getattr__ but handle config module conflict
|
|
116
|
+
|
|
117
|
+
def __getattr__(name):
|
|
118
|
+
"""Allow access to DFM instance properties at module level."""
|
|
119
|
+
# Handle special cases that conflict with submodules
|
|
120
|
+
if name == 'config' and _dfm_instance.config is not None:
|
|
121
|
+
return _dfm_instance.config
|
|
122
|
+
elif name == 'data':
|
|
123
|
+
return _dfm_instance.data
|
|
124
|
+
elif name == 'time':
|
|
125
|
+
return _dfm_instance.time
|
|
126
|
+
elif name == 'result':
|
|
127
|
+
return _dfm_instance.result
|
|
128
|
+
elif name == 'original_data':
|
|
129
|
+
return _dfm_instance.original_data
|
|
130
|
+
# For other attributes, try normal import
|
|
131
|
+
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
|
|
47
132
|
|
|
48
133
|
__all__ = [
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
'load_config', 'load_config_from_yaml', '
|
|
53
|
-
'load_data', '
|
|
54
|
-
'
|
|
134
|
+
# Core classes
|
|
135
|
+
'DFMConfig', 'SeriesConfig', 'BlockConfig', 'DFM',
|
|
136
|
+
# High-level API (module-level - recommended)
|
|
137
|
+
'load_config', 'load_config_from_yaml', 'load_config_from_spec',
|
|
138
|
+
'load_data', 'train', 'reset',
|
|
139
|
+
'get_config', 'get_data', 'get_time', 'get_result', 'get_original_data',
|
|
140
|
+
# Low-level API (functional interface - advanced usage)
|
|
141
|
+
'transform_data',
|
|
142
|
+
'DFMResult', 'dfm', 'calculate_rmse', 'diagnose_series', 'print_series_diagnosis',
|
|
55
143
|
'run_kf', 'skf', 'fis', 'miss_data',
|
|
56
144
|
'update_nowcast', 'news_dfm', 'para_const',
|
|
57
|
-
# Deprecated aliases
|
|
58
|
-
'ModelSpec', 'load_spec',
|
|
59
145
|
]
|
|
60
146
|
|