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

Update a model in Infer with a new observation #401

Closed
Vedrannb opened this issue Apr 1, 2022 · 1 comment
Closed

Update a model in Infer with a new observation #401

Vedrannb opened this issue Apr 1, 2022 · 1 comment

Comments

@Vedrannb
Copy link

Vedrannb commented Apr 1, 2022

Is there a possibility in INFER to update the model, for example here I determined the weights, means and posteriors from the data in mixed gaussian model.

// Define a range for the number of mixture components

            Variable<int> nK = Variable.Observed(2).Named("k");

            Range k = new Range(nK);

 

            // Mixture component means

            var meansVector = Variable.Observed(Vector.FromArray(0.0, 0.0)).Named("Means");

            var precsMatrix = Variable.Observed(PositiveDefiniteMatrix.IdentityScaledBy(2, 0.01)).Named("Precs");

 

            VariableArray<Vector> means = Variable.Array<Vector>(k).Named("mean");

            using (Variable.ForEach(k))

            {

                means[k] = Variable.VectorGaussianFromMeanAndPrecision(meansVector, precsMatrix);

            }

 

 

            double scaleValue = 100;

            var scaleInt = Variable.Observed(scaleValue).Named("Scale");

            var shapeMatrix = Variable.Observed(PositiveDefiniteMatrix.IdentityScaledBy(2, 0.01)).Named("Shape");

 

            // Mixture component precisions

            VariableArray<PositiveDefiniteMatrix> precs = Variable.Array<PositiveDefiniteMatrix>(k).Named("prec");

            using (Variable.ForEach(k))

            {

                precs[k] = Variable.WishartFromShapeAndScale(scaleInt, shapeMatrix);

            }

 

            // Mixture weights

            Variable<Vector> weights = Variable.Dirichlet(k, new double[] { 1, 1 }).Named("weights");

 

            // Create a variable array which will hold the data

            Variable<int> numData = Variable.Observed(300).Named("n");

            Range n = new Range(numData);

            VariableArray<Vector> data = Variable.Array<Vector>(n).Named("x");

 

            // Create latent indicator variable for each data point

            VariableArray<int> z = Variable.Array<int>(n).Named("z");

 

            // The mixture of Gaussians model

            using (Variable.ForEach(n))

            {

                z[n] = Variable.Discrete(weights);

                using (Variable.Switch(z[n]))

                {

                    data[n] = Variable.VectorGaussianFromMeanAndPrecision(means[z[n]], precs[z[n]]);

                }

            }

 

            // Attach some generated data

           data.ObservedValue = GenerateData(300);

 

            // Initialise messages randomly to break symmetry

            VariableArray<Discrete> zInit = Variable.Array<Discrete>(n).Named("zInit");

            zInit.ObservedValue = Util.ArrayInit(300, i => Discrete.PointMass(Rand.Int(2), 2));

            z[n].InitialiseTo(zInit[n]);

 

            // The inference

            InferenceEngine engine = new InferenceEngine();

            engine.Algorithm = new VariationalMessagePassing();

 

            var weights_infer = engine.Infer(weights);

            var means_infer = engine.Infer(means);

            var precs_infer = engine.Infer(precs);
public static Vector[] GenerateData(int nData)

        {

            Vector trueM1 = Vector.FromArray(2.0, 3.0);

            Vector trueM2 = Vector.FromArray(7.0, 5.0);

            PositiveDefiniteMatrix trueP1 = new PositiveDefiniteMatrix(

                new double[,] { { 3.0, 0.2 }, { 0.2, 2.0 } });

            PositiveDefiniteMatrix trueP2 = new PositiveDefiniteMatrix(

                new double[,] { { 2.0, 0.4 }, { 0.4, 4.0 } });

            VectorGaussian trueVG1 = VectorGaussian.FromMeanAndPrecision(trueM1, trueP1);

            VectorGaussian trueVG2 = VectorGaussian.FromMeanAndPrecision(trueM2, trueP2);

            double truePi = 0.6;

            Bernoulli trueB = new Bernoulli(truePi);

 

            // Restart the infer.NET random number generator

            Rand.Restart(12347);

            Vector[] data = new Vector[nData];

            for (int j = 0; j < nData; j++)

            {

                bool bSamp = trueB.Sample();

                data[j] = bSamp ? trueVG1.Sample() : trueVG2.Sample();

            }

 

            return data;

        }

Can I now enter a new data point (only one datapoint) in the model with the new inferred mean, precision and weights, and get completely new posteriors?

@tminka
Copy link
Contributor

tminka commented Apr 3, 2022

Yes, see Online learning.

@tminka tminka closed this as completed Mar 15, 2024
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