dfm-python 0.5.55__py3-none-any.whl → 0.5.57__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 +19 -49
- dfm_python/config/__init__.py +7 -12
- dfm_python/config/adapter.py +63 -7
- dfm_python/config/constants.py +149 -10
- dfm_python/config/schema/__init__.py +8 -6
- dfm_python/config/schema/block.py +61 -3
- dfm_python/config/schema/model.py +40 -11
- dfm_python/config/schema/params.py +279 -0
- dfm_python/config/schema/results.py +121 -92
- dfm_python/config/types.py +57 -28
- dfm_python/dataset/__init__.py +8 -47
- dfm_python/dataset/ddfm_dataset.py +393 -0
- dfm_python/{datamodule/dfm_dm.py → dataset/dfm_dataset.py} +263 -92
- dfm_python/dataset/time.py +97 -0
- dfm_python/decoder/__init__.py +3 -1
- dfm_python/decoder/base.py +78 -0
- dfm_python/decoder/linear.py +63 -59
- dfm_python/decoder/mlp.py +117 -126
- dfm_python/encoder/__init__.py +9 -9
- dfm_python/encoder/pca.py +6 -5
- dfm_python/encoder/simple_autoencoder.py +292 -0
- dfm_python/functional/__init__.py +7 -9
- dfm_python/functional/dfm_block.py +65 -14
- dfm_python/functional/em.py +580 -223
- dfm_python/logger/__init__.py +21 -11
- dfm_python/logger/inference_logger.py +41 -29
- dfm_python/logger/logger.py +129 -5
- dfm_python/logger/train_logger.py +81 -68
- dfm_python/models/__init__.py +2 -10
- dfm_python/models/base.py +51 -230
- dfm_python/models/ddfm.py +809 -1715
- dfm_python/models/dfm.py +576 -384
- dfm_python/numeric/estimator.py +281 -52
- dfm_python/numeric/stability.py +133 -167
- dfm_python/numeric/statistic.py +353 -0
- dfm_python/numeric/tent.py +16 -6
- dfm_python/numeric/validator.py +159 -8
- dfm_python/ssm/__init__.py +13 -3
- dfm_python/ssm/kalman.py +274 -142
- dfm_python/utils/__init__.py +20 -38
- dfm_python/utils/checkpoint.py +295 -0
- dfm_python/utils/helper.py +62 -152
- dfm_python/utils/loss.py +100 -0
- dfm_python/utils/misc.py +73 -150
- dfm_python/utils/validation.py +4 -71
- {dfm_python-0.5.55.dist-info → dfm_python-0.5.57.dist-info}/METADATA +4 -5
- dfm_python-0.5.57.dist-info/RECORD +52 -0
- dfm_python/datamodule/__init__.py +0 -31
- dfm_python/datamodule/base.py +0 -618
- dfm_python/datamodule/ddfm_dm.py +0 -276
- dfm_python/datamodule/kdfm_dm.py +0 -180
- dfm_python/dataset/dataloader.py +0 -142
- dfm_python/dataset/dataset.py +0 -158
- dfm_python/dataset/process.py +0 -435
- dfm_python/encoder/simple_encoder.py +0 -474
- dfm_python/encoder/variational_encoder.py +0 -0
- dfm_python/functional/irf.py +0 -305
- dfm_python/functional/krylov.py +0 -124
- dfm_python/models/kdfm.py +0 -1968
- dfm_python/ssm/arma.py +0 -0
- dfm_python/ssm/companion.py +0 -995
- dfm_python/ssm/structural.py +0 -298
- dfm_python/trainer/__init__.py +0 -683
- dfm_python/trainer/ddfm.py +0 -656
- dfm_python/trainer/dfm.py +0 -154
- dfm_python/trainer/kdfm.py +0 -137
- dfm_python/utils/common.py +0 -403
- dfm_python/utils/tensor_utils.py +0 -199
- dfm_python-0.5.55.dist-info/RECORD +0 -66
- dfm_python-0.5.55.dist-info/licenses/LICENSE +0 -21
- {dfm_python-0.5.55.dist-info → dfm_python-0.5.57.dist-info}/WHEEL +0 -0
dfm_python/__init__.py
CHANGED
|
@@ -23,40 +23,36 @@ Key Features:
|
|
|
23
23
|
- Robust handling of missing data (internal spline interpolation)
|
|
24
24
|
- Automatic standardization and data clipping
|
|
25
25
|
|
|
26
|
-
Example
|
|
27
|
-
>>> from dfm_python import DFM,
|
|
26
|
+
Example:
|
|
27
|
+
>>> from dfm_python import DFM, DFMDataset
|
|
28
28
|
>>> import pandas as pd
|
|
29
29
|
>>>
|
|
30
30
|
>>> # Step 1: Load and preprocess data
|
|
31
31
|
>>> df = pd.read_csv('data/your_data.csv')
|
|
32
32
|
>>> df_processed = df[[col for col in df.columns if col != 'date']]
|
|
33
33
|
>>>
|
|
34
|
-
>>> # Step 2: Create
|
|
35
|
-
>>>
|
|
36
|
-
>>> dm.setup()
|
|
34
|
+
>>> # Step 2: Create Dataset
|
|
35
|
+
>>> dataset = DFMDataset(config_path='config/default.yaml', data=df_processed)
|
|
37
36
|
>>>
|
|
38
37
|
>>> # Step 3: Create model and load config
|
|
39
38
|
>>> model = DFM()
|
|
40
39
|
>>> model.load_config('config/default.yaml')
|
|
41
40
|
>>>
|
|
42
|
-
>>> # Step 4:
|
|
43
|
-
>>>
|
|
44
|
-
>>> trainer.fit(model, dm)
|
|
41
|
+
>>> # Step 4: Fit model
|
|
42
|
+
>>> model.fit(X=dataset.get_processed_data(), dataset=dataset)
|
|
45
43
|
>>>
|
|
46
44
|
>>> # Step 5: Predict
|
|
47
45
|
>>> Xf, Zf = model.predict(horizon=6)
|
|
48
46
|
>>>
|
|
49
|
-
>>> # Or use DDFM
|
|
50
|
-
>>> from dfm_python import DDFM,
|
|
47
|
+
>>> # Or use DDFM
|
|
48
|
+
>>> from dfm_python import DDFM, DDFMDataset
|
|
51
49
|
>>>
|
|
52
|
-
>>>
|
|
53
|
-
>>> dm_ddfm.setup()
|
|
50
|
+
>>> dataset_ddfm = DDFMDataset(config_path='config/default.yaml', data=df_processed)
|
|
54
51
|
>>>
|
|
55
52
|
>>> ddfm_model = DDFM(encoder_layers=[64, 32], num_factors=2)
|
|
56
53
|
>>> ddfm_model.load_config('config/default.yaml')
|
|
57
54
|
>>>
|
|
58
|
-
>>>
|
|
59
|
-
>>> trainer_ddfm.fit(ddfm_model, dm_ddfm)
|
|
55
|
+
>>> ddfm_model.train(dataset=dataset_ddfm)
|
|
60
56
|
>>> Xf, Zf = ddfm_model.predict(horizon=6)
|
|
61
57
|
|
|
62
58
|
Note: DFMConfig uses frequency dict to specify series (column names -> frequencies).
|
|
@@ -65,7 +61,7 @@ Note: DFMConfig uses frequency dict to specify series (column names -> frequenci
|
|
|
65
61
|
For detailed documentation, see the README.md file and the tutorial notebooks/scripts.
|
|
66
62
|
"""
|
|
67
63
|
|
|
68
|
-
__version__ = "0.5.
|
|
64
|
+
__version__ = "0.5.56"
|
|
69
65
|
|
|
70
66
|
# ============================================================================
|
|
71
67
|
# PUBLIC API DEFINITION
|
|
@@ -92,20 +88,15 @@ from .config import (
|
|
|
92
88
|
from .config import DFMConfig
|
|
93
89
|
|
|
94
90
|
# Results
|
|
95
|
-
from .config import DFMResult, DDFMResult,
|
|
91
|
+
from .config import DFMResult, DDFMResult, BaseResult
|
|
96
92
|
|
|
97
93
|
# Utilities (from utils/ subpackage)
|
|
98
94
|
from .utils.metric import calculate_rmse
|
|
99
95
|
|
|
100
|
-
#
|
|
96
|
+
# Dataset classes
|
|
101
97
|
# Users can import these directly from dfm_python
|
|
102
|
-
from .
|
|
103
|
-
|
|
104
|
-
DDFMDataModule, # DDFM-specific DataModule
|
|
105
|
-
KDFMDataModule, # KDFM-specific DataModule
|
|
106
|
-
DDFMDataset, # DDFM Dataset class (usually not needed directly)
|
|
107
|
-
KDFMDataset, # KDFM Dataset class (usually not needed directly)
|
|
108
|
-
)
|
|
98
|
+
from .dataset.dfm_dataset import DFMDataset
|
|
99
|
+
from .dataset.ddfm_dataset import DDFMDataset
|
|
109
100
|
|
|
110
101
|
# Model implementations
|
|
111
102
|
from .models.base import BaseFactorModel
|
|
@@ -114,9 +105,6 @@ from .models.dfm import DFM
|
|
|
114
105
|
# DDFM high-level API (PyTorch is mandatory)
|
|
115
106
|
from .models.ddfm import DDFM
|
|
116
107
|
|
|
117
|
-
# KDFM high-level API
|
|
118
|
-
from .models.kdfm import KDFM
|
|
119
|
-
|
|
120
108
|
__all__ = [
|
|
121
109
|
# Core classes
|
|
122
110
|
'DFM',
|
|
@@ -126,7 +114,7 @@ __all__ = [
|
|
|
126
114
|
'ConfigSource', 'YamlSource',
|
|
127
115
|
'make_config_source',
|
|
128
116
|
# Low-level API (functional interface - advanced usage)
|
|
129
|
-
'BaseResult', 'DFMResult', 'DDFMResult', '
|
|
117
|
+
'BaseResult', 'DFMResult', 'DDFMResult', 'calculate_rmse',
|
|
130
118
|
]
|
|
131
119
|
|
|
132
120
|
# DDFM high-level API (PyTorch is mandatory)
|
|
@@ -134,27 +122,9 @@ __all__.extend([
|
|
|
134
122
|
'DDFM', # High-level API class
|
|
135
123
|
])
|
|
136
124
|
|
|
137
|
-
#
|
|
138
|
-
__all__.extend([
|
|
139
|
-
'KDFM', # High-level API class
|
|
140
|
-
])
|
|
141
|
-
|
|
142
|
-
# Lightning modules (mandatory dependency)
|
|
125
|
+
# Dataset classes
|
|
143
126
|
__all__.extend([
|
|
144
|
-
'
|
|
145
|
-
'
|
|
146
|
-
'KDFMDataModule', # KDFM-specific DataModule
|
|
147
|
-
'DDFMDataset', # DDFM Dataset class (usually not needed directly)
|
|
148
|
-
'KDFMDataset', # KDFM Dataset class (usually not needed directly)
|
|
127
|
+
'DFMDataset', # DFM Dataset class
|
|
128
|
+
'DDFMDataset', # DDFM Dataset class
|
|
149
129
|
])
|
|
150
130
|
|
|
151
|
-
# Trainer classes (mandatory dependency)
|
|
152
|
-
from .trainer import DFMTrainer, DDFMTrainer, KDFMTrainer
|
|
153
|
-
|
|
154
|
-
__all__.extend([
|
|
155
|
-
'DFMTrainer',
|
|
156
|
-
'DDFMTrainer',
|
|
157
|
-
'KDFMTrainer',
|
|
158
|
-
])
|
|
159
|
-
|
|
160
|
-
|
dfm_python/config/__init__.py
CHANGED
|
@@ -8,8 +8,9 @@ Note: Series are specified via frequency dict mapping column names to frequencie
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
from .schema import (
|
|
11
|
-
BaseModelConfig, DFMConfig, DDFMConfig,
|
|
12
|
-
BaseResult, DFMResult, DDFMResult,
|
|
11
|
+
BaseModelConfig, DFMConfig, DDFMConfig,
|
|
12
|
+
BaseResult, DFMResult, DDFMResult,
|
|
13
|
+
DFMStateSpaceParams, DDFMStateSpaceParams,
|
|
13
14
|
)
|
|
14
15
|
# DEFAULT_BLOCK_NAME is imported lazily where needed to avoid circular imports
|
|
15
16
|
from .constants import (
|
|
@@ -45,8 +46,6 @@ from .types import (
|
|
|
45
46
|
ForecastResult,
|
|
46
47
|
CoefficientMatrix,
|
|
47
48
|
CovarianceMatrix,
|
|
48
|
-
IRFArray,
|
|
49
|
-
CompanionMatrix,
|
|
50
49
|
SeriesID,
|
|
51
50
|
Frequency,
|
|
52
51
|
DatasetName,
|
|
@@ -57,7 +56,6 @@ from .types import (
|
|
|
57
56
|
ResultDict,
|
|
58
57
|
ForecastDict,
|
|
59
58
|
MetricsDict,
|
|
60
|
-
IRFResultDict,
|
|
61
59
|
CheckpointDict,
|
|
62
60
|
ConfigDict,
|
|
63
61
|
Device,
|
|
@@ -105,11 +103,11 @@ __all__ = [
|
|
|
105
103
|
'BaseModelConfig', 'BaseResult',
|
|
106
104
|
# 'DEFAULT_BLOCK_NAME', # Removed to avoid circular import - import directly from functional.dfm_block
|
|
107
105
|
# Model-specific configs (from schema.py)
|
|
108
|
-
'DFMConfig', 'DDFMConfig',
|
|
109
|
-
#
|
|
110
|
-
'
|
|
106
|
+
'DFMConfig', 'DDFMConfig',
|
|
107
|
+
# State-space parameters
|
|
108
|
+
'DFMStateSpaceParams', 'DDFMStateSpaceParams',
|
|
111
109
|
# Model-specific results (from results.py)
|
|
112
|
-
'DFMResult', 'DDFMResult',
|
|
110
|
+
'DFMResult', 'DDFMResult',
|
|
113
111
|
# Utilities
|
|
114
112
|
'validate_frequency',
|
|
115
113
|
# IO
|
|
@@ -137,8 +135,6 @@ __all__ = [
|
|
|
137
135
|
'ForecastResult',
|
|
138
136
|
'CoefficientMatrix',
|
|
139
137
|
'CovarianceMatrix',
|
|
140
|
-
'IRFArray',
|
|
141
|
-
'CompanionMatrix',
|
|
142
138
|
'SeriesID',
|
|
143
139
|
'Frequency',
|
|
144
140
|
'DatasetName',
|
|
@@ -149,7 +145,6 @@ __all__ = [
|
|
|
149
145
|
'ResultDict',
|
|
150
146
|
'ForecastDict',
|
|
151
147
|
'MetricsDict',
|
|
152
|
-
'IRFResultDict',
|
|
153
148
|
'CheckpointDict',
|
|
154
149
|
'ConfigDict',
|
|
155
150
|
'Device',
|
dfm_python/config/adapter.py
CHANGED
|
@@ -118,7 +118,12 @@ def _extract_frequency_dict(
|
|
|
118
118
|
data: Dict[str, Any],
|
|
119
119
|
clock: str = DEFAULT_CLOCK_FREQUENCY
|
|
120
120
|
) -> Optional[Dict[str, str]]:
|
|
121
|
-
"""Extract frequency dict from data, handling
|
|
121
|
+
"""Extract frequency dict from data, handling multiple formats.
|
|
122
|
+
|
|
123
|
+
Supports:
|
|
124
|
+
1. Grouped format: {'w': [series1, series2, ...], 'm': [series3, ...]}
|
|
125
|
+
2. Individual format: {'series1': 'w', 'series2': 'm', ...}
|
|
126
|
+
3. Legacy format: {'series': [{'series_id': ..., 'frequency': ...}, ...]}
|
|
122
127
|
|
|
123
128
|
Parameters
|
|
124
129
|
----------
|
|
@@ -132,12 +137,63 @@ def _extract_frequency_dict(
|
|
|
132
137
|
Optional[Dict[str, str]]
|
|
133
138
|
Frequency dict mapping column names to frequencies, or None if not found
|
|
134
139
|
"""
|
|
135
|
-
if 'frequency' in data:
|
|
136
|
-
#
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
140
|
+
if 'frequency' not in data:
|
|
141
|
+
# Legacy: check for 'series' key
|
|
142
|
+
if 'series' in data:
|
|
143
|
+
return _convert_series_to_frequency_dict(data['series'], clock)
|
|
144
|
+
return None
|
|
145
|
+
|
|
146
|
+
freq_data = data['frequency']
|
|
147
|
+
|
|
148
|
+
# Check if it's in grouped format: {'w': [...], 'm': [...]}
|
|
149
|
+
if _is_dict_like(freq_data):
|
|
150
|
+
from .constants import VALID_FREQUENCIES
|
|
151
|
+
|
|
152
|
+
# Check if all keys are valid frequency codes (grouped format)
|
|
153
|
+
keys_are_frequencies = all(
|
|
154
|
+
isinstance(k, str) and k in VALID_FREQUENCIES
|
|
155
|
+
for k in freq_data.keys()
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
# Check if values are lists (grouped format)
|
|
159
|
+
values_are_lists = all(
|
|
160
|
+
isinstance(v, (list, tuple)) for v in freq_data.values()
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
if keys_are_frequencies and values_are_lists:
|
|
164
|
+
# Grouped format: convert to individual format
|
|
165
|
+
result = {}
|
|
166
|
+
for freq, series_list in freq_data.items():
|
|
167
|
+
if not isinstance(series_list, (list, tuple)):
|
|
168
|
+
_raise_config_error(
|
|
169
|
+
f"Frequency '{freq}' must map to a list of series names, got {type(series_list)}"
|
|
170
|
+
)
|
|
171
|
+
for series_name in series_list:
|
|
172
|
+
if not isinstance(series_name, str):
|
|
173
|
+
_raise_config_error(
|
|
174
|
+
f"Series names must be strings, got {type(series_name)} in frequency '{freq}'"
|
|
175
|
+
)
|
|
176
|
+
if series_name in result:
|
|
177
|
+
_raise_config_error(
|
|
178
|
+
f"Series '{series_name}' appears in multiple frequency groups"
|
|
179
|
+
)
|
|
180
|
+
result[series_name] = freq
|
|
181
|
+
return result
|
|
182
|
+
else:
|
|
183
|
+
# Individual format: already in correct format, validate structure
|
|
184
|
+
result = {}
|
|
185
|
+
for series_name, freq in freq_data.items():
|
|
186
|
+
if not isinstance(series_name, str):
|
|
187
|
+
_raise_config_error(
|
|
188
|
+
f"Frequency dict keys must be strings (series names), got {type(series_name)}"
|
|
189
|
+
)
|
|
190
|
+
if not isinstance(freq, str):
|
|
191
|
+
_raise_config_error(
|
|
192
|
+
f"Frequency dict values must be strings (frequency codes), got {type(freq)} for series '{series_name}'"
|
|
193
|
+
)
|
|
194
|
+
result[series_name] = freq
|
|
195
|
+
return result
|
|
196
|
+
|
|
141
197
|
return None
|
|
142
198
|
|
|
143
199
|
|
dfm_python/config/constants.py
CHANGED
|
@@ -23,15 +23,17 @@ DEFAULT_MIN_DELTA = 1e-6 # Minimum change for improvement
|
|
|
23
23
|
# ============================================================================
|
|
24
24
|
|
|
25
25
|
# Minimum eigenvalues and variances
|
|
26
|
-
MIN_EIGENVALUE = 1e-
|
|
26
|
+
MIN_EIGENVALUE = 1e-6 # Minimum eigenvalue for positive definite matrices (increased from 1e-8 for better conditioning)
|
|
27
27
|
MIN_DIAGONAL_VARIANCE = 1e-8 # Minimum variance for diagonal elements
|
|
28
28
|
MIN_OBSERVATION_NOISE = 1e-4 # Minimum observation noise for measurement error (used in EM updates)
|
|
29
|
+
DEFAULT_DDFM_OBSERVATION_NOISE = 1e-15 # Default observation noise for DDFM state-space (matches original TensorFlow)
|
|
29
30
|
MIN_FACTOR_VARIANCE = 1e-10 # Minimum variance for factors
|
|
30
31
|
MIN_STD = 1e-8 # Minimum standard deviation
|
|
32
|
+
MIN_STD_FOR_SCALE_CHECK = 1e-10 # Minimum standard deviation for scale ratio computation (more lenient than MIN_STD)
|
|
31
33
|
DEFAULT_VARIANCE_FALLBACK = 1.0 # Default variance fallback value for numerical stability
|
|
32
34
|
|
|
33
35
|
# Maximum eigenvalues
|
|
34
|
-
MAX_EIGENVALUE =
|
|
36
|
+
MAX_EIGENVALUE = 1e3 # Maximum eigenvalue cap (reduced to 1e3 to improve condition number: 1e3/1e-6 = 1e9)
|
|
35
37
|
|
|
36
38
|
# Eigenvalue stability thresholds
|
|
37
39
|
DEFAULT_EIGENVALUE_MAX_MAGNITUDE = 1.0 # Default maximum eigenvalue magnitude for stability checks
|
|
@@ -44,8 +46,11 @@ DEFAULT_CLEAN_INF = MAX_EIGENVALUE # Default value for Inf replacement in clean
|
|
|
44
46
|
# Identity matrix defaults
|
|
45
47
|
DEFAULT_IDENTITY_SCALE = 1.0 # Default scale for create_scaled_identity(n, 1.0)
|
|
46
48
|
DEFAULT_ZERO_VALUE = 0.0 # Default zero value for explicit zero assignments
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
DEFAULT_INF_VALUE = float('inf') # Default infinity value for loss/scale comparisons
|
|
50
|
+
DEFAULT_XAVIER_GAIN = 1.0 # Default gain for Xavier initialization (matches TensorFlow GlorotNormal)
|
|
51
|
+
DEFAULT_OUTPUT_LAYER_GAIN = 1.0 # Default gain for output layer Xavier initialization (matches original TensorFlow DDFM GlorotNormal for all layers)
|
|
52
|
+
# NOTE: Original TensorFlow DDFM uses GlorotNormal (gain=1.0) for all layers including output layer.
|
|
53
|
+
# Updated to match original TensorFlow behavior to address training divergence (encoder weights too small, near-zero factors).
|
|
49
54
|
|
|
50
55
|
# Companion matrix initialization defaults
|
|
51
56
|
DEFAULT_INIT_SCALE = 0.01 # Default initialization scale for companion matrix B and C matrices
|
|
@@ -59,6 +64,41 @@ DEFAULT_REGULARIZATION = 1e-6 # Default regularization value
|
|
|
59
64
|
DEFAULT_CLIP_THRESHOLD = 10.0 # Default clipping threshold (in standard deviations)
|
|
60
65
|
DEFAULT_DATA_CLIP_THRESHOLD = 100.0 # Default data clipping threshold
|
|
61
66
|
|
|
67
|
+
# Scale validation thresholds (for DDFM scale alignment checks)
|
|
68
|
+
DEFAULT_SCALE_RATIO_MAX = 10.0 # Maximum acceptable scale ratio (prediction std / data std)
|
|
69
|
+
DEFAULT_SCALE_RATIO_MIN = 0.1 # Minimum acceptable scale ratio (prediction std / data std)
|
|
70
|
+
DEFAULT_STANDARDIZATION_MEAN_THRESHOLD = 0.1 # Maximum acceptable absolute mean for standardized data (mean should be ≈0)
|
|
71
|
+
DEFAULT_STANDARDIZATION_STD_MIN = 0.1 # Minimum acceptable std for standardized data (std should be ≈1)
|
|
72
|
+
DEFAULT_STANDARDIZATION_STD_MAX = 10.0 # Maximum acceptable std for standardized data (std should be ≈1)
|
|
73
|
+
DEFAULT_STANDARDIZED_TARGET_STD = 1.0 # Target std for standardized data (std should be ≈1.0 for StandardScaler)
|
|
74
|
+
|
|
75
|
+
# Variance collapse diagnostics thresholds (for DDFM variance collapse detection)
|
|
76
|
+
DEFAULT_VARIANCE_COLLAPSE_THRESHOLD = 0.1 # Prediction std threshold for variance collapse detection (std < 0.1 indicates collapse)
|
|
77
|
+
DEFAULT_FACTOR_COLLAPSE_THRESHOLD = 0.01 # Factor magnitude threshold for factor collapse detection (|mean| < 0.01 indicates collapse)
|
|
78
|
+
DEFAULT_BATCHNORM_SUPPRESSION_THRESHOLD = 0.01 # BatchNorm running_var threshold for signal suppression detection (var < 0.01 indicates suppression)
|
|
79
|
+
DEFAULT_TIMESTEP_COLLAPSE_THRESHOLD = 0.1 # Per-time-step std threshold for localized collapse detection (std < 0.1 indicates collapse)
|
|
80
|
+
DEFAULT_TIMESTEP_COLLAPSE_RATIO_THRESHOLD = 0.5 # Ratio threshold for localized collapse (ratio > 0.5 indicates widespread collapse)
|
|
81
|
+
DEFAULT_EXPECTED_FACTOR_MAGNITUDE_MIN = 0.1 # Expected minimum factor magnitude (for warning messages)
|
|
82
|
+
DEFAULT_EXPECTED_FACTOR_MAGNITUDE_MAX = 1.0 # Expected maximum factor magnitude (for warning messages)
|
|
83
|
+
|
|
84
|
+
# DDFM reproduction target values (for debugging and diagnostics)
|
|
85
|
+
DEFAULT_TARGET_PREDICTION_STD = 1.0 # Target prediction std for standardized data (should be ~1.0 for StandardScaler)
|
|
86
|
+
DEFAULT_VARIANCE_COLLAPSE_STD = 0.03 # Observed variance collapse std (std ~0.03 vs target ~1.0)
|
|
87
|
+
DEFAULT_TARGET_CONVERGENCE_ITERATIONS = 10 # Target convergence iterations for exchange_rate dataset (TensorFlow reference)
|
|
88
|
+
DEFAULT_TARGET_DDFM_LOSS = 0.56 # Target DDFM training loss for exchange_rate dataset (TensorFlow reference)
|
|
89
|
+
DEFAULT_DDFM_LOSS_MULTIPLIER = 1.8 # Current loss multiplier vs target (1.00 vs 0.56 = 1.8x)
|
|
90
|
+
|
|
91
|
+
# Logging precision constants
|
|
92
|
+
DEFAULT_SCALE_LOG_PRECISION = 6 # Default precision for scale logging format strings (e.g., .6f)
|
|
93
|
+
DEFAULT_TIME_LOG_PRECISION = 2 # Default precision for time logging format strings (e.g., .2f)
|
|
94
|
+
DEFAULT_LOSS_LOG_PRECISION = 6 # Default precision for loss/delta logging format strings (e.g., .6f)
|
|
95
|
+
|
|
96
|
+
# Time conversion constants
|
|
97
|
+
SECONDS_PER_MINUTE = 60 # Seconds per minute (for time conversion)
|
|
98
|
+
|
|
99
|
+
# Logging level constants
|
|
100
|
+
LOGGING_DEBUG_LEVEL = 10 # logging.DEBUG level for conditional checks
|
|
101
|
+
|
|
62
102
|
# ============================================================================
|
|
63
103
|
# Training Defaults
|
|
64
104
|
# ============================================================================
|
|
@@ -68,15 +108,41 @@ DEFAULT_MAX_ITER = 100 # Default maximum EM iterations (general)
|
|
|
68
108
|
DEFAULT_EM_MAX_ITER = 5000 # Default maximum EM iterations (DFM-specific)
|
|
69
109
|
DEFAULT_MAX_EPOCHS = 100 # Default maximum training epochs
|
|
70
110
|
DEFAULT_MAX_MCMC_ITER = 200 # Default maximum MCMC iterations
|
|
111
|
+
DEFAULT_N_MC_SAMPLES = 10 # Default number of MC samples per MCMC iteration for DDFM denoising training (matches original TensorFlow epochs=10 default, per experiment/config/model/ddfm.yaml)
|
|
112
|
+
DEFAULT_FACTOR_ORDER = 1 # Default factor order for DDFM (AR(1) dynamics)
|
|
113
|
+
DEFAULT_AR_ORDER_2 = 2 # Default AR order 2 for DDFM forecast (AR(2) dynamics)
|
|
71
114
|
|
|
72
115
|
# Batch size defaults
|
|
73
116
|
DEFAULT_BATCH_SIZE = 32 # Default batch size for neural networks
|
|
74
|
-
|
|
117
|
+
DEFAULT_DDFM_WINDOW_SIZE = 100 # Default window size (time-step batch size) for DDFM
|
|
118
|
+
DEFAULT_DDFM_BATCH_SIZE = 100 # Default batch size for DDFM (matches original TensorFlow batch_size=100)
|
|
119
|
+
|
|
120
|
+
# DDFM target interpolation defaults
|
|
121
|
+
DEFAULT_MIN_TARGET_INTERPOLATE_RATIO = 0.3 # Default minimum target interpolate ratio threshold for DDFM (ratio of missing target values above which interpolation is skipped)
|
|
122
|
+
|
|
123
|
+
# MCMC training defaults (for DDFM sequential MC processing)
|
|
124
|
+
DEFAULT_MCMC_EPOCHS = 1 # Default epochs per MC sample (MCMC training pattern: one epoch per MC sample)
|
|
125
|
+
DEFAULT_MCMC_VERBOSE = 0 # Default verbosity for MCMC training (silent training)
|
|
126
|
+
|
|
127
|
+
# Placeholder defaults (for DDFM placeholder MC dataset)
|
|
128
|
+
DEFAULT_PLACEHOLDER_MC_SAMPLES = 1 # Minimal MC samples for placeholder dataset (replaced after on_train_start)
|
|
129
|
+
DEFAULT_PLACEHOLDER_DATA_SHAPE_T = 100 # Default time steps for placeholder data shape
|
|
130
|
+
DEFAULT_PLACEHOLDER_DATA_SHAPE_N = 10 # Default number of series for placeholder data shape
|
|
131
|
+
DEFAULT_PLACEHOLDER_SEED = 42 # Seed for placeholder random state (common test value, placeholder gets replaced)
|
|
132
|
+
DEFAULT_NUM_WORKERS = 0 # Default number of workers for DataLoader (0 = single-threaded)
|
|
133
|
+
DEFAULT_CUDA_DEVICE_INDEX = 0 # Default CUDA device index for GPU operations (0 = first GPU)
|
|
134
|
+
|
|
135
|
+
# Initialization sample size defaults
|
|
136
|
+
DEFAULT_KDFM_INIT_SAMPLE_SIZE = 100 # Default sample size for KDFM initialization (first N rows used for initialize_from_data)
|
|
75
137
|
|
|
76
138
|
# Learning rate defaults
|
|
77
139
|
DEFAULT_LEARNING_RATE = 0.001 # Default learning rate
|
|
78
140
|
DEFAULT_DDFM_LEARNING_RATE = 0.005 # Default learning rate for DDFM
|
|
79
141
|
|
|
142
|
+
# Autoencoder training defaults (matches original TensorFlow pattern)
|
|
143
|
+
DEFAULT_AUTOENCODER_FIT_EPOCHS = 1 # Number of epochs per MC sample (matches original TensorFlow: epochs=1 per autoencoder.fit() call)
|
|
144
|
+
DEFAULT_AUTOENCODER_FIT_VERBOSE = 0 # Verbosity level for autoencoder.fit() (0 = silent, matches original TensorFlow verbose=0)
|
|
145
|
+
|
|
80
146
|
# Gradient clipping
|
|
81
147
|
DEFAULT_GRAD_CLIP_VAL = 1.0 # Default gradient clipping value
|
|
82
148
|
|
|
@@ -86,6 +152,22 @@ DEFAULT_WEIGHT_DECAY = 0.0 # Default weight decay (L2 regularization)
|
|
|
86
152
|
# Learning rate decay
|
|
87
153
|
DEFAULT_LR_DECAY_RATE = 0.96 # Default exponential decay rate for learning rate
|
|
88
154
|
|
|
155
|
+
# Optimizer defaults
|
|
156
|
+
VALID_OPTIMIZERS = {'Adam', 'AdamW', 'SGD'} # Valid optimizer types for DDFM
|
|
157
|
+
|
|
158
|
+
# Adam optimizer defaults
|
|
159
|
+
DEFAULT_ADAM_BETA1 = 0.9 # Default beta1 (momentum decay) for Adam optimizer
|
|
160
|
+
DEFAULT_ADAM_BETA2 = 0.999 # Default beta2 (squared gradient decay) for Adam optimizer
|
|
161
|
+
DEFAULT_ADAM_EPS = 1e-7 # Default epsilon for Adam optimizer (matches TensorFlow default for DDFM compatibility)
|
|
162
|
+
DEFAULT_PYTORCH_ADAM_EPS = 1e-8 # PyTorch default epsilon for Adam optimizer (for reference)
|
|
163
|
+
|
|
164
|
+
# Batch normalization defaults (matching TensorFlow/Keras defaults)
|
|
165
|
+
DEFAULT_BATCH_NORM_MOMENTUM = 0.99 # TensorFlow/Keras BatchNormalization default momentum
|
|
166
|
+
DEFAULT_BATCH_NORM_EPS = 1e-3 # TensorFlow/Keras BatchNormalization default epsilon
|
|
167
|
+
|
|
168
|
+
# Random seed defaults
|
|
169
|
+
DEFAULT_RANDOM_SEED_MAX = 2**31 # Maximum value for random seed generation (2147483647, 32-bit signed integer max)
|
|
170
|
+
|
|
89
171
|
# Loss function defaults
|
|
90
172
|
DEFAULT_HUBER_DELTA = 1.0 # Default delta parameter for Huber loss
|
|
91
173
|
HUBER_QUADRATIC_COEFF = 0.5 # Quadratic coefficient for Huber loss (0.5 * a^2 term)
|
|
@@ -115,7 +197,11 @@ CHOLESKY_LOG_DET_FACTOR = 2.0 # Factor for log determinant computation from Cho
|
|
|
115
197
|
# ============================================================================
|
|
116
198
|
|
|
117
199
|
# Encoder layer defaults
|
|
118
|
-
DEFAULT_ENCODER_LAYERS = [
|
|
200
|
+
DEFAULT_ENCODER_LAYERS = [16, 4] # Default encoder layer sizes (matches experiment config and ddfm.py default parameter)
|
|
201
|
+
DEFAULT_NUM_FACTORS = 3 # Default number of factors for DDFM
|
|
202
|
+
DEFAULT_ACTIVATION = 'relu' # Default activation function for DDFM
|
|
203
|
+
DEFAULT_DECODER = 'linear' # Default decoder type for DDFM
|
|
204
|
+
DEFAULT_USE_BATCH_NORM = True # Default batch normalization setting for DDFM
|
|
119
205
|
|
|
120
206
|
# ============================================================================
|
|
121
207
|
# Data Processing Defaults
|
|
@@ -131,8 +217,9 @@ DEFAULT_START_DATE = datetime(2000, 1, 1)
|
|
|
131
217
|
# Default window size for DDFM
|
|
132
218
|
DEFAULT_WINDOW_SIZE = 100
|
|
133
219
|
DEFAULT_TENT_KERNEL_SIZE = 5 # Default tent kernel size for slower-frequency series aggregation
|
|
134
|
-
#
|
|
135
|
-
#
|
|
220
|
+
DEFAULT_TENT_KERNEL_REGULARIZATION_MULTIPLIER = 100.0 # Regularization multiplier for tent kernel series (handles ill-conditioning)
|
|
221
|
+
# Note: DEFAULT_BATCH_SIZE is defined above (line 88) as 32 for general neural networks
|
|
222
|
+
# Use DEFAULT_DDFM_WINDOW_SIZE (100) for DDFM-specific window size (time-step batch size)
|
|
136
223
|
|
|
137
224
|
# Warning/display limits
|
|
138
225
|
MAX_WARNING_ITEMS = 5 # Maximum number of items to show in warning messages
|
|
@@ -142,6 +229,9 @@ MAX_ERROR_ITEMS = 20 # Maximum number of items to show in error message details
|
|
|
142
229
|
DEFAULT_MIN_OBS = 5 # Default minimum observations for estimation
|
|
143
230
|
DEFAULT_MIN_OBS_IDIO = 5 # Default minimum observations for idio estimation
|
|
144
231
|
DEFAULT_MIN_OBS_VAR = 7 # Minimum observations for VAR estimation (order + 5)
|
|
232
|
+
DEFAULT_MIN_OBS_PRETRAIN = 50 # Minimum observations for DDFM pre-training without interpolation
|
|
233
|
+
DEFAULT_MULT_EPOCH_PRETRAIN = 1 # Multiplier for DDFM pre-training epochs
|
|
234
|
+
DEFAULT_PRETRAIN_EPOCHS = 200 # Default number of epochs for DDFM pre-training (matching original paper)
|
|
145
235
|
|
|
146
236
|
# Dimension validation bounds
|
|
147
237
|
MIN_TIME_STEPS = 1 # Minimum number of time steps (T) required for data
|
|
@@ -149,7 +239,9 @@ MIN_VARIABLES = 1 # Minimum number of variables (N) required for data
|
|
|
149
239
|
MIN_DDFM_TIME_STEPS = 2 # Minimum number of time steps (T) required for DDFM training (DDFM-specific, different from general MIN_TIME_STEPS=1)
|
|
150
240
|
MIN_DDFM_DATASET_SIZE_WARNING = 10 # Minimum dataset size (T) below which DDFM denoising training warns about potential instability
|
|
151
241
|
MIN_ITER_FOR_DELTA_COMPUTATION = 1 # Minimum iteration count required before computing delta (MSE change) in DDFM denoising training
|
|
242
|
+
DEFAULT_MIN_ITER_FOR_CONVERGENCE_CHECK = 2 # Minimum iteration count required before checking convergence in DDFM (check from iteration 3 onwards)
|
|
152
243
|
MIN_EPS_SHAPE_FOR_IDIO = 1 # Minimum eps shape dimension required for idiosyncratic component processing in DDFM
|
|
244
|
+
MIN_SHAPE_FOR_AR2 = 2 # Minimum shape dimension for AR(2) forecast (need at least 2 previous time steps)
|
|
153
245
|
|
|
154
246
|
# Idiosyncratic component defaults
|
|
155
247
|
DEFAULT_IDIO_STD = 0.1 # Default idiosyncratic standard deviation (when estimation fails)
|
|
@@ -193,7 +285,7 @@ DEFAULT_PROGRESS_LOG_INTERVAL = 5 # Default progress logging interval for EM al
|
|
|
193
285
|
# Precision Defaults
|
|
194
286
|
# ============================================================================
|
|
195
287
|
|
|
196
|
-
DEFAULT_DTYPE = np.
|
|
288
|
+
DEFAULT_DTYPE = np.float64 # Default numpy dtype for arrays (float64 for better numerical stability)
|
|
197
289
|
|
|
198
290
|
# PyTorch dtype (matches DEFAULT_DTYPE)
|
|
199
291
|
try:
|
|
@@ -328,6 +420,7 @@ __all__ = [
|
|
|
328
420
|
'MIN_OBSERVATION_NOISE',
|
|
329
421
|
'MIN_FACTOR_VARIANCE',
|
|
330
422
|
'MIN_STD',
|
|
423
|
+
'MIN_STD_FOR_SCALE_CHECK',
|
|
331
424
|
'MAX_EIGENVALUE',
|
|
332
425
|
'DEFAULT_EIGENVALUE_MAX_MAGNITUDE',
|
|
333
426
|
'DEFAULT_EIGENVALUE_WARN_THRESHOLD',
|
|
@@ -343,19 +436,53 @@ __all__ = [
|
|
|
343
436
|
'DEFAULT_REGULARIZATION',
|
|
344
437
|
'DEFAULT_CLIP_THRESHOLD',
|
|
345
438
|
'DEFAULT_DATA_CLIP_THRESHOLD',
|
|
439
|
+
'DEFAULT_SCALE_RATIO_MAX',
|
|
440
|
+
'DEFAULT_SCALE_RATIO_MIN',
|
|
441
|
+
'DEFAULT_STANDARDIZATION_MEAN_THRESHOLD',
|
|
442
|
+
'DEFAULT_STANDARDIZATION_STD_MIN',
|
|
443
|
+
'DEFAULT_STANDARDIZATION_STD_MAX',
|
|
444
|
+
'DEFAULT_STANDARDIZED_TARGET_STD',
|
|
445
|
+
'DEFAULT_TARGET_PREDICTION_STD',
|
|
446
|
+
'DEFAULT_VARIANCE_COLLAPSE_STD',
|
|
447
|
+
'DEFAULT_TARGET_CONVERGENCE_ITERATIONS',
|
|
448
|
+
'DEFAULT_TARGET_DDFM_LOSS',
|
|
449
|
+
'DEFAULT_DDFM_LOSS_MULTIPLIER',
|
|
450
|
+
'DEFAULT_SCALE_LOG_PRECISION',
|
|
451
|
+
'DEFAULT_TIME_LOG_PRECISION',
|
|
452
|
+
'DEFAULT_LOSS_LOG_PRECISION',
|
|
453
|
+
'SECONDS_PER_MINUTE',
|
|
346
454
|
'MIN_CONDITION_NUMBER',
|
|
347
455
|
'MAX_CONDITION_NUMBER',
|
|
348
456
|
# Training
|
|
349
457
|
'DEFAULT_MAX_ITER',
|
|
350
458
|
'DEFAULT_MAX_EPOCHS',
|
|
351
459
|
'DEFAULT_MAX_MCMC_ITER',
|
|
460
|
+
'DEFAULT_N_MC_SAMPLES',
|
|
352
461
|
'DEFAULT_BATCH_SIZE', # General neural network default (32)
|
|
353
|
-
'
|
|
462
|
+
'DEFAULT_DDFM_WINDOW_SIZE', # DDFM-specific window size default (100)
|
|
463
|
+
'DEFAULT_DDFM_BATCH_SIZE', # DDFM batch size default (100)
|
|
464
|
+
'DEFAULT_PLACEHOLDER_MC_SAMPLES', # Placeholder MC samples default (1)
|
|
465
|
+
'DEFAULT_PLACEHOLDER_DATA_SHAPE_T', # Placeholder data shape T default (100)
|
|
466
|
+
'DEFAULT_PLACEHOLDER_DATA_SHAPE_N', # Placeholder data shape N default (10)
|
|
467
|
+
'DEFAULT_PLACEHOLDER_SEED', # Placeholder random seed default (42)
|
|
468
|
+
'DEFAULT_NUM_WORKERS', # DataLoader num_workers default (0)
|
|
469
|
+
'DEFAULT_CUDA_DEVICE_INDEX', # CUDA device index default (0 = first GPU)
|
|
470
|
+
'DEFAULT_KDFM_INIT_SAMPLE_SIZE', # KDFM initialization sample size default (100)
|
|
354
471
|
'DEFAULT_LEARNING_RATE',
|
|
355
472
|
'DEFAULT_DDFM_LEARNING_RATE',
|
|
473
|
+
'DEFAULT_AUTOENCODER_FIT_EPOCHS',
|
|
474
|
+
'DEFAULT_AUTOENCODER_FIT_VERBOSE',
|
|
356
475
|
'DEFAULT_GRAD_CLIP_VAL',
|
|
357
476
|
'DEFAULT_WEIGHT_DECAY',
|
|
358
477
|
'DEFAULT_LR_DECAY_RATE',
|
|
478
|
+
'VALID_OPTIMIZERS',
|
|
479
|
+
'DEFAULT_ADAM_BETA1',
|
|
480
|
+
'DEFAULT_ADAM_BETA2',
|
|
481
|
+
'DEFAULT_ADAM_EPS',
|
|
482
|
+
'DEFAULT_TENSORFLOW_ADAM_EPS',
|
|
483
|
+
'DEFAULT_BATCH_NORM_MOMENTUM',
|
|
484
|
+
'DEFAULT_BATCH_NORM_EPS',
|
|
485
|
+
'DEFAULT_RANDOM_SEED_MAX',
|
|
359
486
|
'DEFAULT_HUBER_DELTA',
|
|
360
487
|
'HUBER_QUADRATIC_COEFF',
|
|
361
488
|
'DEFAULT_DDFM_CLIP_RANGE_DEEP',
|
|
@@ -368,7 +495,13 @@ __all__ = [
|
|
|
368
495
|
'DEFAULT_STRUCTURAL_DIAG_SCALE',
|
|
369
496
|
'DEFAULT_CHOLESKY_EPS',
|
|
370
497
|
# Architecture
|
|
498
|
+
'DEFAULT_FACTOR_ORDER',
|
|
499
|
+
'DEFAULT_AR_ORDER_2',
|
|
371
500
|
'DEFAULT_ENCODER_LAYERS',
|
|
501
|
+
'DEFAULT_NUM_FACTORS',
|
|
502
|
+
'DEFAULT_ACTIVATION',
|
|
503
|
+
'DEFAULT_DECODER',
|
|
504
|
+
'DEFAULT_USE_BATCH_NORM',
|
|
372
505
|
# Data processing
|
|
373
506
|
'DEFAULT_NAN_METHOD',
|
|
374
507
|
'DEFAULT_NAN_K',
|
|
@@ -378,12 +511,17 @@ __all__ = [
|
|
|
378
511
|
'DEFAULT_MIN_OBS',
|
|
379
512
|
'DEFAULT_MIN_OBS_IDIO',
|
|
380
513
|
'DEFAULT_MIN_OBS_VAR',
|
|
514
|
+
'DEFAULT_MIN_OBS_PRETRAIN',
|
|
515
|
+
'DEFAULT_MULT_EPOCH_PRETRAIN',
|
|
516
|
+
'DEFAULT_PRETRAIN_EPOCHS',
|
|
381
517
|
# Dimension validation
|
|
382
518
|
'MIN_TIME_STEPS',
|
|
383
519
|
'MIN_VARIABLES',
|
|
520
|
+
'MIN_SHAPE_FOR_AR2',
|
|
384
521
|
'MIN_DDFM_TIME_STEPS',
|
|
385
522
|
'MIN_DDFM_DATASET_SIZE_WARNING',
|
|
386
523
|
'MIN_ITER_FOR_DELTA_COMPUTATION',
|
|
524
|
+
'DEFAULT_MIN_ITER_FOR_CONVERGENCE_CHECK',
|
|
387
525
|
'MIN_EPS_SHAPE_FOR_IDIO',
|
|
388
526
|
'DEFAULT_IDIO_STD',
|
|
389
527
|
'DEFAULT_IDIO_RHO0',
|
|
@@ -408,6 +546,7 @@ __all__ = [
|
|
|
408
546
|
'DEFAULT_LOG_INTERVAL',
|
|
409
547
|
'DEFAULT_PROGRESS_LOG_INTERVAL',
|
|
410
548
|
'DEFAULT_TENT_KERNEL_SIZE',
|
|
549
|
+
'DEFAULT_TENT_KERNEL_REGULARIZATION_MULTIPLIER',
|
|
411
550
|
'MAX_ERROR_ITEMS',
|
|
412
551
|
# IRF
|
|
413
552
|
'DEFAULT_IRF_HORIZON',
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
"""Configuration schema package for DFM models.
|
|
2
2
|
|
|
3
3
|
This package contains:
|
|
4
|
-
- model.py: BaseModelConfig, DFMConfig, DDFMConfig
|
|
5
|
-
- results.py: BaseResult, DFMResult, DDFMResult
|
|
4
|
+
- model.py: BaseModelConfig, DFMConfig, DDFMConfig - model configurations
|
|
5
|
+
- results.py: BaseResult, DFMResult, DDFMResult - result structures
|
|
6
6
|
|
|
7
7
|
Note: Series are specified via frequency dict mapping column names to frequencies.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
from .model import BaseModelConfig, DFMConfig, DDFMConfig
|
|
11
|
-
from .results import BaseResult, DFMResult, DDFMResult
|
|
10
|
+
from .model import BaseModelConfig, DFMConfig, DDFMConfig
|
|
11
|
+
from .results import BaseResult, DFMResult, DDFMResult
|
|
12
|
+
from .params import DFMStateSpaceParams, DDFMStateSpaceParams
|
|
12
13
|
|
|
13
14
|
__all__ = [
|
|
14
|
-
'BaseModelConfig', 'DFMConfig', 'DDFMConfig',
|
|
15
|
-
'BaseResult', 'DFMResult', 'DDFMResult',
|
|
15
|
+
'BaseModelConfig', 'DFMConfig', 'DDFMConfig',
|
|
16
|
+
'BaseResult', 'DFMResult', 'DDFMResult',
|
|
17
|
+
'DFMStateSpaceParams', 'DDFMStateSpaceParams',
|
|
16
18
|
]
|
|
17
19
|
|