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

sequence of Gamma distributions in Infer.NET #393

Closed
jacowp357 opened this issue Feb 10, 2022 · 3 comments
Closed

sequence of Gamma distributions in Infer.NET #393

jacowp357 opened this issue Feb 10, 2022 · 3 comments

Comments

@jacowp357
Copy link

jacowp357 commented Feb 10, 2022

Hi,

I would like to know if it's possible to model a Gamma process (i.e., a sequence of Gamma distributions) in Infer.NET similar to the Kalman Filter for the Gaussian distribution.

The mean of the Gamma in the next time step should be conditioned on the previous time step's Gamma. I'm not sure how to do this with the Gamma alpha and beta parameters. I guess the mean and variance parameters should work? Please let me know.

Here is my code:

double[] data = new double[] {
                0.592,
                0.708,
                0.789,
                0.621,
                0.873,
                1.074,
                4.634,
                3.945,
                2.118,
                4.207,
                2.884,
                1.462,
                2.851 };

            Range n = new Range(data.Length);

            VariableArray<double> nodes = Variable.Array<double>(n).Named("nodes");
            VariableArray<double> NoisyNodes = Variable.Array<double>(n).Named("NoisyNodes");
            

            using (var mblock = Variable.ForEach(n))
            {
                var i = mblock.Index;
                var mIs0 = (i == 0);
                var mIsGr = (i > 0);

                using (Variable.If(mIs0))
                {
                    nodes[n] = Variable.GammaFromMeanAndVariance(1, 1);
                }

                using (Variable.If(mIsGr))
                {
                    var prevM = i - 1;
                    nodes[n] = Variable.GammaFromMeanAndVariance(nodes[prevM], 1);
                }

                NoisyNodes[n] = Variable.GammaFromMeanAndVariance(nodes[n], 1);
            }

            NoisyNodes.ObservedValue = data;

            InferenceEngine engine = new InferenceEngine(new ExpectationPropagation());

            Gamma[] postNodes = engine.Infer<Gamma[]>(nodes);

            for (int i = 0; i < n.SizeAsInt; i++)
            {
                Console.WriteLine("{0}: {1}", data[i], postNodes[i]);
            }

This code gives the following error message:

Screenshot 2022-02-10 at 13 29 16

I have also tried Variational message passing and Gibbs sampling as well.

Kind regards,

Jaco

@tminka
Copy link
Contributor

tminka commented Feb 15, 2022

The issue here is that GammaFromMeanAndVariance does not handle stochastic arguments. Factors that handle stochastic arguments are listed on the List of factors and constraints. For example, you can make a Gamma with a stochastic rate, or multiply together two Gamma variables.

@jacowp357
Copy link
Author

I changed the code to multiply the Gammas as you suggested, but getting the error below which I'm unable to fix.

double[] data = new double[] {
                0.592,
                0.708,
                0.789,
                0.621,
                0.873,
                1.074,
                4.634,
                3.945,
                2.118,
                4.207,
                2.884,
                1.462,
                2.851 };

            Range n = new Range(data.Length);

            VariableArray<double> nodes = Variable.Array<double>(n).Named("nodes");
            //nodes[n] = Variable.GammaFromMeanAndVariance(1, 1).ForEach(n);
            VariableArray<double> NoisyNodes = Variable.Array<double>(n).Named("NoisyNodes");


            using (var mblock = Variable.ForEach(n))
            {
                var i = mblock.Index;
                var mIs0 = (i == 0);
                var mIsGr = (i > 0);

                using (Variable.If(mIs0))
                {
                    nodes[n] = Variable.GammaFromMeanAndVariance(1, 1);
                }

                using (Variable.If(mIsGr))
                {
                    var prevM = i - 1;
                    nodes[n] = nodes[prevM] * Variable.GammaFromMeanAndVariance(1, 1);
                }

                NoisyNodes[n] = nodes[n] * Variable.GammaFromMeanAndVariance(1, 1);
            }

            NoisyNodes.ObservedValue = data;

            InferenceEngine engine = new InferenceEngine(new ExpectationPropagation());

            Gamma[] postNodes = engine.Infer<Gamma[]>(nodes);

            for (int i = 0; i < n.SizeAsInt; i++)
            {
                Console.WriteLine("{0}: {1}", data[i], postNodes[i]);
            }

Screenshot 2022-02-15 at 15 36 08

@tminka
Copy link
Contributor

tminka commented Feb 16, 2022

Thanks, you found a bug in Infer.NET. You can work around it by initializing nodes. Here is one possible initialisation (it doesn't matter which):

            nodes[n].InitialiseTo(Variable<Gamma>.Factor(Gamma.PointMass, NoisyNodes[n]));

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