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

Printing or saving posterior distribution parameters, not density function #10

Open
Kwonsoo opened this issue Dec 14, 2020 · 7 comments

Comments

@Kwonsoo
Copy link

Kwonsoo commented Dec 14, 2020

Dear PSI team,

Thanks for the nice solver and clean documentation.

It would be very useful if we can specify an option so that the solver produces parameters of the posterior distribution as well as the density function. For example, when the posterior distribution is a normal, then it would be more useful if we could just get the mean and standard deviation (possibly in the csv form).
I read the github page and the CAV 2016 paper, but I couldn't figure out how to do it. So now I think that the current solver does not have the functionality.

Do you also think it is a good thing to do?

Thanks,
Gwonsoo

@tgehr
Copy link
Collaborator

tgehr commented Dec 14, 2020

Hi Gwonsoo,

The main challenges are:

  • It's not so easy to detect a specific PDF shape in a robust way (but we could try to do some best-effort matching).
  • There's a large number of named distributions, so implementing some sort of matching for all of them is quite a bit of work.
  • Not every posterior distribution is explicitly named with a standard set of parameters.

What is your use case? Is it just for readability?

Best,
Timon

@Kwonsoo
Copy link
Author

Kwonsoo commented Dec 14, 2020

Only doing so for cases where we can figure out the type (e.g., normal) of distributions easily would still be useful.

Readability is one, but not just that. One may directly compare the distribution computed by PSI with the one produced by a different learning/inference algorithm. For example, one basic form of the variational distribution (in variational inference) is a mean-field normal, and one may want to compare (and possibly plot together) what's learned with what PSI produces. My use case is similar to this.

Another use case is that one may want to use the distribution parameters as the input to another machine learning algorithm or system. That way, the algorithm may exploit the power of PSI and focus on something that the algorithm should do.

The density output format may be useful for some other use cases, but for simpler cases (e.g., normal), providing mean and standard deviation seems more concise and useful (since the mean and standard deviation characterizes the normal distribution, and it's easy to set up the density function with the two quantity).

Thanks,
Gwonsoo

@tgehr
Copy link
Collaborator

tgehr commented Dec 14, 2020

If PSI gives you a Gaussian PDF with concrete parameters for some variable, I think it will reliably simplify queries of the following form:

def main(){
	x:=gauss(0,1); // x is your result
	μ:=Expectation(x);
	ν:=Expectation(x^2)-μ^2;
	return (μ,ν);
}
time psi --raw --expectation test.psi
(0,1)

So possibly this can help you out while you wait for further built-in support.

@Kwonsoo
Copy link
Author

Kwonsoo commented Dec 18, 2020

Thank you very much, Timon. It is a nice and simple way of getting those quantities.

But there is another concern. What PSI returns includes symbols as in 1/2, or √2, and so it is not so direct to process those returned quantities in some other procedures (in my case, in OCaml). Can we somehow set PSI to produce just (possibly rounded-up) floats? Probably it will not take too much efforts.

@Kwonsoo
Copy link
Author

Kwonsoo commented Dec 18, 2020

It seems like the writeln method takes some argument and writes the argument in the text format to the stdout, and when the argument is not the type of string, it calls the toString method of the argument first, and then print the tostring version of the argument.

What I want to do specifically is to print the variable expectation at line 146 of backend.d, with all the values in the tuple fully evaluated to float. What do you think will be the quickest workaround?

@tgehr
Copy link
Collaborator

tgehr commented Dec 18, 2020

Hi Gwonsoo, just put the following after line 146:

DExpr toFloat(DExpr e){
	auto h=e.getHoles!(x=>cast(Dℚ)x,Dℚ);
	auto r=h.expr;
	foreach(hole;h.holes){
		r=r.substitute(hole.var,dFloat(toReal(hole.expr.c)));
	}
	return r.simplify(one);
}
expectation=toFloat(expectation);

Maybe we can add something like this as a more general command-line option at some point. (Note: With the workaround above, the result is subject to round-off error, therefore sometimes not all printed significant digits are correct.)

@Kwonsoo
Copy link
Author

Kwonsoo commented Dec 24, 2020

Great workaround, and it works! Thank you so much for the workaround and the caution.

Thanks,
Gwonsoo

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

2 participants