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
Prior statistics and set-up for multidimensional priors #4907
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## main #4907 +/- ##
==========================================
+ Coverage 75.73% 75.76% +0.02%
==========================================
Files 226 226
Lines 33149 33197 +48
==========================================
+ Hits 25105 25151 +46
- Misses 8044 8046 +2 ☔ View full report in Codecov by Sentry. |
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.
Thanks @katrinstreil! I have left some first comments in line.
prior_stat_sum -= prior_fit_statistic(dataset.models.priors) | ||
# compute prior_fit_statistics from all datasets | ||
if self.models is not None: | ||
prior_stat_sum += prior_fit_statistic(self.models.priors) |
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.
Why does one prior count positive the other negative?
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.
Datasets.model
includes all models, why is there an independent sum for dataset.models
?
prior_stat_sum = self.models.parameters.prior_stat_sum() | ||
|
||
counts, npred = self.counts.data.astype(float), self.npred().data | ||
prior_stat_sum = prior_fit_statistic(self.models.priors) |
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.
Wouldn't this double count the prior, when it is evaluated again at the Datasets.stat_sum()
level?
@@ -32,7 +32,15 @@ def _build_priorparameters_from_dict(data, default_parameters): | |||
class Prior(ModelBase): | |||
_unit = "" | |||
|
|||
def __init__(self, **kwargs): | |||
def __init__(self, modelparameters, **kwargs): |
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.
I think taking the Parameter
object here on init is rather confusing to establish the linking between parameters and their priors. I think this also deviates from the API proposed in the PIG.
@@ -144,8 +162,7 @@ class GaussianPrior(Prior): | |||
mu = PriorParameter(name="mu", value=0) | |||
sigma = PriorParameter(name="sigma", value=1) | |||
|
|||
@staticmethod | |||
def evaluate(value, mu, sigma): | |||
def evaluate(self, value, mu, sigma): |
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.
self
I snot used, this can remain a static method.
@@ -172,8 +189,7 @@ class UniformPrior(Prior): | |||
min = PriorParameter(name="min", value=-np.inf, unit="") | |||
max = PriorParameter(name="max", value=np.inf, unit="") | |||
|
|||
@staticmethod | |||
def evaluate(value, min, max): | |||
def evaluate(self, value, min, max): |
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.
Same as above...
There are some aspects, that are confusing to me in the current implementation.
Next question is how the evaluate hierarchical priors. I think that priors exist on multiple levels of the model hierarchy:
And I think they can be treated independently. So e.g. if a users defines: norm_pl = PowerLawNormSpectralModel()
norm_pl.prior = MultivariateGaussianPrior() Then In general I think it makes sense to define a These are a a few half-structured thoughts, maybe they help a bit in developing a clearer vision of the implementation. |
Thanks @adonath for the comments! About the first thing you mention concerning the evaluation of the prior in
About the hierarchical treatment of the prior: For instance, coupling two indices from two Skymodels?
Which intrinsically sets: How would this is implemented without passing the model parameters to the prior instance? The only possibility I can think of is the following:
And then the mapping happens internally. In your example:
Would the About the non-static evaluation of the priors:
|
Your first example with the coupled indices is an interesting use case, that will help us! I think we are going in the exact same direction, with some small differences. Your first use case I think should look like: models = Models([model1, model2])
# this creates a full covariance matrix internally
prior = MultiVariateGaussianPrior.from_subcovariance(
pars=[model1.spectral_model.index, model2.spectral_model.index],
subcovar=C_sub
)
models.prior = prior
# but this should also work:
prior = MultiVariateGaussianPrior(
parameters=None
covariance=C_full
)
# just based on the fact that the number parameters in models is the same size as the full covariance
# matrix one can assign it internally. See
models.prior = prior But yes internally the For this use case we can probably just re-use the existing |
This is the part I'm less sure about. This would require passing information both direction: up and down the hierarchy. I implemented this for the covariance handling of models and it is rather complex, with not such a huge benefit. Or do you propose to only pass the information down? As prior are always set explicitly by the user, I think it is not important that we always synchronize the information: norm_pl = PowerLawNormSpectralModel()
norm_pl.prior = MultivariateGaussianPrior(covariance=np.eye(len(norm_pl.norms)))
assert norm_pl.norms[0].prior is None I think it is fine if, when the prior is set on a higher level to account for correlations, to not represent this on a lower level. |
Any news here @katrinstreil ? |
Description
This pull request modifies how priors are evaluated with a separate stat method:
prior_fit_statistic(priors)
.The priors themselves are no longer saved on the
parameters
object but onmodels
.To allow the evaluation of multidimensional priors, the information on the model parameters is saved on the prior instance as
modelparameters
.