-
-
Notifications
You must be signed in to change notification settings - Fork 127
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
ValueError: Non-parent parameter not found in posterior #750
Comments
Hi @amoulin55, thanks for opening the issue! Do you have a reproducible example? I just need
Thanks! |
Hi, thank you for the quick follow-up. Below are some details: Dataset, I unfortunately cannot provide it, but this pet-example shows the same error: import numpy as np
import pandas as pd
import bambi as bmb
import pymc as pm
import arviz as az
n_obs = 1000
x_obs = np.random.uniform(size=(n_obs))
y_mean = x_obs -0.5
y_distr = pm.TruncatedNormal.dist(mu=y_mean, sigma=.03, lower=0)
y_obs = pm.draw(y_distr)
df_model=pd.DataFrame({"x": x_obs, "y": y_obs}) Versions: bambi 0.13.0 pymc 5.9.1 |
Hey @amoulin55, thanks for the simulated data and code for the model. I am able to reproduce the error (although I had to change the value of the |
What's happening is that you're passing data as a prior. It results in Bambi looking for some value in the inference data object, when it shouldn't be looked there. You can write it as a custom family with a custom likelihood. Feels a little bit hacky but it's supported. class CustomTruncatedNormal(pm.TruncatedNormal):
def __call__(self, *args, **kwargs):
# Set whatever value you want for `lower=0`
return pm.TruncatedNormal(*args, **kwargs, lower=0)
@classmethod
def dist(self, *args, **kwargs):
return pm.TruncatedNormal.dist(*args, **kwargs, lower=0)
likelihood = bmb.Likelihood(
"TruncatedNormal", params=["mu", "sigma"], parent="mu", dist=CustomTruncatedNormal
)
links = {"mu": "identity"}
family = bmb.Family("truncated_normal", likelihood, links)
priors = {"sigma": bmb.Prior("HalfStudentT", nu=4, sigma=4.48)}
model = bmb.Model("y ~ x", df_model, family=family, priors=priors)
trace = model.fit()
model.predict(trace, kind="pps") |
In addition, since #752, we don't need custom families anymore for truncated models. In you case, simply do bmb.Model("truncated(y, 0.18) ~ x", ...) and that would be it. Have a look at the example in the PR if you want to learn more. |
Thank you both, very much appreciated. I will try it out on my 'real' data and confirm. |
Hi - I tried the simple bmb.Model("truncated(y, 0) ~ ......", ...) and it returned an error 'KeyError: 'truncated'' Then I tried to run your example from #752 , exactly as-is, and it returns the same error. I I am new in this space, so could very well miss something. I am still using bambi 0.13.0. Thank you again for your guidance. |
You need to install Bambi from the main branch as I didn't make any release yet
|
Many thanks for your guidance. I first played with your example with having only a lower bound at -5 (because my data distribution of interest has only a lower bound), see yt (observed) plotted below. model = bmb.Model("truncated(y, -5) ~ x", df, priors=priors) But it seems that the posterior predictive vs observed results are then flipped, see below. |
Why do you say the results are flipped? The observed is cut at "-5" because you never observe values below "-5" because of the truncation process. However, the model can still predict values below "-5". Am I missing something? |
Indeed, I did not think it through. Thanks again for the new feature. I will try truncated StudentT next. |
Following up as I am still having a couple of questions:
For your information, this is what I as posterior predictive mean distribution with my real data, comparing a plain gaussian with a truncated gaussian likelihood. Thank you again. |
I had a similar issue using the truncated response variable function. I was getting response values outside of the bounds that I had set. Maybe I am not understanding the concept either. |
The type of truncation I'm talking about here is the one mentioned in this example https://www.pymc.io/projects/examples/en/latest/generalized_linear_models/GLM-truncated-censored-regression.html "Truncation is a type of missing data problem where you are simply unaware of any data where the outcome variable falls outside of a certain set of bounds.". This does not mean that values outside those bounds are not possible (i.e. the density function outside the bounds is zero). It means you can't observe those values, but those values of course can exist, so posterior predictive distribution is not bounded. If you want the other kind of truncation, where you just restrict the boundary of a random variable, then that's another thing. About the first point, you see the warning because there's some special function that doesn't have a C implementation thus PyTensor can't perform all the optimizations it would perform in other situations. It's not a bug, it's just that there's a missing feature. |
“If you want the other kind of truncation, where you just restrict the
boundary of a random variable, then that's another thing.”
How would this be done?
…On Thu, Nov 16, 2023 at 15:25 Tomás Capretto ***@***.***> wrote:
The type of truncation I'm talking about here is the one mentioned in this
example
https://www.pymc.io/projects/examples/en/latest/generalized_linear_models/GLM-truncated-censored-regression.html
"Truncation is a type of missing data problem where you are simply unaware
of any data where the outcome variable falls outside of a certain set of
bounds.". This does not mean that values outside those bounds are not
possible (i.e. the density function outside the bounds is zero). It means
you can't observe those values, but those values of course can exist, so
posterior predictive distribution is not bounded.
If you want the other kind of truncation, where you just restrict the
boundary of a random variable, then that's another thing.
About the first point, you see the warning because there's some special
function that doesn't have a C implementation thus PyTensor can't perform
all the optimizations it would perform in other situations. It's not a bug,
it's just that there's a missing feature.
—
Reply to this email directly, view it on GitHub
<#750 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AH3QQV73EFJZTT3LPRJJZ7LYEZZCTAVCNFSM6AAAAAA7C2DCF2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMJVGI3DAMBQHA>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Hi tomicapretto Similar ask as zwelitunyiswa, would you have some guidance on how we set a bound on y? And thanks for the note on the missing feature. |
Hi @tomicapretto . Still, when fitting a model with a prior set to a constant value as @amoulin55 did in their OP it is unfortunate that the (constant valued) samples do not appear in the posterior, as it makes applying |
@amoulin55 I'm double checking this because I think I got confused too. Will write again when I have an answer! |
I've been thinking about this and I've discussed it with others too. When we have a truncated distribution in PyMC we can get two kinds of predictions
|
@tomicapretto Thanks for spending time thinking about this. Your explanation makes complete sense. I, like @amoulin55 , thought that we were doing #2. My use case is healthcare research where I am trying to predict the area of a wound at certain body part. The prediction of the truncated random variable, cannot be bigger than the body part, e.g. foot. |
Maybe we can have "constrained" function, and follow the truncated syntax so -> constrained(y, lb=2, ub=8). |
@tomicapretto @zwelitunyiswa @amoulin55 Great clarification, thanks! Imo a good solution would be to change the name of what is currently |
@DanielRobertNicoud I think @zwelitunyiswa thanks for proposing |
@zwelitunyiswa @DanielRobertNicoud we now have a |
This is great! Amazing for my use case. Thank you.
Question: what if I have constrained DVs at certain levels? So for example
I have a model like: size ~ body_location, and body location has like 5
levels, would it be able to constrain by level?
Z.
…On Wed, Nov 29, 2023 at 1:00 PM Tomás Capretto ***@***.***> wrote:
@zwelitunyiswa <https://github.com/zwelitunyiswa> @DanielRobertNicoud
<https://github.com/DanielRobertNicoud> we now have a constrained
transformation, implemented in #764
<#764>.
—
Reply to this email directly, view it on GitHub
<#750 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AH3QQV2KOKONRY3KUXXL2ULYG5Z3PAVCNFSM6AAAAAA7C2DCF2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQMZSGQZTQMZVGI>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Do you mean that the bounds of the constrained distribution depend on the level of a categorical predictor? If that's what you mean, the answer is not for now as it only supports scalar values for |
@tomicapretto Yup that's exactly right. Right now I can constrain at the max value possible level for all anatomical sites, who have varying max values. Thanks to you, that makes my model behave much better. Doing it at varying levels would be icing on the cake but totally get that it is not trivial and a very narrow use case. |
Hi - I am trying to use a Truncated Normal as my likelihood, see simple example below.
My issue is that the model.predict(trace, kind="pps") returns an error:
ValueError: Non-parent parameter not found in posterior.This error shouldn't have happened!
Is it something to do with the 'lower' parameter set as a constant? Thank you for your help.
Armelle
The text was updated successfully, but these errors were encountered: