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 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 (daily, weekly, monthly, quarterly, semi-annual, annual)
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 follows the FRBNY (Federal Reserve Bank of New York) approach to mixed-frequency
12
- DFMs, where all latent factors (global and block-level) are synchronized to a common "clock"
13
- frequency, typically monthly. Lower-frequency observed variables are mapped to higher-frequency
14
- latent states using deterministic tent kernels in the observation equation.
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/CSV)
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
- >>> from dfm_python import load_config, load_data, dfm
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
- >>> X, Time, _ = load_data('data.csv', config)
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.4"
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
- load_config, load_config_from_yaml, load_config_from_csv, load_data, transform_data
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
- # Backward compatibility aliases
44
- ModelConfig = DFMConfig # Deprecated: ModelConfig merged into DFMConfig
45
- ModelSpec = DFMConfig # Deprecated: use DFMConfig
46
- load_spec = load_config # Deprecated: use load_config
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
- 'DFMConfig',
50
- # Backward compatibility
51
- 'ModelConfig', # Alias for DFMConfig
52
- 'load_config', 'load_config_from_yaml', 'load_config_from_csv',
53
- 'load_data', 'transform_data',
54
- 'DFMResult', 'dfm', 'calculate_rmse',
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