/// <summary> /// Whether to compute smoothing probabilities using the ForwardBackwardAlgorithm /// for the states of the most likely sequence. Note that this significantly increases /// computation time and memory footprint. <br/> /// Must be called before processing is started. /// </summary> /// <param name="isComputeSmoothingProbabilities">Default: false</param> /// <returns></returns> public ViterbiModel <TState, TObservation, TDescriptor> SetComputeSmoothingProbabilities(bool isComputeSmoothingProbabilities) { if (this.IsProcessingStarted) { throw new InvalidOperationException("Processing has already started."); } if (isComputeSmoothingProbabilities) { _forwardBackward = new ForwardBackwardModel <TState, TObservation>(); } else { _forwardBackward = null; } return(this); }
public void testForwardBackward() { List <Rain> candidates = new List <Rain>(); candidates.Add(Rain.T); candidates.Add(Rain.F); var initialStateProbabilities = new Dictionary <Rain, double>(); initialStateProbabilities.Add(Rain.T, 0.5); initialStateProbabilities.Add(Rain.F, 0.5); var emissionProbabilitiesForUmbrella = new Dictionary <Rain, double>(); emissionProbabilitiesForUmbrella.Add(Rain.T, 0.9); emissionProbabilitiesForUmbrella.Add(Rain.F, 0.2); var emissionProbabilitiesForNoUmbrella = new Dictionary <Rain, double>(); emissionProbabilitiesForNoUmbrella.Add(Rain.T, 0.1); emissionProbabilitiesForNoUmbrella.Add(Rain.F, 0.8); var transitionProbabilities = new Dictionary <Transition <Rain>, double>(); transitionProbabilities.Add(new Transition <Rain>(Rain.T, Rain.T), 0.7); transitionProbabilities.Add(new Transition <Rain>(Rain.T, Rain.F), 0.3); transitionProbabilities.Add(new Transition <Rain>(Rain.F, Rain.T), 0.3); transitionProbabilities.Add(new Transition <Rain>(Rain.F, Rain.F), 0.7); var fw = new ForwardBackwardModel <Rain, Umbrella>(); fw.Start(candidates, initialStateProbabilities); fw.NextStep(Umbrella.T, candidates, emissionProbabilitiesForUmbrella, transitionProbabilities); fw.NextStep(Umbrella.T, candidates, emissionProbabilitiesForUmbrella, transitionProbabilities); fw.NextStep(Umbrella.F, candidates, emissionProbabilitiesForNoUmbrella, transitionProbabilities); fw.NextStep(Umbrella.T, candidates, emissionProbabilitiesForUmbrella, transitionProbabilities); fw.NextStep(Umbrella.T, candidates, emissionProbabilitiesForUmbrella, transitionProbabilities); var result = fw.ComputeSmoothingProbabilities(); Assert.Equal(6, result.Count); var DELTA = 4; //1e-4; Assert.Equal(0.6469, result[0][Rain.T], DELTA); Assert.Equal(0.3531, result[0][Rain.F], DELTA); Assert.Equal(0.8673, result[1][Rain.T], DELTA); Assert.Equal(0.1327, result[1][Rain.F], DELTA); Assert.Equal(0.8204, result[2][Rain.T], DELTA); Assert.Equal(0.1796, result[2][Rain.F], DELTA); Assert.Equal(0.3075, result[3][Rain.T], DELTA); Assert.Equal(0.6925, result[3][Rain.F], DELTA); Assert.Equal(0.8204, result[4][Rain.T], DELTA); Assert.Equal(0.1796, result[4][Rain.F], DELTA); Assert.Equal(0.8673, result[5][Rain.T], DELTA); Assert.Equal(0.1327, result[5][Rain.F], DELTA); }