Example #1
0
        public Gamma InferPrecisionCustomFactor(double[] xObs, int epIteration,
                                                Type gammaOp = null)
        {
            Variable <int> dataCount = Variable.Observed(xObs.Length).Named("dataCount");
            Range          n         = new Range(dataCount).Named("n");

            Variable <double> precision = Variable <double> .Factor(
                CGFac.FromCompoundGamma);

//			Variable<double> precision = Variable<double>.Factor(
//				CGFac4.FromCompoundGamma,
//				CGParams.Shape1,
//				CGParams.Rate1,
//				CGParams.Shape2
//			);

            precision.AddAttribute(new TraceMessages());
            precision.AddAttribute(new MarginalPrototype(new Gamma()));
            VariableArray <double> x = Variable.Array <double>(n).Named("X");

            x[n]            = Variable.GaussianFromMeanAndPrecision(GaussMean, precision).ForEach(n);
            x.ObservedValue = xObs;

            InferenceEngine ie = new InferenceEngine();

            //http://research.microsoft.com/en-us/um/cambridge/projects/infernet/docs/Inference%20engine%20settings.aspx

            if (gammaOp != null)
            {
                ie.Compiler.GivePriorityTo(gammaOp);
            }
            else
            {
                ie.Compiler.GivePriorityTo(typeof(CGFacOp));
//				ie.Compiler.GivePriorityTo(typeof(CGFac4Op));
            }

            // If you want to debug into your generated inference code, you must set this to false:
            //			ie.Compiler.GenerateInMemory = false;
            //			ie.Compiler.WriteSourceFiles = true;
            //			ie.Compiler.GeneratedSourceFolder = Config.PathToCompiledModelFolder();
            ie.Compiler.GenerateInMemory = false;
            ie.Compiler.WriteSourceFiles = true;

            ie.Compiler.IncludeDebugInformation = true;
            //			ie.Algorithm = new VariationalMessagePassing();
            ie.Algorithm = new ExpectationPropagation();
            //			ie.ModelName = "KEPBinaryLogistic";
            ie.NumberOfIterations = epIteration;
            //			ie.ShowFactorGraph = true;
            ie.ShowWarnings = true;
            ie.ModelName    = "CompoundGammaCustom";
            ie.ShowTimings  = true;
            //			ie.Compiler.UseParallelForLoops = true;

            Gamma postPrec = ie.Infer <Gamma>(precision);

            return(postPrec);
        }
Example #2
0
        private void OnlineLearningWithCompoundGammaPrecision(IAlgorithm algorithm)
        {
            Variable <int>    nItems    = Variable.New <int>().Named("nItems");
            Range             item      = new Range(nItems).Named("item");
            Variable <double> shape     = Variable.Observed(1.0).Named("shape");
            Gamma             ratePrior = Gamma.FromShapeAndRate(1, 1);
            Variable <double> rate      = Variable <double> .Random(ratePrior).Named("rate");

            Variable <double>      prec = Variable.GammaFromShapeAndRate(shape, rate).Named("prec");
            VariableArray <double> x    = Variable.Array <double>(item).Named("x");

            x[item] = Variable.GaussianFromMeanAndPrecision(0, prec).ForEach(item);
            Variable <Gamma> precMessage = Variable.Observed <Gamma>(Gamma.Uniform()).Named("precMessage");

            Variable.ConstrainEqualRandom(prec, precMessage);
            prec.AddAttribute(QueryTypes.Marginal);
            prec.AddAttribute(QueryTypes.MarginalDividedByPrior);
            InferenceEngine engine = new InferenceEngine(algorithm);

            engine.ModelName    = "GaussianWithCompoundGammaPrecision";
            engine.ShowProgress = false;

            // inference on a single batch
            double[] data = { 2, 3, 4, 5 };
            x.ObservedValue      = data;
            nItems.ObservedValue = data.Length;
            Gamma precExpected = engine.Infer <Gamma>(prec);

            // online learning in mini-batches
            int batchSize = 1;

            double[][] dataBatches = new double[data.Length / batchSize][];
            for (int batch = 0; batch < dataBatches.Length; batch++)
            {
                dataBatches[batch] = data.Skip(batch * batchSize).Take(batchSize).ToArray();
            }
            Gamma precMarginal = Gamma.Uniform();

            for (int batch = 0; batch < dataBatches.Length; batch++)
            {
                nItems.ObservedValue = dataBatches[batch].Length;
                x.ObservedValue      = dataBatches[batch];
                precMarginal         = engine.Infer <Gamma>(prec);
                Console.WriteLine("prec after batch {0} = {1}", batch, precMarginal);
                precMessage.ObservedValue = engine.Infer <Gamma>(prec, QueryTypes.MarginalDividedByPrior);
            }
            // the answers should be identical for this simple model
            Console.WriteLine("prec = {0} should be {1}", precMarginal, precExpected);
            Assert.True(precExpected.MaxDiff(precMarginal) < 1e-10);
        }
 private Variable CreateVariableForField(FieldRef fref)
 {
     Variable var = new Variable(fref.Type)
     {
         Name = fref.Name,
         LocalIndex = _nextLocIndex++,
         InitialValue = fref.FieldDesc.ConstantValue
     };
     var.AddAttribute(fref);
     foreach (var attr in fref.Attributes)
         var.AddAttribute(attr);
     DeclareLocal(var);
     return var;
 }
Example #4
0
        public void OnlineLearningWithLaplacianMean()
        {
            Variable <int>         nItems   = Variable.New <int>().Named("nItems");
            Range                  item     = new Range(nItems).Named("item");
            Variable <double>      variance = Variable.GammaFromShapeAndRate(1.0, 1.0).Named("variance");
            Variable <double>      mean     = Variable.GaussianFromMeanAndVariance(0.0, variance).Named("mean");
            VariableArray <double> x        = Variable.Array <double>(item).Named("x");

            x[item] = Variable.GaussianFromMeanAndPrecision(mean, 1.0).ForEach(item);

            Variable <Gaussian> meanMessage = Variable.Observed <Gaussian>(Gaussian.Uniform()).Named("meanMessage");

            Variable.ConstrainEqualRandom(mean, meanMessage);
            mean.AddAttribute(QueryTypes.Marginal);
            mean.AddAttribute(QueryTypes.MarginalDividedByPrior);
            InferenceEngine engine = new InferenceEngine();

            engine.ModelName    = "OnlineLearningWithLaplacianMean";
            engine.ShowProgress = false;

            // inference on a single batch
            double[] data = { 2, 3, 4, 5 };
            x.ObservedValue      = data;
            nItems.ObservedValue = data.Length;
            Gaussian meanExpected = engine.Infer <Gaussian>(mean);

            // online learning in mini-batches
            int batchSize = 1;

            double[][] dataBatches = new double[data.Length / batchSize][];
            for (int batch = 0; batch < dataBatches.Length; batch++)
            {
                dataBatches[batch] = data.Skip(batch * batchSize).Take(batchSize).ToArray();
            }
            Gaussian meanMarginal = Gaussian.Uniform();

            for (int batch = 0; batch < dataBatches.Length; batch++)
            {
                nItems.ObservedValue = dataBatches[batch].Length;
                x.ObservedValue      = dataBatches[batch];
                meanMarginal         = engine.Infer <Gaussian>(mean);
                Console.WriteLine("mean after batch {0} = {1}", batch, meanMarginal);
                meanMessage.ObservedValue = engine.Infer <Gaussian>(mean, QueryTypes.MarginalDividedByPrior);
            }
            // the answers should be identical for this simple model
            Console.WriteLine("mean = {0} should be {1}", meanMarginal, meanExpected);
            Assert.True(meanExpected.MaxDiff(meanMarginal) < 1e-10);
        }
Example #5
0
        public static void TestMixtureOf2Gaussians()
        {
            int            mixtureSize = 2;
            Range          r           = new Range(mixtureSize);
            Variable <int> comp        = Variable <int> .Discrete(r, new double[] { 0.5, 0.5 });

            Variable <double> x = Variable <double> .New <double>().Named("x");

            double[] means = new double[] { 1, 2 };
            VariableArray <double> Means = Variable.Observed(means, r);

            using (Variable.Switch(comp)){
                x.SetTo(Variable.GaussianFromMeanAndPrecision(Means[comp], 1));
            }
            x.AddAttribute(new TraceMessages());

            InferenceEngine engine = new InferenceEngine();

            engine.OptimiseForVariables             = new[] { x };
            engine.Compiler.IncludeDebugInformation = true;
            engine.Algorithm   = new GibbsSampling();
            engine.ModelName   = "MyMixtureOf2Gaussians";
            engine.ShowTimings = true;
//			engine.ShowMsl = true;
//			InferenceEngine.ShowFactorManager(true);
            // this gives a Gaussian with mean 1.5
            Console.WriteLine("inferred x = " + engine.Infer(x));
            // How to get a Gaussian mixture ????
            // => put prior on means and infer the the distribution on means instead
        }
Example #6
0
        /// <summary>
        /// Test modified EP updates
        /// </summary>
        internal void StudentIsPositiveTest()
        {
            double shape     = 1;
            Gamma  precPrior = Gamma.FromShapeAndRate(shape, shape);
            // mean=-1 causes improper messages
            double   mean = -1;
            double   evExpected;
            Gaussian xExpected = StudentIsPositiveExact(mean, precPrior, out evExpected);

            Variable <bool>   evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock           block    = Variable.If(evidence);
            Variable <double> prec     = Variable.Random(precPrior).Named("prec");
            Variable <double> x        = Variable.GaussianFromMeanAndPrecision(mean, prec).Named("x");

            Variable.ConstrainPositive(x);
            block.CloseBlock();

            InferenceEngine engine = new InferenceEngine();

            x.AddAttribute(new TraceMessages());
            //x.InitialiseTo(Gaussian.FromMeanAndVariance(-3.719, 4.836));
            //GaussianOp.ForceProper = false;
            //GaussianOp.modified = true;
            //engine.Compiler.GivePriorityTo(typeof(GaussianOp_Laplace));
            //engine.Compiler.GivePriorityTo(typeof(GaussianOp_Slow));
            GaussianOp_Laplace.modified  = true;
            GaussianOp_Laplace.modified2 = true;
            Console.WriteLine("x = {0} should be {1}", engine.Infer(x), xExpected);
            double evActual = System.Math.Exp(engine.Infer <Bernoulli>(evidence).LogOdds);

            Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
        }
Example #7
0
        private Variable CreateVariableForField(FieldRef fref)
        {
            Variable var = new Variable(fref.Type)
            {
                Name         = fref.Name,
                LocalIndex   = _nextLocIndex++,
                InitialValue = fref.FieldDesc.ConstantValue
            };

            var.AddAttribute(fref);
            foreach (var attr in fref.Attributes)
            {
                var.AddAttribute(attr);
            }
            DeclareLocal(var);
            return(var);
        }
Example #8
0
        /// <summary>
        /// Test a difficult case
        /// </summary>
        internal void StudentIsPositiveTest5()
        {
            // depending on the exact setting of priors, the messages will alternate between proper and improper
            Gamma precPrior = new Gamma(5, 0.2);
            // mean=-1 causes improper messages
            var               mean     = Variable.Random(new Gaussian(-0.9, 0.25)).Named("mean");
            Variable <bool>   evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock           block    = Variable.If(evidence);
            Variable <double> prec     = Variable.Random(precPrior).Named("prec");
            Variable <double> x        = Variable.GaussianFromMeanAndPrecision(mean, prec).Named("x");
            Variable <bool>   y        = Variable.IsPositive(x);

            Variable.ConstrainEqualRandom(y, new Bernoulli(0.8889));
            block.CloseBlock();

            InferenceEngine engine = new InferenceEngine();

            x.AddAttribute(new TraceMessages());
            Console.WriteLine(engine.Infer(x));
            //Console.WriteLine("x = {0} should be {1}", engine.Infer(x), xExpected);
            double evActual = System.Math.Exp(engine.Infer <Bernoulli>(evidence).LogOdds);
            //Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
        }
Example #9
0
        private void BugsRats(bool initialiseAlpha, bool initialiseAlphaC)
        {
            Rand.Restart(0);
            double precOfGaussianPrior   = 1.0E-6;
            double shapeRateOfGammaPrior = 0.02; // smallest choice that will avoid zeros

            double meanOfBetaPrior  = 0.0;
            double meanOfAlphaPrior = 0.0;

            // The model
            int    N    = RatsHeightData.GetLength(0);
            int    T    = RatsHeightData.GetLength(1);
            double xbar = 22.0;

            double[] xDataZeroMean = new double[RatsXData.Length];
            for (int i = 0; i < RatsXData.Length; i++)
            {
                xDataZeroMean[i] = RatsXData[i] - xbar;
            }
            Range r = new Range(N).Named("N");
            Range w = new Range(T).Named("T");
            VariableArray2D <double> y        = Variable.Observed <double>(RatsHeightData, r, w).Named("y");
            VariableArray <double>   x        = Variable.Observed <double>(xDataZeroMean, w).Named("x");
            Variable <double>        tauC     = Variable.GammaFromShapeAndRate(shapeRateOfGammaPrior, shapeRateOfGammaPrior).Named("tauC");
            Variable <double>        alphaC   = Variable.GaussianFromMeanAndPrecision(meanOfAlphaPrior, precOfGaussianPrior).Named("alphaC");
            Variable <double>        alphaTau = Variable.GammaFromShapeAndRate(shapeRateOfGammaPrior, shapeRateOfGammaPrior).Named("alphaTau");
            Variable <double>        betaC    = Variable.GaussianFromMeanAndPrecision(meanOfBetaPrior, precOfGaussianPrior).Named("betaC");
            Variable <double>        betaTau  = Variable.GammaFromShapeAndRate(shapeRateOfGammaPrior, shapeRateOfGammaPrior).Named("betaTau");
            VariableArray <double>   alpha    = Variable.Array <double>(r).Named("alpha");

            alpha[r] = Variable.GaussianFromMeanAndPrecision(alphaC, alphaTau).ForEach(r);
            VariableArray <double> beta = Variable.Array <double>(r).Named("beta");

            beta[r] = Variable.GaussianFromMeanAndPrecision(betaC, betaTau).ForEach(r);
            VariableArray2D <double> mu    = Variable.Array <double>(r, w).Named("mu");
            VariableArray2D <double> betaX = Variable.Array <double>(r, w).Named("betax");

            betaX[r, w] = beta[r] * x[w];
            mu[r, w]    = alpha[r] + betaX[r, w];
            y[r, w]     = Variable.GaussianFromMeanAndPrecision(mu[r, w], tauC);
            Variable <double> alpha0 = (alphaC - xbar * betaC).Named("alpha0");

            InferenceEngine ie;
            GibbsSampling   gs = new GibbsSampling();
            // Initialise both alpha and beta together.
            // Initialising only alpha (or only beta) is not reliable because you could by chance get a large betaTau and small tauC to start,
            // at which point beta and alphaC become garbage, leading to alpha becoming garbage on the next iteration.
            bool initialiseBeta  = initialiseAlpha;
            bool initialiseBetaC = initialiseAlphaC;

            if (initialiseAlpha)
            {
                Gaussian[] alphaInit = new Gaussian[N];
                for (int i = 0; i < N; i++)
                {
                    alphaInit[i] = Gaussian.FromMeanAndPrecision(250.0, 1.0);
                }
                alpha.InitialiseTo(Distribution <double> .Array(alphaInit));
            }
            if (initialiseBeta)
            {
                Gaussian[] betaInit = new Gaussian[N];
                for (int i = 0; i < N; i++)
                {
                    betaInit[i] = Gaussian.FromMeanAndPrecision(6.0, 1.0);
                }
                beta.InitialiseTo(Distribution <double> .Array(betaInit));
            }
            if (initialiseAlphaC)
            {
                alphaC.InitialiseTo(Gaussian.FromMeanAndVariance(250.0, 1.0));
            }
            if (initialiseBetaC)
            {
                betaC.InitialiseTo(Gaussian.FromMeanAndVariance(6.0, 1.0));
            }
            if (false)
            {
                //tauC.InitialiseTo(Gamma.FromMeanAndVariance(1.0, 0.1));
                //alphaTau.InitialiseTo(Gamma.FromMeanAndVariance(1.0, 0.1));
                //betaTau.InitialiseTo(Gamma.FromMeanAndVariance(1.0, 0.1));
            }
            if (!initialiseAlpha && !initialiseBeta && !initialiseAlphaC && !initialiseBetaC)
            {
                gs.BurnIn = 1000;
            }
            ie = new InferenceEngine(gs);
            ie.ShowProgress         = false;
            ie.ModelName            = "BugsRats";
            ie.NumberOfIterations   = 4000;
            ie.OptimiseForVariables = new List <IVariable>()
            {
                alphaC, betaC, alpha0, tauC
            };
            betaC.AddAttribute(QueryTypes.Marginal);
            betaC.AddAttribute(QueryTypes.Samples);
            alpha0.AddAttribute(QueryTypes.Marginal);
            alpha0.AddAttribute(QueryTypes.Samples);
            tauC.AddAttribute(QueryTypes.Marginal);
            tauC.AddAttribute(QueryTypes.Samples);

            // Inference
            object   alphaCActual = ie.Infer(alphaC);
            Gaussian betaCMarg    = ie.Infer <Gaussian>(betaC);
            Gaussian alpha0Marg   = ie.Infer <Gaussian>(alpha0);
            Gamma    tauCMarg     = ie.Infer <Gamma>(tauC);

            // Check results against BUGS
            Gaussian betaCExpected     = new Gaussian(6.185, System.Math.Pow(0.1068, 2));
            Gaussian alpha0Expected    = new Gaussian(106.6, System.Math.Pow(3.625, 2));
            double   sigmaMeanExpected = 6.082;
            double   sigmaMean         = System.Math.Sqrt(1.0 / tauCMarg.GetMean());

            if (!initialiseAlpha && !initialiseAlphaC)
            {
                Debug.WriteLine("betaC = {0} should be {1}", betaCMarg, betaCExpected);
                Debug.WriteLine("alpha0 = {0} should be {1}", alpha0Marg, alpha0Expected);
            }
            Assert.True(GaussianDiff(betaCExpected, betaCMarg) < 0.1);
            Assert.True(GaussianDiff(alpha0Expected, alpha0Marg) < 0.1);
            Assert.True(MMath.AbsDiff(sigmaMeanExpected, sigmaMean, 0.1) < 0.1);

            IList <double> betaCSamples  = ie.Infer <IList <double> >(betaC, QueryTypes.Samples);
            IList <double> alpha0Samples = ie.Infer <IList <double> >(alpha0, QueryTypes.Samples);
            IList <double> tauCSamples   = ie.Infer <IList <double> >(tauC, QueryTypes.Samples);

            GaussianEstimator est = new GaussianEstimator();

            foreach (double sample in betaCSamples)
            {
                est.Add(sample);
            }
            Gaussian betaCMarg2 = est.GetDistribution(new Gaussian());

            Assert.True(GaussianDiff(betaCMarg, betaCMarg2) < 0.1);
        }
Example #10
0
        public static void RunOnlineKEPDotNet()
        {
            // KJIT with Infer.NET oracle

            // Compile model only once. In this model, only one message can
            // be collected from one EP problem.
            Variable <int>    dataCount = Variable.Observed(-1).Named("dataCount");
            Range             n         = new Range(dataCount).Named("N");
            Variable <double> precision = Variable <double> .Factor(CGFac.FromCompoundGamma);

            precision.AddAttribute(new TraceMessages());
            precision.AddAttribute(new MarginalPrototype(new Gamma()));
            VariableArray <double> x = Variable.Array <double>(n).Named("X");

            x[n] = Variable.GaussianFromMeanAndPrecision(GaussMean, precision).ForEach(n);


            // Create the  operator instance only once because we want to use the same
            // one after a new problem (new seed).
            // stopwatch for measuring inference time for each problem
            Stopwatch   watch  = new Stopwatch();
            CGOpRecords record = new CGOpRecords();
            var         opIns  = new KEP_CGFacOpIns(onlineBatchSizeTrigger, record, watch, initialThreshold);

            opIns.IsPrintTrueWhenCertain = true;
            opIns.IsRecordMessages       = true;

            //---- records -----
            List <long> allInferTimes       = new List <long>();
            List <long> allOracleInferTimes = new List <long>();
//			List<Dictionary<string, object>> allExtras = new List<Dictionary<string, object>>();
            var allPosteriors       = new List <Gamma>();
            var allOraclePosteriors = new List <Gamma>();

            int[]           Ns         = new int[seed_to];
            double[]        trueRate2s = new double[seed_to];
            double[]        truePrecs  = new double[seed_to];
            List <double[]> allObs     = new List <double[]>();

            //---------------

            OpControl.Set(typeof(KEP_CGFacOp), opIns);

            // one engine means the initial model compilation is done only once
            InferenceEngine ie = NewInferenceEngine("KJIT_CG");

            ie.Compiler.GivePriorityTo(typeof(KEP_CGFacOp));

            // engine for the oracle
            InferenceEngine dnetIe = NewInferenceEngine("Oracle_CG");

            dnetIe.Compiler.GivePriorityTo(typeof(CGFacOp));

            Random precRand = new Random(1);

            for (int seed = 1; seed <= seed_to; seed++)
            {
                int i = seed - 1;
                Rand.Restart(seed);
                // n is between 10 and 100 for. Could be different for each seed.
                int N = Rand.Int(10, 100 + 1);
                Console.WriteLine("\n    ///// New compound Gamma problem {0} of size: {1}  /////\n",
                                  seed, N);
                Ns[i] = N;
                CompoundGamma cg = new CompoundGamma();

                double   trueR2, truePrec;
                double[] obs;
                cg.GenData(N, seed, out obs, out trueR2, out truePrec);

                // Draw a number uniformly from log(1e-4)
                // to log(1e4) and exp(.) it to get the precision.
//				double logPrec = precRand.NextDouble()*(Math.Log(1e4) - Math.Log(1e-4)) + Math.Log(1e-4);
//				double truePrec = Math.Exp(logPrec);
//				double[] obs = CompoundGamma.DrawFromGaussian(GaussMean, truePrec, N);

                allObs.Add(obs);
//				trueRate2s[i] = trueR2;
                truePrecs[i] = truePrec;

                dataCount.ObservedValue = N;
                x.ObservedValue         = obs;

                //				Console.Write("observations: ");
                //				StringUtils.PrintArray(obs);
                //			ie.Compiler.UseParallelForLoops = true;
                watch.Restart();
                Gamma postPrec      = ie.Infer <Gamma>(precision);
                long  inferenceTime = watch.ElapsedMilliseconds;

                allInferTimes.Add(inferenceTime);
                allPosteriors.Add(postPrec);


//				// Run Infer.net's operator on the same data
                Stopwatch dnetWatch = new Stopwatch();
//
                dataCount.ObservedValue = N;
                x.ObservedValue         = obs;
                dnetWatch.Start();
                Gamma dnetPost = dnetIe.Infer <Gamma>(precision);
                long  dnetTime = dnetWatch.ElapsedMilliseconds;
                allOracleInferTimes.Add(dnetTime);
                allOraclePosteriors.Add(dnetPost);


                //print
                Console.WriteLine("seed: {0}", seed);
                Console.WriteLine("n: {0}", N);
//				Console.WriteLine("True r2: {0}", trueR2);
                Console.WriteLine("True precision: {0}", truePrec);
                Console.WriteLine("Inferred precision posterior: {0}", postPrec);
                Console.WriteLine("Infer.NET posterior: {0}", dnetPost);
                Console.WriteLine("Inference time: {0} ms", inferenceTime);
                Console.WriteLine("Infer.NET time: {0} ms", dnetTime);
                Console.WriteLine("=========================");
                Console.WriteLine();
            }

            // MatlabWriter cannot write int
            var extra = new Dictionary <string, object>();

            extra.Add("inferTimes", MatrixUtils.ToDouble(allInferTimes));
            extra.Add("oraInferTimes", MatrixUtils.ToDouble(allOracleInferTimes));
            double[] postShapes, postRates;
            double[] oraPostShapes, oraPostRates;
            CGOpRecords.GammaListToArrays(allPosteriors, out postShapes, out postRates);
            CGOpRecords.GammaListToArrays(allOraclePosteriors, out oraPostShapes, out oraPostRates);
            extra.Add("postShapes", postShapes);
            extra.Add("postRates", postRates);
            extra.Add("oraPostShapes", oraPostShapes);
            extra.Add("oraPostRates", oraPostRates);
            extra.Add("Ns", MatrixUtils.ToDoubleArray(Ns));
            extra.Add("trueRate2s", trueRate2s);
            extra.Add("truePrecs", truePrecs);

            // MatlabWriter cannot write List<Vector> or List<double[]>. Why ?
//			List<Vector> allObsVec = allObs.Select(ob => Vector.FromArray(ob)).ToList();
//			extra.Add("allObs", allObsVec);

            // write the records to a file

            string fname = string.Format("kjit_cg_iter{0}_bt{1}_st{2}.mat",
                                         epIter, onlineBatchSizeTrigger, seed_to);
            string recordPath = Config.PathToSavedFile(fname);

            record.WriteRecords(recordPath, extra);
        }
Example #11
0
        public LogisticIrtModel(int numParams, PriorType priorType)
        {
            numStudents = Variable.New <int>().Named("numStudents");
            Range student = new Range(numStudents);

            abilityMean      = Variable.GaussianFromMeanAndVariance(0, 1e6).Named("abilityMean");
            abilityPrecision = Variable.GammaFromShapeAndRate(1, 1).Named("abilityPrecision");
            ability          = Variable.Array <double>(student).Named("ability");
            bool useTruncatedGaussianPrior = false;
            bool useMixturePrior           = false;

            if (!useTruncatedGaussianPrior && !useMixturePrior)
            {
                ability[student] = Variable.GaussianFromMeanAndPrecision(abilityMean, abilityPrecision).ForEach(student);
            }
            else if (useTruncatedGaussianPrior)
            {
                // truncated Gaussian prior for ability
                double threshold, m, v;
                bool   mildSkew = false;
                if (mildSkew)
                {
                    // matched to Mild_skew generator
                    threshold = -1.6464;
                    m         = -0.4;
                    v         = 1.5;
                }
                else
                {
                    // matched to Extreme_skew generator
                    threshold = -1.0187;
                    m         = -10;
                    v         = 10;
                }
                VariableArray <double> abilityTrunc = Variable.Array <double>(student).Named("abilityTrunc");
                abilityTrunc[student] = Variable.TruncatedGaussian(m, v, threshold, double.PositiveInfinity).ForEach(student);
                ability[student]      = Variable.Copy(abilityTrunc[student]);
                ability.AddAttribute(new MarginalPrototype(new Gaussian()));
            }
            else
            {
                // mixture
                abilityMean2      = Variable.GaussianFromMeanAndVariance(0, 1e6).Named("abilityMean2");
                abilityPrecision2 = Variable.GammaFromShapeAndRate(1, 1).Named("abilityPrecision2");
                Variable <double> weight2 = Variable.Beta(1, 1).Named("weight2");
                isExceptional     = Variable.Array <bool>(student).Named("isExceptional");
                isExceptionalInit = Variable.New <IDistribution <bool[]> >();
                isExceptional.InitialiseTo(isExceptionalInit);
                using (Variable.ForEach(student)) {
                    isExceptional[student] = Variable.Bernoulli(weight2);
                    using (Variable.If(isExceptional[student])) {
                        ability[student] = Variable.GaussianFromMeanAndPrecision(abilityMean2, abilityPrecision2);
                    }
                    using (Variable.IfNot(isExceptional[student])) {
                        ability[student] = Variable.GaussianFromMeanAndPrecision(abilityMean, abilityPrecision);
                    }
                }
            }
            numQuestions = Variable.New <int>().Named("numQuestions");
            Range question = new Range(numQuestions);

            difficultyMean           = Variable.GaussianFromMeanAndVariance(0, 1e6).Named("difficultyMean");
            difficultyPrecision      = Variable.GammaFromShapeAndRate(1, 1).Named("difficultyPrecision");
            difficulty               = Variable.Array <double>(question).Named("difficulty");
            difficulty[question]     = Variable.GaussianFromMeanAndPrecision(difficultyMean, difficultyPrecision).ForEach(question);
            discriminationMean       = Variable.GaussianFromMeanAndVariance(0, 1e6).Named("discriminationMean");
            discriminationPrecision  = Variable.GammaFromShapeAndRate(1, 1).Named("discriminationPrecision");
            discrimination           = Variable.Array <double>(question).Named("discrimination");
            discrimination[question] = Variable.Exp(Variable.GaussianFromMeanAndPrecision(discriminationMean, discriminationPrecision).ForEach(question));
            guessProb           = Variable.Array <double>(question).Named("guessProb");
            guessProb[question] = Variable.Beta(2, 12).ForEach(question);
            response            = Variable.Array <bool>(student, question).Named("response");
            if (numParams == 1)
            {
                response[student, question] = Variable.BernoulliFromLogOdds(ability[student] - difficulty[question]);
            }
            else if (numParams == 2)
            {
                response[student, question] = Variable.BernoulliFromLogOdds(((ability[student] - difficulty[question]).Named("minus") * discrimination[question]).Named("product"));
            }
            else if (numParams == 3)
            {
                using (Variable.ForEach(student))
                {
                    using (Variable.ForEach(question))
                    {
                        Variable <bool> guess = Variable.Bernoulli(guessProb[question]);
                        using (Variable.If(guess))
                        {
                            response[student, question] = Variable.Bernoulli(1 - 1e-10);
                        }
                        using (Variable.IfNot(guess))
                        {
                            Variable <double> score = (ability[student] - difficulty[question]) * discrimination[question];
                            score.Name = "score";
                            // explicit MarginalPrototype is needed when ability and difficulty are observed
                            score.AddAttribute(new MarginalPrototype(new Gaussian()));
                            response[student, question] = Variable.BernoulliFromLogOdds(score);
                        }
                    }
                }
            }
            else
            {
                throw new ArgumentException($"Unsupported number of parameters: {numParams}");
            }
            if (priorType == PriorType.Standard)
            {
                // standard normal prior
                abilityMean.ObservedValue             = 0;
                abilityPrecision.ObservedValue        = 1;
                difficultyMean.ObservedValue          = 0;
                difficultyPrecision.ObservedValue     = 1;
                discriminationMean.ObservedValue      = 0;
                discriminationPrecision.ObservedValue = 4 * 4;
            }
            else if (priorType == PriorType.Vague)
            {
                // vague prior
                abilityMean.ObservedValue         = 0;
                abilityPrecision.ObservedValue    = 1e-6;
                difficultyMean.ObservedValue      = 0;
                difficultyPrecision.ObservedValue = 1e-6;
                discriminationMean.ObservedValue  = 0;
                // must have exp(var) be finite, i.e. var <= 709, precision > 1.5e-3
                discriminationPrecision.ObservedValue = 1.5e-2;
            }
            else if (priorType == PriorType.StandardVague)
            {
                abilityMean.ObservedValue             = 0;
                abilityPrecision.ObservedValue        = 1;
                difficultyMean.ObservedValue          = 0;
                difficultyPrecision.ObservedValue     = 1e-6;
                discriminationMean.ObservedValue      = 0;
                discriminationPrecision.ObservedValue = 1.5e-2;
            }
            else if (priorType == PriorType.VagueStandard)
            {
                abilityMean.ObservedValue             = 0;
                abilityPrecision.ObservedValue        = 1e-6;
                difficultyMean.ObservedValue          = 0;
                difficultyPrecision.ObservedValue     = 1;
                discriminationMean.ObservedValue      = 0;
                discriminationPrecision.ObservedValue = 4 * 4;
            }
            else if (priorType == PriorType.Standard5)
            {
                abilityMean.ObservedValue             = 0;
                abilityPrecision.ObservedValue        = 1;
                difficultyMean.ObservedValue          = 0;
                difficultyPrecision.ObservedValue     = 1.0 / 25;
                discriminationMean.ObservedValue      = 0;
                discriminationPrecision.ObservedValue = 4 * 4;
            }
            else if (priorType == PriorType.Hierarchical)
            {
                // do nothing
            }
            else
            {
                throw new ArgumentException($"priorType {priorType} is not supported");
            }
            engine = new InferenceEngine();
        }