コード例 #1
0
ファイル: ForwardBackward.cs プロジェクト: xg86/HmmDotNet
        public double RunForward <TEmmisionType>(IList <IObservation> observations, IHiddenMarkovModel <TEmmisionType> model) where TEmmisionType : IDistribution
        {
            var alphaEstimator = new AlphaEstimator <TEmmisionType>();

            _alpha = alphaEstimator.Estimate(new BasicEstimationParameters <TEmmisionType> {
                Model = model, Observations = observations, Normalized = Normalized
            });
            var T      = observations.Count;
            var result = (Normalized) ? double.NaN : 0d;

            // Calculate results
            for (var i = 0; i < model.N; i++)
            {
                if (Normalized)
                {
                    result = LogExtention.eLnSum(result, _alpha[T - 1][i]);
                }
                else
                {
                    result += _alpha[T - 1][i];
                }
            }

            return(result);
        }
コード例 #2
0
        public double[][] Estimate(KsiGammaTransitionProbabilityMatrixParameters <TDistribution> parameters)
        {
            if (_estimatedTransitionProbabilityMatrix != null)
            {
                return(_estimatedTransitionProbabilityMatrix);
            }
            _estimatedTransitionProbabilityMatrix = new double[parameters.Model.N][];

            for (var i = 0; i < parameters.Model.N; i++)
            {
                _estimatedTransitionProbabilityMatrix[i] = new double[parameters.Model.N];
                for (var j = 0; j < parameters.Model.N; j++)
                {
                    double denominator = (parameters.Model.Normalized) ? double.NaN : 0, nominator = (parameters.Model.Normalized) ? double.NaN : 0;
                    for (var t = 0; t < parameters.T - 1; t++)
                    {
                        if (parameters.Model.Normalized)
                        {
                            nominator   = LogExtention.eLnSum(nominator, parameters.Ksi[t][i, j]);
                            denominator = LogExtention.eLnSum(denominator, parameters.Gamma[t][i]);
                        }
                        else
                        {
                            nominator   += parameters.Ksi[t][i, j];
                            denominator += parameters.Gamma[t][i];
                        }
                    }
                    _estimatedTransitionProbabilityMatrix[i][j] = CalculateTransitionProbabilityMatrixEntry(nominator, denominator, parameters.Normalized);
                }
            }
            return(_estimatedTransitionProbabilityMatrix);
        }
コード例 #3
0
        public double[][] Estimate(AlphaBetaTransitionProbabiltyMatrixParameters <TDistribution> parameters)
        {
            if (_estimatedTransitionProbabilityMatrix != null)
            {
                return(_estimatedTransitionProbabilityMatrix);
            }
            var T = parameters.Observations.Length;

            _estimatedTransitionProbabilityMatrix = new double[parameters.Model.N][];

            for (var i = 0; i < parameters.Model.N; i++)
            {
                _estimatedTransitionProbabilityMatrix[i] = new double[parameters.Model.N];
                for (var j = 0; j < parameters.Model.N; j++)
                {
                    double nominator = (parameters.Normalized) ? double.NaN : 0.0d, denominator = (parameters.Normalized) ? double.NaN : 0.0d;
                    for (var t = 0; t < T - 1; t++)
                    {
                        var probability = parameters.Model.Emission[j].ProbabilityDensityFunction(parameters.Observations[t + 1]);
                        if (parameters.Normalized)
                        {
                            nominator   = LogExtention.eLnSum(nominator, LogExtention.eLnProduct(parameters.Weights[t], LogExtention.eLnProduct(parameters.Alpha[t][i], LogExtention.eLnProduct(LogExtention.eLn(parameters.Model.TransitionProbabilityMatrix[i][j]), LogExtention.eLnProduct(LogExtention.eLn(probability), parameters.Beta[t + 1][j])))));
                            denominator = LogExtention.eLnSum(denominator, LogExtention.eLnProduct(parameters.Weights[t], LogExtention.eLnProduct(parameters.Alpha[t][i], parameters.Beta[t][j])));
                        }
                        else
                        {
                            nominator   += parameters.Weights[t] * parameters.Alpha[t][i] * parameters.Model.TransitionProbabilityMatrix[i][j] * probability * parameters.Beta[t + 1][j];
                            denominator += parameters.Weights[t] * parameters.Alpha[t][i] * parameters.Beta[t][j];
                        }
                    }
                    _estimatedTransitionProbabilityMatrix[i][j] = CalculateTransitionProbabilityMatrixEntry(nominator, denominator, parameters.Normalized);
                }
            }
            return(_estimatedTransitionProbabilityMatrix);
        }
コード例 #4
0
        public double[] Estimate(MuEstimationParameters <TDistribution> parameters)
        {
            if (_muUnivariate != null)
            {
                return(_muUnivariate);
            }
            _muUnivariate = new double[parameters.Model.N];
            for (var n = 0; n < parameters.Model.N; n++)
            {
                var T    = parameters.Observations.Count;
                var mean = 0d;
                var nK   = 0d;
                for (var t = 0; t < T; t++)
                {
                    if (parameters.Model.Normalized)
                    {
                        nK   += LogExtention.eExp(parameters.Gamma[t][n]);
                        mean += parameters.Observations[t].Value[0] * LogExtention.eExp(parameters.Gamma[t][n]);
                    }
                    else
                    {
                        nK   += parameters.Gamma[t][n];
                        mean += parameters.Observations[t].Value[0] * parameters.Gamma[t][n];
                    }
                }

                _muUnivariate[n] = mean / nK;
            }

            return(_muUnivariate);
        }
コード例 #5
0
        public IDistribution Evaluate(double[] observations, double[] symbols, double[] gamma)
        {
            var M             = symbols.Length;
            var T             = observations.Length;
            var probabilities = new double[M];

            for (var k = 0; k < M; k++)
            {
                double den = 0, num = 0;
                for (var t = 0; t < T; t++)
                {
                    if (observations[t] == symbols[k])
                    {
                        num = num + gamma[t];
                    }
                    den = den + gamma[t];
                }
                probabilities[k] = 1e-10;
                if (num.EqualsToZero())
                {
                    probabilities[k] = den.EqualsToZero() ? 0.0 : LogExtention.eExp(LogExtention.eLnProduct(num, -den));
                }
            }
            return(new DiscreteDistributionNormalized(symbols, probabilities));
        }
コード例 #6
0
ファイル: GammaEstimator.cs プロジェクト: xg86/HmmDotNet
        public double[][] Estimate(AdvancedEstimationParameters <TDistribution> parameters)
        {
            if (_gamma != null)
            {
                return(_gamma);
            }

            var denominator = new double[parameters.Observations.Count];

            for (var t = 0; t < parameters.Observations.Count; t++)
            {
                denominator[t] = (parameters.Normalized) ? double.NaN : 0d;
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    if (parameters.Normalized)
                    {
                        denominator[t] = LogExtention.eLnSum(denominator[t], LogExtention.eLnProduct(parameters.Alpha[t][i], parameters.Beta[t][i]));
                    }
                    else
                    {
                        denominator[t] += parameters.Alpha[t][i] * parameters.Beta[t][i];
                    }
                }
            }


            try
            {
                _gamma = new double[parameters.Observations.Count][];
                for (var t = 0; t < parameters.Observations.Count; t++)
                {
                    _gamma[t] = new double[parameters.Model.N];
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        if (parameters.Normalized)
                        {
                            _gamma[t][i] = LogExtention.eLnProduct(LogExtention.eLnProduct(parameters.Alpha[t][i], parameters.Beta[t][i]), -denominator[t]);
                        }
                        else
                        {
                            _gamma[t][i] = (parameters.Alpha[t][i] * parameters.Beta[t][i]) / denominator[t];
                        }
                    }
                }
            }
            catch (Exception)
            {
                for (var t = 0; t < parameters.Observations.Count; t++)
                {
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        Debug.WriteLine("Gamma [{0}][{1}] : alpha : {2} , beta : {3} , denominator : {4} : gamma {5} ", t, i, parameters.Alpha[t][i], parameters.Beta[t][i], denominator[t], _gamma[t][i]);
                    }
                }
                throw;
            }

            return(_gamma);
        }
コード例 #7
0
ファイル: LogExtentionsTest.cs プロジェクト: xg86/HmmDotNet
        public void eLn_XisZero_NaNReturned()
        {
            var x = 0;

            var result = LogExtention.eLn(x);

            Assert.AreEqual(double.NaN, result);
        }
コード例 #8
0
ファイル: LogExtentionsTest.cs プロジェクト: xg86/HmmDotNet
        public void eExp_XisNumber_ePowerXReturned()
        {
            var x = 1d;

            var result = LogExtention.eExp(x);

            Assert.AreEqual(Math.E, result);
        }
コード例 #9
0
ファイル: LogExtentionsTest.cs プロジェクト: xg86/HmmDotNet
        public void eLn_XisGreaterThanZero_LogXReturned()
        {
            var x = 1d;

            var result = LogExtention.eLn(x);

            Assert.AreEqual(0, result);
        }
コード例 #10
0
ファイル: LogExtentionsTest.cs プロジェクト: xg86/HmmDotNet
        public void eExp_XisNaN_ZeroReturned()
        {
            var x = double.NaN;

            var result = LogExtention.eExp(x);

            Assert.AreEqual(0, result);
        }
コード例 #11
0
 private double CalculateTransitionProbabilityMatrixEntry(double nominator, double denominator, bool normalized)
 {
     if (denominator.EqualsToZero())
     {
         return(0);
     }
     return((normalized) ? LogExtention.eExp(LogExtention.eLnProduct(nominator, -denominator)) : nominator / denominator);
 }
コード例 #12
0
        public double[][] Estimate(BasicEstimationParameters <TDistribution> parameters)
        {
            if (_beta != null)
            {
                return(_beta);
            }
            var T = parameters.Observations.Count;

            try
            {
                _beta        = new double[T][];
                _beta[T - 1] = new double[parameters.Model.N];

                for (var i = 0; i < parameters.Model.N; i++)
                {
                    _beta[T - 1][i] = (parameters.Normalized) ? 0d : 1d;
                }

                for (var t = T - 2; t >= 0; t--)
                {
                    _beta[t] = new double[parameters.Model.N];
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        _beta[t][i] = (parameters.Normalized) ? double.NaN : 0d;
                        for (var j = 0; j < parameters.Model.N; j++)
                        {
                            var o = EstimatorUtilities.GetProbability(parameters.Model.Emission[j], parameters.Observations, t + 1);
                            if (parameters.Normalized)
                            {
                                _beta[t][i] = LogExtention.eLnSum(_beta[t][i],
                                                                  LogExtention.eLnProduct(LogExtention.eLn(parameters.Model.TransitionProbabilityMatrix[i][j]),
                                                                                          LogExtention.eLnProduct(LogExtention.eLn(o), _beta[t + 1][j])));
                            }
                            else
                            {
                                _beta[t][i] += parameters.Model.TransitionProbabilityMatrix[i][j] * o * _beta[t + 1][j];
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                for (var t = T - 2; t >= 0; t--)
                {
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        for (var j = 0; j < parameters.Model.N; j++)
                        {
                            Debug.WriteLine("[{0}][{1}] : beta : {2}", t, i, _beta[t][i]);
                        }
                    }
                }
                throw;
            }

            return(_beta);
        }
コード例 #13
0
ファイル: LogExtentionsTest.cs プロジェクト: xg86/HmmDotNet
        public void eLnProduct_YandXnotEqualsNan_XPlusYReturned()
        {
            var x = 1d;
            var y = 1d;

            var result = LogExtention.eLnProduct(x, y);

            Assert.AreEqual(x + y, result);
        }
コード例 #14
0
ファイル: LogExtentionsTest.cs プロジェクト: xg86/HmmDotNet
        public void eLnSum_XGreaterThanY_eLnSumReturned()
        {
            var x = 2d;
            var y = 1d;

            var result = LogExtention.eLnSum(x, y);

            Assert.AreEqual(x + LogExtention.eLn(1 + Math.Exp(y - x)), result);
        }
コード例 #15
0
ファイル: KsiEstimator.cs プロジェクト: xg86/HmmDotNet
        public double[][,] Estimate(AdvancedEstimationParameters <TDistribution> parameters)
        {
            if (_ksi != null)
            {
                return(_ksi);
            }
            var denominator = new double[parameters.Observations.Count];

            for (var t = 0; t < parameters.Observations.Count - 1; t++)
            {
                denominator[t] = (parameters.Normalized) ? double.NaN : 0d;
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    for (var j = 0; j < parameters.Model.N; j++)
                    {
                        var o = EstimatorUtilities.GetProbability(parameters.Model.Emission[j], parameters.Observations, t + 1);
                        if (parameters.Normalized)
                        {
                            denominator[t] = LogExtention.eLnSum(denominator[t], LogExtention.eLnProduct(parameters.Alpha[t][i],
                                                                                                         LogExtention.eLnProduct(LogExtention.eLn(parameters.Model.TransitionProbabilityMatrix[i][j]),
                                                                                                                                 LogExtention.eLnProduct(parameters.Beta[t + 1][j], LogExtention.eLn(o)))));
                        }
                        else
                        {
                            denominator[t] += parameters.Alpha[t][i] * parameters.Model.TransitionProbabilityMatrix[i][j] * parameters.Beta[t + 1][j] * o;
                        }
                    }
                }
            }

            _ksi = new double[parameters.Observations.Count][, ];
            for (var t = 0; t < parameters.Observations.Count - 1; t++)
            {
                _ksi[t] = new double[parameters.Model.N, parameters.Model.N];
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    for (var j = 0; j < parameters.Model.N; j++)
                    {
                        var o = EstimatorUtilities.GetProbability(parameters.Model.Emission[j], parameters.Observations, t + 1);
                        if (parameters.Normalized)
                        {
                            var nominator = LogExtention.eLnProduct(parameters.Alpha[t][i],
                                                                    LogExtention.eLnProduct(LogExtention.eLn(parameters.Model.TransitionProbabilityMatrix[i][j]),
                                                                                            LogExtention.eLnProduct(parameters.Beta[t + 1][j], LogExtention.eLn(o))));
                            _ksi[t][i, j] = LogExtention.eLnProduct(nominator, -denominator[t]);
                        }
                        else
                        {
                            var nominator = parameters.Alpha[t][i] * parameters.Model.TransitionProbabilityMatrix[i][j] * parameters.Beta[t + 1][j] * o;
                            _ksi[t][i, j] = nominator / denominator[t];
                        }
                    }
                }
            }

            return(_ksi);
        }
コード例 #16
0
ファイル: LogExtentionsTest.cs プロジェクト: xg86/HmmDotNet
        public void eLnSum_YisNaN_XReturned()
        {
            var x = 1d;
            var y = double.NaN;

            var result = LogExtention.eLnSum(x, y);

            Assert.AreEqual(x, result);
        }
コード例 #17
0
ファイル: LogExtentionsTest.cs プロジェクト: xg86/HmmDotNet
        public void eLnSum_YGreaterThanX_eLnSumReturned()
        {
            var x = 1d;
            var y = 2d;

            var result = LogExtention.eLnSum(x, y);

            Assert.AreEqual(y + LogExtention.eLn(1 + Math.Exp(x - y)), result);
        }
コード例 #18
0
ファイル: LogExtentionsTest.cs プロジェクト: xg86/HmmDotNet
        public void eLnProduct_XisNaN_YReturned()
        {
            var x = double.NaN;
            var y = 1d;

            var result = LogExtention.eLnProduct(x, y);

            Assert.AreEqual(double.NaN, result);
        }
コード例 #19
0
        public double[][,] Estimate(SigmaEstimationParameters <TDistribution, double[][]> parameters)
        {
            if (_sigmaMultivariate != null)
            {
                return(_sigmaMultivariate);
            }
            try
            {
                _sigmaMultivariate = new double[parameters.Model.N][, ];
                var K = parameters.Observations[0].Dimention;
                var T = parameters.Observations.Count;

                for (var n = 0; n < parameters.Model.N; n++)
                {
                    var covariance = new double[K, K];
                    var nK         = 0d;
                    for (var t = 0; t < T; t++)
                    {
                        var x = parameters.Observations[t].Value;
                        var z = x.Substruct(parameters.Mean[n]);
                        var m = z.OuterProduct(z);
                        if (parameters.Model.Normalized)
                        {
                            nK += LogExtention.eExp(parameters.Gamma[t][n]);
                            m   = m.Product(LogExtention.eExp(parameters.Gamma[t][n]));
                        }
                        else
                        {
                            nK += parameters.Gamma[t][n];
                            m   = m.Product(parameters.Gamma[t][n]);
                        }

                        covariance = covariance.Add(m);
                    }
                    _sigmaMultivariate[n] = covariance.Product(1 / nK);
                    var matrix = new Matrix(_sigmaMultivariate[n]);
                    if (!matrix.PositiviDefinite)
                    {
                        _sigmaMultivariate[n] = matrix.ConvertToPositiveDefinite();
                        Debug.WriteLine("HMM State {0} Sigma is not Positive Definite. Converting.", n);
                        Debug.WriteLine("{0}", matrix);
                    }
                    Debug.WriteLine("HMM State {0} Sigma : {1}", n, new Matrix(_sigmaMultivariate[n]));
                }
            }
            catch (Exception)
            {
                for (var n = 0; n < parameters.Model.N; n++)
                {
                    Debug.WriteLine("HMM State {0} Sigma : {1}", n, new Matrix(_sigmaMultivariate[n]));
                }
                throw;
            }

            return(_sigmaMultivariate);
        }
コード例 #20
0
ファイル: BaseBaumWelch.cs プロジェクト: xg86/HmmDotNet
        protected void EstimatePi(double[][] gamma)
        {
            var checksum = 0d;

            for (var i = 0; i < _model.N; i++)
            {
                _estimatedPi[i] = (_model.Normalized) ? LogExtention.eExp(gamma[0][i]) : gamma[0][i];
                checksum       += _estimatedPi[i];
            }
            CheckPi(checksum);
        }
コード例 #21
0
        public double[, ][,] Estimate(MixtureSigmaEstimationParameters <TDistribution> parameters)
        {
            if (_sigma != null)
            {
                return(_sigma);
            }
            try
            {
                _sigma = new double[parameters.Model.N, parameters.L][, ];
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    for (var l = 0; l < parameters.L; l++)
                    {
                        var denominator = 0.0d;
                        var nominator   = new double[parameters.Observations[0].Dimention, parameters.Observations[0].Dimention];
                        for (var t = 0; t < parameters.Observations.Count; t++)
                        {
                            // TODO : weights here
                            var weight          = GetWeightValue(t, parameters.ObservationWeights);
                            var gammaComponents = (parameters.Model.Normalized) ? LogExtention.eExp(parameters.GammaComponents[t][i, l]) : parameters.GammaComponents[t][i, l];

                            var x = parameters.Observations[t].Value;
                            var z = x.Substruct(parameters.Mu[i, l]);
                            var m = z.OuterProduct(z);

                            m            = m.Product(weight * gammaComponents);
                            denominator += weight * gammaComponents;
                            nominator    = nominator.Add(m);
                        }
                        _sigma[i, l] = nominator.Product(1 / denominator);
                        var matrix = new Matrix(_sigma[i, l]);
                        if (!matrix.PositiviDefinite)
                        {
                            _sigma[i, l] = matrix.ConvertToPositiveDefinite();
                            Debug.WriteLine("HMM State [{0},{1}] Sigma is not Positive Definite. Converting.", i, l);
                            Debug.WriteLine("{0}", matrix);
                        }
                    }
                }
            }
            catch (Exception)
            {
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    for (var l = 0; l < parameters.L; l++)
                    {
                        Debug.WriteLine("Mixture Sigma [{0},{1}] : {2}", i, l, new Matrix(_sigma[i, l]));
                    }
                }
                throw;
            }

            return(_sigma);
        }
コード例 #22
0
        public double[][,] Estimate(MixtureAdvancedEstimationParameters <TDistribution> parameters)
        {
            if (_gammaComponents != null)
            {
                return(_gammaComponents);
            }

            try
            {
                _gammaComponents = new double[parameters.Observations.Count][, ];
                for (var t = 0; t < parameters.Observations.Count; t++)
                {
                    _gammaComponents[t] = new double[parameters.Model.N, parameters.L];
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        var d = parameters.Model.Emission[i] as Mixture <IMultivariateDistribution>;
                        if (d != null)
                        {
                            for (var l = 0; l < parameters.L; l++)
                            {
                                //Emmision in our case are Mixture<T>
                                var p = d.ProbabilityDensityFunction(l, parameters.Observations[t].Value);
                                if (parameters.Normalized)
                                {
                                    _gammaComponents[t][i, l] = LogExtention.eLnProduct(_gammaEstimator.Estimate(parameters)[t][i], LogExtention.eLn(p));
                                }
                                else
                                {
                                    _gammaComponents[t][i, l] = _gammaEstimator.Estimate(parameters)[t][i] * p;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                for (var t = 0; t < parameters.Observations.Count; t++)
                {
                    if (Math.Round(_gammaComponents[t].Sum(), 5) > 1)
                    {
                        Debug.WriteLine("Mixture Gamma Components [{0}] : {1}", t, new Matrix(_gammaComponents[t]));
                        throw new ApplicationException(string.Format("Mixture Sigma is greater than 1. [{0}] : {1} : {2}", t, new Matrix(_gammaComponents[t]), Math.Round(_gammaComponents[t].Sum(), 5)));
                    }
                }
                throw;
            }


            return(_gammaComponents);
        }
コード例 #23
0
        private double GetWeightValue(int t, decimal[] weights)
        {
            var weight = 0.0;

            if (weights != null)
            {
                weight = (_parameters.Model.Normalized) ? LogExtention.eLn((double)weights[t]) : (double)weights[t];
            }
            else
            {
                weight = (_parameters.Model.Normalized) ? 0 : 1;
            }
            return(weight);
        }
コード例 #24
0
 public void Denormalize()
 {
     if (!_denormalized)
     {
         for (var i = 0; i < _parameters.Model.N; i++)
         {
             for (var l = 0; l < _parameters.L; l++)
             {
                 _coefficients[i][l] = LogExtention.eExp(_coefficients[i][l]);
             }
         }
         _denormalized = true;
     }
 }
コード例 #25
0
ファイル: PiEstimator.cs プロジェクト: xg86/HmmDotNet
        public double[] Estimate(PiParameters parameters)
        {
            if (_estimatedPi != null)
            {
                return(_estimatedPi);
            }
            _estimatedPi = new double[parameters.N];

            for (var i = 0; i < parameters.N; i++)
            {
                _estimatedPi[i] = (parameters.Normalized) ? LogExtention.eExp(parameters.Gamma[0][i]) : parameters.Gamma[0][i];
            }

            return(_estimatedPi);
        }
コード例 #26
0
        public double[][] Estimate(BasicEstimationParameters <TDistribution> parameters)
        {
            if (_alpha != null)
            {
                return(_alpha);
            }

            _alpha    = new double[parameters.Observations.Count][];
            _alpha[0] = new double[parameters.Model.N];
            // Initialize
            for (var i = 0; i < parameters.Model.N; i++)
            {
                var o = EstimatorUtilities.GetProbability(parameters.Model.Emission[i], parameters.Observations, 0);
                _alpha[0][i] = (parameters.Normalized) ? LogExtention.eLnProduct(LogExtention.eLn(parameters.Model.Pi[i]), LogExtention.eLn(o)) : parameters.Model.Pi[i] * o;
            }
            // Induction
            for (var t = 1; t < parameters.Observations.Count; t++)
            {
                _alpha[t] = new double[parameters.Model.N];
                for (var j = 0; j < parameters.Model.N; j++)
                {
                    var sum = (parameters.Normalized) ? double.NaN : 0d;
                    for (var i = 0; i < parameters.Model.N; i++)
                    {
                        if (parameters.Normalized)
                        {
                            sum = LogExtention.eLnSum(sum, LogExtention.eLnProduct(_alpha[t - 1][i], LogExtention.eLn(parameters.Model.TransitionProbabilityMatrix[i][j])));
                        }
                        else
                        {
                            sum += _alpha[t - 1][i] * parameters.Model.TransitionProbabilityMatrix[i][j];
                        }
                    }
                    var o = EstimatorUtilities.GetProbability(parameters.Model.Emission[j], parameters.Observations, t);
                    if (parameters.Normalized)
                    {
                        _alpha[t][j] = LogExtention.eLnProduct(sum, LogExtention.eLn(o));
                    }
                    else
                    {
                        _alpha[t][j] = sum * o;
                    }
                }
            }

            return(_alpha);
        }
コード例 #27
0
        public IDistribution Evaluate(double[] observations, double[] symbols, double[] gamma, bool logNormalized)
        {
            var M             = symbols.Length;
            var T             = observations.Length;
            var probabilities = new double[M];

            for (var k = 0; k < M; k++)
            {
                double den = (logNormalized) ? double.NaN : 0, num = (logNormalized) ? double.NaN : 0;
                for (var t = 0; t < T; t++)
                {
                    if (observations[t] == symbols[k])
                    {
                        if (logNormalized)
                        {
                            num = LogExtention.eLnSum(num, gamma[t]);
                        }
                        else
                        {
                            num = num + gamma[t];
                        }
                    }
                    if (logNormalized)
                    {
                        den = LogExtention.eLnSum(den, gamma[t]);
                    }
                    else
                    {
                        den = den + gamma[t];
                    }
                }
                probabilities[k] = 1e-10;
                if (!num.EqualsToZero())
                {
                    if (logNormalized)
                    {
                        probabilities[k] = den.EqualsToZero() ? 0.0 : LogExtention.eExp(LogExtention.eLnProduct(num, -den));
                    }
                    else
                    {
                        probabilities[k] = den.EqualsToZero() ? 0.0 : num / den;
                    }
                }
            }
            return(new DiscreteDistribution(symbols, probabilities));
        }
コード例 #28
0
        public double[, ][] Estimate(MixtureCoefficientEstimationParameters <TDistribution> parameters)
        {
            if (_mu != null)
            {
                return(_mu);
            }

            try
            {
                _mu = new double[parameters.Model.N, parameters.L][];
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    for (var l = 0; l < parameters.L; l++)
                    {
                        var denominator = 0.0d;
                        var nominator   = new double[parameters.Observations[0].Dimention];
                        for (var t = 0; t < parameters.Observations.Count; t++)
                        {
                            // TODO : weights here
                            var weight = GetWeightValue(t, parameters.ObservationWeights);
                            var x      = parameters.Observations[t].Value;
                            var gamma  = (parameters.Model.Normalized) ? LogExtention.eExp(parameters.GammaComponents[t][i, l])
                                                                          : parameters.GammaComponents[t][i, l];
                            denominator += weight * gamma;
                            x            = x.Product(gamma * weight);
                            nominator    = nominator.Add(x);
                        }
                        _mu[i, l] = nominator.Product(1 / denominator);
                    }
                }
            }
            catch (Exception)
            {
                for (var i = 0; i < parameters.Model.N; i++)
                {
                    for (var l = 0; l < parameters.L; l++)
                    {
                        Debug.WriteLine("Mixture Mu [{0},{1}] : {2}", i, l, new Vector(_mu[i, l]));
                    }
                }
                throw;
            }

            return(_mu);
        }
コード例 #29
0
        public double[][] Estimate(MuEstimationParameters <TDistribution> parameters)
        {
            if (_muMultivariate != null)
            {
                return(_muMultivariate);
            }
            try
            {
                _muMultivariate = new double[parameters.Model.N][];
                var K = parameters.Observations[0].Dimention; // Number of dimentions
                var T = parameters.Observations.Count;

                for (var n = 0; n < parameters.Model.N; n++)
                {
                    var mean = new double[K];
                    var nK   = 0d;
                    for (var t = 0; t < T; t++)
                    {
                        if (parameters.Model.Normalized)
                        {
                            nK  += LogExtention.eExp(parameters.Gamma[t][n]);
                            mean = mean.Add(parameters.Observations[t].Value.Product(LogExtention.eExp(parameters.Gamma[t][n])));
                        }
                        else
                        {
                            nK  += parameters.Gamma[t][n];
                            mean = mean.Add(parameters.Observations[t].Value.Product(parameters.Gamma[t][n]));
                        }
                    }

                    _muMultivariate[n] = mean.Product(1 / nK);
                    Debug.WriteLine(string.Format("HMM State {0} : Mu {1}", n, new Vector(_muMultivariate[n])));
                }
            }
            catch (Exception)
            {
                for (var n = 0; n < parameters.Model.N; n++)
                {
                    Debug.WriteLine(string.Format("HMM State {0} : Mu {1}", n, new Vector(_muMultivariate[n])));
                }
                throw;
            }
            return(_muMultivariate);
        }
コード例 #30
0
ファイル: BaseBaumWelch.cs プロジェクト: xg86/HmmDotNet
        protected void EstimateTransitionProbabilityMatrix(double[][] gamma, double[][,] ksi, decimal[] observationWeights, int sequenceLength)
        {
            var checksum = new double[_model.N];

            for (var i = 0; i < _model.N; i++)
            {
                _estimatedTransitionProbabilityMatrix[i] = new double[_model.N];
                for (var j = 0; j < _model.N; j++)
                {
                    double den = (_model.Normalized) ? double.NaN : 0, num = (_model.Normalized) ? double.NaN : 0;
                    for (var t = 0; t < sequenceLength - 1; t++)
                    {
                        var weight = GetWeightValue(t, observationWeights);
                        if (_model.Normalized)
                        {
                            num = LogExtention.eLnSum(num, LogExtention.eLnProduct(weight, ksi[t][i, j]));
                            den = LogExtention.eLnSum(den, LogExtention.eLnProduct(weight, gamma[t][i]));
                        }
                        else
                        {
                            num += weight * ksi[t][i, j];
                            den += weight * gamma[t][i];
                        }
                    }
                    if (_model.Normalized)
                    {
                        _estimatedTransitionProbabilityMatrix[i][j] = den.EqualsToZero() ? 0.0 : LogExtention.eExp(LogExtention.eLnProduct(num, -den));
                    }
                    else
                    {
                        _estimatedTransitionProbabilityMatrix[i][j] = den.EqualsToZero() ? 0.0 : num / den;
                    }
                    checksum[i] = checksum[i] + _estimatedTransitionProbabilityMatrix[i][j];
                }
            }

            CheckTransitionProbabilityMatrix(checksum);
        }