-
-
Notifications
You must be signed in to change notification settings - Fork 69
Dynamical Factor Models (DFM) Implementation (GSOC 2025) #446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Looks interesting! Just say when you think it's ready for review |
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
Thanks for the feedback! I'm still exploring the best approach for implementing Dynamic Factor Models. |
In the notebook a comparison between the custom DFM and the implemented DFM (which has an hardcoded version of make_symbolic_graph, that work just in this case)
Still to do: 1) vectorization/block matrices 2) measurament errors
…ate/pymc-extras into DFM_draft_implementation
pymc_extras/statespace/models/DFM.py
Outdated
factor_order : int | ||
Order of the VAR process for the latent factors. | ||
|
||
k_endog : int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
k_endog : int | |
k_endog : int, optional |
pymc_extras/statespace/models/DFM.py
Outdated
Order of the VAR process for the latent factors. | ||
|
||
k_endog : int | ||
Number of observed time series. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Number of observed time series. | |
Number of observed time series. If not provided, the number of observed series will be inferred from `endog_names`. At least one of `k_endog` or `endog_names` must be provided. |
pymc_extras/statespace/models/DFM.py
Outdated
k_endog : int | ||
Number of observed time series. | ||
|
||
endog_names : Sequence[str], optional |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
endog_names : Sequence[str], optional | |
endog_names : list of str, optional |
pymc_extras/statespace/models/DFM.py
Outdated
Number of observed time series. | ||
|
||
endog_names : Sequence[str], optional | ||
Names of the observed time series. If not provided, default names will be generated as `endog_1`, `endog_2`, ..., `endog_k`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Names of the observed time series. If not provided, default names will be generated as `endog_1`, `endog_2`, ..., `endog_k`. | |
Names of the observed time series. If not provided, default names will be generated as `endog_1`, `endog_2`, ..., `endog_k` based on `k_endog`. At least one of `k_endog` or `endog_names` must be provided. |
verbose: bool, default True | ||
If true, a message will be logged to the terminal explaining the variable names, dimensions, and supports. | ||
|
||
Notes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're going to have to add all the math equations and whatnot here eventually. No rush, but I want to make sure it's on your TODO list. Check the VARMAX docstring for what I have in mind
pymc_extras/statespace/models/DFM.py
Outdated
# Factor states | ||
for i in range(self.k_factors): | ||
for lag in range(self.factor_order): | ||
names.append(f"factor_{i+1}_lag{lag}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I've been using stata notation for lagged states, e.g. L{lag}.factor_{i+1}
Not married to it, but consider it for consistency's sake.
pymc_extras/statespace/models/DFM.py
Outdated
if self.error_order > 0: | ||
for i in range(self.k_endog): | ||
for lag in range(self.error_order): | ||
names.append(f"error_{i+1}_lag{lag}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as above
pymc_extras/statespace/models/DFM.py
Outdated
|
||
# If error_order > 0 | ||
if self.error_order > 0: | ||
coords["error_ar_param"] = list(range(1, self.error_order + 1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coords["error_ar_param"] = list(range(1, self.error_order + 1)) | |
coords[ERROR_AR_PARAM_DIM] = list(range(1, self.error_order + 1)) |
It's weird to have a global everywhere except here
pymc_extras/statespace/models/DFM.py
Outdated
coord_map["factor_ar"] = (FACTOR_DIM, AR_PARAM_DIM) | ||
|
||
if self.error_order > 0: | ||
coord_map["error_ar"] = (OBS_STATE_DIM, "error_ar_param") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
coord_map["error_ar"] = (OBS_STATE_DIM, "error_ar_param") | |
coord_map["error_ar"] = (OBS_STATE_DIM, ERROR_AR_PARAM_DIM) |
|
||
self.ssm["initial_state_cov", :, :] = P0 | ||
|
||
# TODO vectorize the design matrix |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're going to have to double-check all of these matrix constructions if you re-ordered the states.
Dynamical Factor Models (DFM) Implementation
This PR provides a first draft implementation of Dynamical Factor Models as part of my application proposal for the PyMC GSoC 2025 project. A draft of my application report can be found at this link.
Overview
DFM.py
with initial functionalityCurrent Status
This implementation is a work in progress and I welcome any feedback
Next Steps