//        /// <summary>
        //        /// Gets the value of information.
        //        /// </summary>
        //        /// <value>The value of information.</value>
        //        public double[] GetValueOfInformation()
        //        {
        //            double jall = JAll();
        //            return Unlabelled.Select(index => VOI(jall, index)).ToArray();
        //        }
        /// <summary>
        /// Gets the argument maxising the Value of information.
        /// </summary>
        /// <param name="activityPosteriors">Activity posteriors.</param>
        /// <param name="priors">Priors.</param>
        /// <param name="argMax">Argument max.</param>
        /// <param name="maxVal">Max value.</param>
        public override void GetArgMaxVOI(Bernoulli[] activityPosteriors, Marginals priors, out int argMax, out double maxVal)
        {
            hypothesisActivityPosteriors = activityPosteriors.Select(ia => new Bernoulli(ia)).ToArray();
            double jall = JAll();

            var unlabelled = Unlabelled.ToArray();
            argMax = -1;
            maxVal = Reversed ? double.PositiveInfinity : double.NegativeInfinity;

            var signs = new double[unlabelled.Length];
            var vois = new double[unlabelled.Length];

            for (int i = 0; i < unlabelled.Length; i++)
            {
                var index = unlabelled[i];
                vois[i] = VOI(jall, index, activityPosteriors, priors);
                signs[i] = Math.Sign(vois[i]) / 2.0 + 0.5;
                //Console.Write( "." );
                //Console.WriteLine( "y_true: {0}", labels[0][ind] );
                //Console.WriteLine( "y_hat: {0}", probs[ind] );
                //Console.WriteLine( "VOJ_{0}: {1}", ind, voi );
                //Console.WriteLine();
                if (Reversed)
                {
                    if (vois[i] < maxVal || argMax < 0)
                    {
                        maxVal = vois[i];
                        argMax = index;
                    }
                }
                else
                {
                    if (vois[i] > maxVal || argMax < 0)
                    {
                        maxVal = vois[i];
                        argMax = index;
                    }
                }
            }

            //Console.WriteLine();
            //Console.WriteLine( "\n+ivity: {0}", signs.Average() );
        }
        private double JAll_j(int index, Bernoulli[] activityPosteriors, Marginals priors)
        {
            // var prevProbs = activityPosteriors.Select(ia => new Bernoulli(ia)).ToArray();
            hypothesisActivityPosteriors = activityPosteriors.Select(ia => new Bernoulli(ia)).ToArray();

            // Get datum
            // var datum = DataSet.GetSubSet(0, index);
            bool trueLabel = DataSet.Labels[0][index];

            // Create copies of the Labelled an Unlabelled sets
            var labelled = new HashSet<int>(Labelled);
            var unlabelled = new HashSet<int>(Unlabelled);

            labelled.Add(index);
            unlabelled.Remove(index);

            // datum.Labels[0][0] = true;
            DataSet.Labels[0][index] = true;

            // Learn as if positive
            // var positivePosteriors = TrainModel.Train(datum, priors, 1);
            Marginals positivePosteriors = priors;

            try
            {
                positivePosteriors = TrainModel.Train(DataSet.GetSubSet(0, index), priors, 1);
            }
            catch (ImproperMessageException)
            {
                // As fallback use priors
            }

            // recompute probabilities
            CalculateProbabilities(positivePosteriors);

            //var jjposl = JL(labelled);
            //var jjposu = JU(unlabelled);
            var Jjpos = (JAll()) * (1.0 - hypothesisActivityPosteriors[index].GetMean());

            // Restore posteriors

            labelled.Add(index);
            unlabelled.Remove(index);

            // datum.Labels[0][0] = false;
            DataSet.Labels[0][index] = false;

            // Learn as if negative
            // var negativePosteriors = TrainModel.Train(datum, priors, 1);
            Marginals negativePosteriors = priors;
            try
            {
                negativePosteriors = TrainModel.Train(DataSet.GetSubSet(0, index), priors, 1);
            }
            catch (ImproperMessageException)
            {
                // As fallback use priors
            }

            // recompute probabilities
            CalculateProbabilities(negativePosteriors);

            //var jjnegl = JL(labelled);
            //var jjnegu = JU(unlabelled);
            var Jjneg = (JAll()) * (hypothesisActivityPosteriors[index].GetMean());

            // restore posteriors
            // activityPosteriors = prevProbs;
            DataSet.Labels[0][index] = trueLabel;

            var voi = Jjpos + Jjneg;

            return voi;
        }
Example #3
0
        /// <summary>
        /// Tests the binary hidden markov model.
        /// </summary>
        public static void TestBinaryHiddenMarkovModel()
        {
            // fix random seed
            Rand.Restart(12347);

            // model size
            const int T = 100;
            const int K = 2;

            // set hyperparameters
            var probInitPriorObs = Dirichlet.Uniform(K);
            var cptTransPriorObs = Enumerable.Repeat(Dirichlet.Uniform(K), K).ToArray();
            var emitPriorObs     = Enumerable.Repeat(new Beta(1, 1), K).ToArray();

            // sample model parameters
            var init  = probInitPriorObs.Sample().ToArray();
            var trans = new double[K][];

            for (int i = 0; i < K; i++)
            {
                trans[i] = cptTransPriorObs[i].Sample().ToArray();
            }

            var emit = new double[K];

            for (int i = 0; i < K; i++)
            {
                emit[i] = emitPriorObs[i].Sample();
            }

            // print parameters
            var modelForPrinting = new BinaryHMM();

            modelForPrinting.CreateModel(T, K, 1, false);
            modelForPrinting.SetParameters(init, trans, emit, null);
            Console.WriteLine("parameters:");
            modelForPrinting.PrintParameters();
            Console.WriteLine();

            // create distributions for sampling
            var initDist  = new Discrete(init);
            var transDist = new Discrete[K];

            for (int i = 0; i < K; i++)
            {
                transDist[i] = new Discrete(trans[i]);
            }

            var emitDist = new Bernoulli[K];

            for (int i = 0; i < K; i++)
            {
                emitDist[i] = new Bernoulli(emit[i]);
            }

            // calculate order of actual states
            var actualStateOrder = emitDist.Select((ia, i) => new { ia, i }).OrderBy(pair => pair.ia.GetMean()).Select(pair => pair.i).ToArray();

            Console.WriteLine("actualStateOrder");
            Console.WriteLine(string.Join(",", actualStateOrder));
            Console.WriteLine();

            // sample state and emission data
            var actualStates = new int[T];
            var emissions    = new bool[T];

            actualStates[0] = initDist.Sample();
            emissions[0]    = emitDist[actualStates[0]].Sample();
            for (int i = 1; i < T; i++)
            {
                actualStates[i] = transDist[actualStates[i - 1]].Sample();
                emissions[i]    = emitDist[actualStates[i]].Sample();
            }

            Console.WriteLine("sample data:");
            Console.WriteLine(string.Join(",", actualStates));
            Console.WriteLine();

            // infer model parameters, states and model evidence given priors and emission data
            var model = new BinaryHMM();

            model.CreateModel(T, K, 1, false);
            model.SetPriors(probInitPriorObs, cptTransPriorObs, emitPriorObs, null);
            model.ObserveData(emissions);
            model.InitialiseStatesRandomly();
            model.InferPosteriors();
            Console.WriteLine("model likelihood: " + model.modelEvidencePosterior);
            var mapStatesDistr = model.statesPosterior;
            var mapStates      = mapStatesDistr.Select(s => s.GetMode()).ToArray();

            Console.WriteLine();

            // print maximum a priori states
            Console.WriteLine("statesMAP");
            Console.WriteLine(string.Join(",", mapStates));
            Console.WriteLine();

            // print posterior distributions
            Console.WriteLine("posteriors");
            model.PrintPosteriors();
            Console.WriteLine();

            // calculate order of MAP states
            var mapStateOrder = ArgSort <Beta, double>(model.emitMeanPosterior);

            Console.WriteLine(string.Join(",", mapStateOrder));
            Console.WriteLine();

            // accuracy of MAP estimates
            int correctStates = actualStates.Where((t, i) => actualStateOrder[t] == mapStateOrder[mapStates[i]]).Count();

            Console.WriteLine("correctStates: " + correctStates + " / " + actualStates.Length);
            Console.WriteLine();

            Console.WriteLine("------------------\n");
        }