Пример #1
0
        private double[,] LogSpaceGamma(int[] O, double[,] logAlpha, double[,] logBeta)
        {
            int N = states;
            int M = observationSymbols;
            int T = O.Length;

            var logGamma = new double[T, N];

            #region Calculating digamma and gamma
            for (int t = 0; t < T; t++)
            {
                double normalizer = MathE.LOGZERO;
                for (int i = 0; i < N; i++)
                {
                    logGamma[t, i] = MathE.elnproduct(logAlpha[t, i], logBeta[t, i]);
                    normalizer     = MathE.elnsum(normalizer, logGamma[t, i]);
                }

                for (int i = 0; i < N; i++)
                {
                    logGamma[t, i] = MathE.elnproduct(logGamma[t, i], -normalizer);
                }
            }

            #endregion

            return(logGamma);
        }
Пример #2
0
        private double[, ,] LogSpaceEta(int[] O, double[,] logAlpha, double[,] logBeta)
        {
            int N = states;
            int M = observationSymbols;
            int T = O.Length;

            var logEta = new double[T, N, N];

            #region Calculating digamma and gamma
            for (int t = 0; t < T - 1; t++)
            {
                double normalizer = MathE.LOGZERO;
                for (int i = 0; i < N; i++)
                {
                    for (int j = 0; j < N; j++)
                    {
                        //logEta[t, i, j] = MathE.elnproduct(logAlpha[t, i], MathE.elnproduct(MathE.eln(transition[i, j]),
                        //   MathE.elnproduct(MathE.eln(emission[j, O[t + 1]]), logBeta[t + 1, j])));

                        /*logEta[t, i, j] = MathE.elnproduct(logAlpha[t, i], MathE.elnproduct(logTransition[i, j],
                         *  MathE.elnproduct(logEmission[j, O[t + 1]], logBeta[t + 1, j])));
                         */
                        logEta[t, i, j] = MathE.elnproduct(logAlpha[t, i], logTransition[i, j], logEmission[j, O[t + 1]], logBeta[t + 1, j]);
                        normalizer      = MathE.elnsum(normalizer, logEta[t, i, j]);
                    }
                }

                for (int i = 0; i < N; i++)
                {
                    for (int j = 0; j < N; j++)
                    {
                        logEta[t, i, j] = MathE.elnproduct(logEta[t, i, j], -normalizer);
                    }
                }
            }

            #endregion


            return(logEta);
        }
Пример #3
0
        // ln(b_t(i))
        private double[,] LogSpaceBackward(int[] O)
        {
            int N = states;
            int M = observationSymbols;
            int T = O.Length;

            var logBeta = new double[T, N];

            #region Beta Pass

            for (int i = 0; i < N; i++)
            {
                logBeta[T - 1, i] = 0;
            }

            // Beta pass
            for (int t = T - 2; t >= 0; t--)
            {
                for (int i = 0; i < N; i++)
                {
                    double logbeta = MathE.LOGZERO;

                    for (int j = 0; j < N; j++)
                    {
                        // logbeta = MathE.elnsum(logbeta, MathE.elnproduct(MathE.eln(transition[i, j]),
                        //    MathE.elnproduct(emission[j, O[t + 1]], logBeta[t + 1, j])));
                        // mISTAKE ??? MathE.elnproduct(emission[j, O[t + 1]],...

                        logbeta = MathE.elnsum(logbeta, MathE.elnproduct(logTransition[i, j],
                                                                         MathE.elnproduct(logEmission[j, O[t + 1]], logBeta[t + 1, j])));
                    }
                    logBeta[t, i] = logbeta;
                }
            }
            #endregion

            return(logBeta);
        }
Пример #4
0
        // ln(a_t(i))
        private double[,] LogSpaceForward(int[] O)
        {
            int N = states;
            int M = observationSymbols;
            int T = O.Length;

            var logAlpha = new double[T, N];

            #region Alpha Pass

            for (int i = 0; i < N; i++)
            {
                //logAlpha[0, i] = MathE.elnproduct(MathE.eln(pi[i]), MathE.eln(emission[i, O[0]]));
                logAlpha[0, i] = MathE.elnproduct(logPi[i], logEmission[i, O[0]]);
            }

            //compute a_t(i)
            for (int t = 1; t < T; t++)
            {
                for (int i = 0; i < N; i++)
                {
                    double logalpha = MathE.LOGZERO;
                    //alpha[t, i] = 0;
                    for (int j = 0; j < N; j++)
                    {
                        //logalpha = MathE.elnsum(logalpha, MathE.elnproduct(logAlpha[t - 1, j], MathE.eln(transition[j, i])));
                        logalpha = MathE.elnsum(logalpha, MathE.elnproduct(logAlpha[t - 1, j], logTransition[j, i]));
                    }

                    // logAlpha[t, i] = MathE.elnproduct(logalpha, MathE.eln(emission[i, O[t]]));
                    logAlpha[t, i] = MathE.elnproduct(logalpha, logEmission[i, O[t]]);
                }
            }

            return(logAlpha);

            #endregion
        }
Пример #5
0
        private void UpdateModel(int[][] Obs)
        {
            int N = states;
            int M = observationSymbols;

            int K = Obs.GetLength(0);



            Dictionary <int, double[, ]>   alphas = new Dictionary <int, double[, ]>();
            Dictionary <int, double[, ]>   betas  = new Dictionary <int, double[, ]>();
            Dictionary <int, double[, ]>   gammas = new Dictionary <int, double[, ]>();
            Dictionary <int, double[, , ]> etas   = new Dictionary <int, double[, , ]>();

            for (int k = 0; k < K; k++)
            {
                int[] O = Obs[k];
                int   T = O.Length;

                var logAlpha = LogSpaceForward(O);
                var logBeta  = LogSpaceBackward(O);
                var logGamma = LogSpaceGamma(O, logAlpha, logBeta);
                var logEta   = LogSpaceEta(O, logAlpha, logBeta);

                alphas[k] = logAlpha;
                betas[k]  = logBeta;
                gammas[k] = logGamma;
                etas[k]   = logEta;
            }

            #region Re-estimation of parameters



            // re-sestimate pi



            for (int i = 0; i < N; i++)
            {
                double logpi = MathE.LOGZERO;
                for (int k = 0; k < K; k++)
                {
                    var logGamma = gammas[k];
                    int T        = Obs[k].Length;

                    logpi = MathE.elnsum(logpi, logGamma[0, i]);
                }
                logPi[i] = MathE.elnproduct(logpi, -K);
            }



            // re-estimate A
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    double numer = MathE.LOGZERO;
                    double denom = MathE.LOGZERO;

                    for (int k = 0; k < K; k++)
                    {
                        var logEta   = etas[k];
                        var logGamma = gammas[k];
                        int T        = Obs[k].Length;

                        for (int t = 0; t < T - 1; t++)
                        {
                            numer = MathE.elnsum(numer, logEta[t, i, j]);
                            denom = MathE.elnsum(denom, logGamma[t, i]);
                        }
                    }
                    logTransition[i, j] = MathE.elnproduct(numer, -denom);
                }
            }



            // re-estimate B
            for (int j = 0; j < N; j++)
            {
                for (int ki = 0; ki < M; ki++)
                {
                    double numer = MathE.LOGZERO;
                    double denom = MathE.LOGZERO;
                    for (int k = 0; k < K; k++)
                    {
                        var logEta   = etas[k];
                        var logGamma = gammas[k];
                        int T        = Obs[k].Length;

                        for (int t = 0; t < T; t++)
                        {
                            if (Obs[k][t] == ki)
                            {
                                numer = MathE.elnsum(numer, logGamma[t, j]);
                            }
                            denom = MathE.elnsum(denom, logGamma[t, j]);
                        }
                    }
                    logEmission[j, ki] = MathE.elnproduct(numer, -denom);
                }
            }

            #endregion
        }