Skip to content
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

Constraint the GP fit to be strictly positive #106

Open
maria-vincenzi opened this issue Nov 24, 2018 · 11 comments
Open

Constraint the GP fit to be strictly positive #106

maria-vincenzi opened this issue Nov 24, 2018 · 11 comments

Comments

@maria-vincenzi
Copy link

Hi,
I have a question (sorry if this is not strictly related to the code implementation itself).
Is there any way to constraint the GP fit to be strictly positive?
Let's say I'm trying to fit some physical quantity that have to be positive (e.g. Flux).
Is there a way to prevent the GP to go below zero?
The only solution I came up with was to perform the GP fit in LOG space but this is not performing very well (I get smooth fits in LOG space, but when I then transform everything back to LIN the fit look a little bit "messy").
Thank you,
Maria

@dfm
Copy link
Owner

dfm commented Nov 24, 2018 via email

@davidwhogg
Copy link

It feels like a constrained-positive solution is possible -- because it is for any finite-parameter model. But I don't know how to do it!

@tmcclintock
Copy link

I just wanted to chime in that this is possible by transforming the Gaussian posterior predictive distribution to a truncated Gaussian PPD. In other words, one can train the GP on the normal training data, but then just plug the moments of the GP (the mean and cov) into the truncated Gaussian distribution along with the bounds and recover a PDF over the truncated range. In the case of requiring y>0 you can set the lower bound on the GP to be a=0. This is a cute solution too because your truncation bounds can vary with input x.

You just have to be careful since the +-68% confidence intervals (the sigma levels) are not symmetric about the mean prediction, and furthermore the mean prediction is no longer the median of the PPD. It is straightforward to compute the median of the truncated Gaussian, though.

Here is an example figure showing the tutorial GP with a truncated PPD to exist only in y>0. The black points, green line, and gray lines are all the same as the tutorial. The red line shows the mean of the truncated GP PPD and the red shaded regions show the 68% confidence interval (not the standard deviation).

example

@dfm @davidwhogg if you think this might be worth a PR I'd be happy to implement it.

@lleewwiiss
Copy link

lleewwiiss commented Jul 16, 2020

Also something worth considering https://arxiv.org/abs/2004.04632.pdf

@tmcclintock
Copy link

@lleewwiiss good find. It turns out that because of the nice properties of Gaussians, you can construct even more sophisticated constrained GPs (like ones where the slope or convexity of the GP is bounded). Here is a nice recent stats paper on the topic https://arxiv.org/abs/1703.00787.

@lleewwiiss
Copy link

@tmcclintock Interesting I will check it out, do you have an example of how you implemented the above constraints? I tried by can't seem to work it out

@tmcclintock
Copy link

Oh the ones in the paper? I do not. Or did you mean the one I commented about in November?

@lleewwiiss
Copy link

The comment from November using the tutorial example

@tmcclintock
Copy link

Ah I see. Not on hand, but I'll whip up a gist and ping you.

scipy.stats.truncnorm is very unwieldy and not amenable to working with a GP since the loc and scale arguments need to change over the domain of the prediction, hence a vectorized implementation might be nice to make.

@tmcclintock
Copy link

@lleewwiiss here you go: https://github.com/tmcclintock/TruncatedGP
It ended up being too long for a gist. I show the posteriors for the truncated and non-truncated GPs, as well as draws from both posteriors.

If you look at the code you will see that you need to do some annoying transformations because of the way scipy.stats.truncnorm works. The upside is that my implementation allows for arbitrary bounds a(x) and b(x).

Drop me a line if you feel like spinning this out into a real project.

@lleewwiiss
Copy link

@tmcclintock Thank you! I will check it out now, and credit you where I can

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants