dfm-python 0.6.11__py3-none-any.whl → 0.6.13__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 +1 -1
- dfm_python/config/schema/params.py +119 -35
- dfm_python/config/schema/results.py +3 -3
- dfm_python/dataset/ddfm_dataset.py +55 -324
- dfm_python/functional/cauchy.py +236 -0
- dfm_python/functional/krylov.py +204 -0
- dfm_python/layer/mlp.py +272 -0
- dfm_python/layer/pca.py +304 -0
- dfm_python/logger/__init__.py +5 -2
- dfm_python/logger/ddfm_logger.py +23 -0
- dfm_python/logger/inference_logger.py +1 -8
- dfm_python/logger/ivdfm_logger.py +0 -0
- dfm_python/logger/train_logger.py +1 -8
- dfm_python/models/base.py +51 -1
- dfm_python/models/ddfm/__init__.py +12 -0
- dfm_python/models/ddfm/ddfm.py +313 -496
- dfm_python/models/ddfm/decoder.py +263 -0
- dfm_python/{encoder/simple_autoencoder.py → models/ddfm/encoder.py} +204 -43
- dfm_python/models/ddfm/sampling.py +442 -0
- dfm_python/models/dfm/initialization.py +1 -1
- dfm_python/models/dfm/mixed_freq.py +24 -3
- dfm_python/models/ivdfm/__init__.py +0 -0
- dfm_python/models/ivdfm/decoder.py +0 -0
- dfm_python/models/ivdfm/encoder.py +0 -0
- dfm_python/models/ivdfm/ivdfm.py +708 -0
- dfm_python/numeric/builder.py +207 -0
- dfm_python/utils/__init__.py +2 -2
- dfm_python/utils/loss.py +232 -2
- {dfm_python-0.6.11.dist-info → dfm_python-0.6.13.dist-info}/METADATA +1 -1
- dfm_python-0.6.13.dist-info/RECORD +61 -0
- dfm_python/decoder/__init__.py +0 -16
- dfm_python/decoder/base.py +0 -78
- dfm_python/decoder/linear.py +0 -72
- dfm_python/decoder/mlp.py +0 -128
- dfm_python/encoder/__init__.py +0 -38
- dfm_python/encoder/base.py +0 -111
- dfm_python/encoder/pca.py +0 -271
- dfm_python-0.6.11.dist-info/RECORD +0 -55
- {dfm_python-0.6.11.dist-info → dfm_python-0.6.13.dist-info}/WHEEL +0 -0
dfm_python/__init__.py
CHANGED
|
@@ -63,7 +63,7 @@ Note: DFMConfig uses frequency dict to specify series (column names -> frequenci
|
|
|
63
63
|
For detailed documentation, see the README.md file and the tutorial notebooks/scripts.
|
|
64
64
|
"""
|
|
65
65
|
|
|
66
|
-
__version__ = "0.
|
|
66
|
+
__version__ = "0.6.13"
|
|
67
67
|
|
|
68
68
|
# ============================================================================
|
|
69
69
|
# PUBLIC API DEFINITION
|
|
@@ -163,11 +163,11 @@ class DFMModelState:
|
|
|
163
163
|
)
|
|
164
164
|
|
|
165
165
|
@dataclass
|
|
166
|
-
class
|
|
167
|
-
"""
|
|
166
|
+
class DDFMModelState:
|
|
167
|
+
"""DDFM model state including training state and state-space parameters.
|
|
168
168
|
|
|
169
|
-
|
|
170
|
-
loss, factors,
|
|
169
|
+
Consolidates all DDFM model state for checkpointing: training state (convergence,
|
|
170
|
+
loss, factors, residuals) and fitted state-space parameters.
|
|
171
171
|
|
|
172
172
|
Attributes
|
|
173
173
|
----------
|
|
@@ -184,15 +184,84 @@ class DDFMTrainingState:
|
|
|
184
184
|
last_neurons : np.ndarray, optional
|
|
185
185
|
Last layer neurons for MLP decoder (n_mc_samples x T x num_neurons) or (T x num_neurons).
|
|
186
186
|
For linear decoder, this equals factors.
|
|
187
|
+
F : np.ndarray, optional
|
|
188
|
+
Transition matrix (m x m) - VAR(1) dynamics for factors (A in paper)
|
|
189
|
+
Q : np.ndarray, optional
|
|
190
|
+
Process noise covariance (m x m) - innovation covariance (W in original code)
|
|
191
|
+
mu_0 : np.ndarray, optional
|
|
192
|
+
Initial state mean (m,) - initial factor values
|
|
193
|
+
Sigma_0 : np.ndarray, optional
|
|
194
|
+
Initial state covariance (m x m) - initial uncertainty
|
|
195
|
+
H : np.ndarray, optional
|
|
196
|
+
Observation matrix (N x m) - decoder weights (measurement equation, theta in paper)
|
|
197
|
+
R : np.ndarray, optional
|
|
198
|
+
Observation noise covariance (N x N) - typically diagonal, small values
|
|
187
199
|
"""
|
|
200
|
+
# Training state
|
|
188
201
|
num_iter: int = 0
|
|
189
202
|
loss_now: Optional[float] = None
|
|
190
203
|
converged: bool = False
|
|
191
204
|
eps: Optional[np.ndarray] = None
|
|
192
205
|
factors: Optional[np.ndarray] = None
|
|
193
206
|
last_neurons: Optional[np.ndarray] = None
|
|
207
|
+
# State-space parameters (fitted during build_state_space)
|
|
208
|
+
F: Optional[np.ndarray] = None # Transition matrix (m x m) - A in paper
|
|
209
|
+
Q: Optional[np.ndarray] = None # Process noise covariance (m x m) - W in original code
|
|
210
|
+
mu_0: Optional[np.ndarray] = None # Initial state mean (m,)
|
|
211
|
+
Sigma_0: Optional[np.ndarray] = None # Initial state covariance (m x m)
|
|
212
|
+
H: Optional[np.ndarray] = None # Observation matrix (N x m) - theta in paper
|
|
213
|
+
R: Optional[np.ndarray] = None # Observation noise covariance (N x N)
|
|
194
214
|
|
|
195
|
-
|
|
215
|
+
@classmethod
|
|
216
|
+
def from_model(cls, model: Any) -> 'DDFMModelState':
|
|
217
|
+
"""Create DDFMModelState from DDFM model instance.
|
|
218
|
+
|
|
219
|
+
Parameters
|
|
220
|
+
----------
|
|
221
|
+
model : DDFM
|
|
222
|
+
DDFM model instance
|
|
223
|
+
|
|
224
|
+
Returns
|
|
225
|
+
-------
|
|
226
|
+
DDFMModelState
|
|
227
|
+
Model state dataclass
|
|
228
|
+
"""
|
|
229
|
+
# Get training state from model attributes
|
|
230
|
+
factors = getattr(model, 'factors', None)
|
|
231
|
+
eps = getattr(model, 'eps', None)
|
|
232
|
+
last_neurons = getattr(model, 'last_neurons', None)
|
|
233
|
+
num_iter = getattr(model, '_num_iter', 0)
|
|
234
|
+
loss_now = getattr(model, 'loss_now', None)
|
|
235
|
+
converged = getattr(model, '_converged', False)
|
|
236
|
+
|
|
237
|
+
# Get state-space parameters from training_state
|
|
238
|
+
F = Q = mu_0 = Sigma_0 = H = R = None
|
|
239
|
+
if hasattr(model, 'training_state') and model.training_state is not None:
|
|
240
|
+
ts = model.training_state
|
|
241
|
+
if hasattr(ts, 'F'):
|
|
242
|
+
F = ts.F
|
|
243
|
+
Q = ts.Q
|
|
244
|
+
mu_0 = ts.mu_0
|
|
245
|
+
Sigma_0 = ts.Sigma_0
|
|
246
|
+
H = ts.H
|
|
247
|
+
R = ts.R
|
|
248
|
+
|
|
249
|
+
return cls(
|
|
250
|
+
num_iter=num_iter,
|
|
251
|
+
loss_now=loss_now,
|
|
252
|
+
converged=converged,
|
|
253
|
+
eps=eps,
|
|
254
|
+
factors=factors,
|
|
255
|
+
last_neurons=last_neurons,
|
|
256
|
+
F=F,
|
|
257
|
+
Q=Q,
|
|
258
|
+
mu_0=mu_0,
|
|
259
|
+
Sigma_0=Sigma_0,
|
|
260
|
+
H=H,
|
|
261
|
+
R=R
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
def sync_from_model(self, model: Any) -> 'DDFMModelState':
|
|
196
265
|
"""Update this dataclass from model instance attributes.
|
|
197
266
|
|
|
198
267
|
Parameters
|
|
@@ -202,7 +271,7 @@ class DDFMTrainingState:
|
|
|
202
271
|
|
|
203
272
|
Returns
|
|
204
273
|
-------
|
|
205
|
-
|
|
274
|
+
DDFMModelState
|
|
206
275
|
Self (for chaining)
|
|
207
276
|
"""
|
|
208
277
|
if hasattr(model, '_has_factors') and model._has_factors:
|
|
@@ -212,37 +281,52 @@ class DDFMTrainingState:
|
|
|
212
281
|
self.num_iter = getattr(model, '_num_iter', 0)
|
|
213
282
|
self.loss_now = getattr(model, 'loss_now', None)
|
|
214
283
|
self.converged = getattr(model, '_converged', False)
|
|
284
|
+
|
|
285
|
+
# Sync state-space parameters if available
|
|
286
|
+
if hasattr(model, 'training_state') and model.training_state is not None:
|
|
287
|
+
ts = model.training_state
|
|
288
|
+
if hasattr(ts, 'F'):
|
|
289
|
+
self.F = ts.F
|
|
290
|
+
self.Q = ts.Q
|
|
291
|
+
self.mu_0 = ts.mu_0
|
|
292
|
+
self.Sigma_0 = ts.Sigma_0
|
|
293
|
+
self.H = ts.H
|
|
294
|
+
self.R = ts.R
|
|
295
|
+
|
|
215
296
|
return self
|
|
216
|
-
|
|
217
|
-
@dataclass
|
|
218
|
-
class DDFMStateSpaceParams:
|
|
219
|
-
"""State-space model parameters for DDFM (fitted during model training).
|
|
220
|
-
|
|
221
|
-
These parameters are computed during DDFM.build_state_space() and represent
|
|
222
|
-
the fitted state-space model structure. Similar to DFMStateSpaceParams, this contains
|
|
223
|
-
the fitted state-space parameters but for DDFM. Naming follows original paper conventions.
|
|
224
297
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
298
|
+
def apply_to_model(self, model: Any) -> None:
|
|
299
|
+
"""Apply this state to DDFM model instance.
|
|
300
|
+
|
|
301
|
+
Parameters
|
|
302
|
+
----------
|
|
303
|
+
model : DDFM
|
|
304
|
+
DDFM model instance to update
|
|
305
|
+
"""
|
|
306
|
+
# Apply training state
|
|
307
|
+
if self.factors is not None:
|
|
308
|
+
model.factors = self.factors
|
|
309
|
+
if self.eps is not None:
|
|
310
|
+
model.eps = self.eps
|
|
311
|
+
if self.last_neurons is not None:
|
|
312
|
+
model.last_neurons = self.last_neurons
|
|
313
|
+
model._num_iter = self.num_iter
|
|
314
|
+
model.loss_now = self.loss_now
|
|
315
|
+
model._converged = self.converged
|
|
316
|
+
|
|
317
|
+
# Apply state-space parameters if available
|
|
318
|
+
if self.F is not None and self.Q is not None and self.mu_0 is not None:
|
|
319
|
+
if hasattr(model, 'training_state'):
|
|
320
|
+
model.training_state.F = self.F
|
|
321
|
+
model.training_state.Q = self.Q
|
|
322
|
+
model.training_state.mu_0 = self.mu_0
|
|
323
|
+
model.training_state.Sigma_0 = self.Sigma_0
|
|
324
|
+
model.training_state.H = self.H
|
|
325
|
+
model.training_state.R = self.R
|
|
326
|
+
|
|
327
|
+
# Backward compatibility aliases
|
|
328
|
+
DDFMTrainingState = DDFMModelState
|
|
329
|
+
DDFMStateSpaceParams = DDFMModelState
|
|
246
330
|
|
|
247
331
|
# Backward compatibility alias
|
|
248
332
|
DFMStateSpaceParams = DFMModelState
|
|
@@ -13,7 +13,7 @@ from typing import Optional, List, Dict, Any, Tuple
|
|
|
13
13
|
from datetime import datetime
|
|
14
14
|
|
|
15
15
|
from .model import DFMConfig
|
|
16
|
-
from .params import
|
|
16
|
+
from .params import DDFMModelState
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
|
|
@@ -311,7 +311,7 @@ class DDFMResult(BaseResult):
|
|
|
311
311
|
Architecture of the encoder network used.
|
|
312
312
|
use_idiosyncratic : bool, optional
|
|
313
313
|
Whether idiosyncratic components were modeled.
|
|
314
|
-
fit_params :
|
|
314
|
+
fit_params : DDFMModelState, optional
|
|
315
315
|
State-space model parameters created during fit (F, Q, mu_0, sigma_0, H, R).
|
|
316
316
|
These are computed during build_state_space() and represent the fitted
|
|
317
317
|
state-space model structure.
|
|
@@ -365,7 +365,7 @@ class DDFMResult(BaseResult):
|
|
|
365
365
|
use_idiosyncratic: Optional[bool] = None # Whether idio components were used
|
|
366
366
|
|
|
367
367
|
# State-space parameters (fitted during training)
|
|
368
|
-
fit_params: Optional[
|
|
368
|
+
fit_params: Optional[DDFMModelState] = None
|
|
369
369
|
|
|
370
370
|
# Training hyperparameters
|
|
371
371
|
training_max_iter: Optional[int] = None
|