Exemplo n.º 1
0
        DenseMatrix[] sigmas; //covariance of the 3D gaussians.

        #endregion Fields

        #region Constructors

        public CD_HMM(MarkovChain A, DenseVector pi, DenseVector[] mus, DenseMatrix[] sigmas)
        {
            this.A = A;
            this.pi = pi;
            this.mus = mus;
            this.sigmas = sigmas;
        }
Exemplo n.º 2
0
        public void reestimateParameters(DenseVector[][] observationsCollection)
        {
            int K = observationsCollection.Length;
            int[] times = new int[K];
            int N = A.numberOfStates;

            for (int k = 0; k < K; k++)
            {
                times[k] = observationsCollection[k].Length; //possible error?
            }

            double[][,] alphabars = new double[K][,];
            double[][,] alphahats = new double[K][,];
            double[][] scales = new double[K][];

            double[][,] betahats = new double[K][,];

            double[][,,] digammas = new double[K][,,];
            double[][,] gammas = new double[K][,];

            //Initialize arrays to proper sizes.
            for (int k = 0; k < K; k++)
            {
                alphahats[k]    = new double[times[k], N];
                alphabars[k]    = new double[times[k], N];
                scales[k]       = new double[times[k]];
                betahats[k]     = new double[times[k], N];
                digammas[k]     = new double[times[k],N,N];
                gammas[k]       = new double[times[k],N];
            }

            for (int k = 0; k < K; k++)
            {
                //The alpha pass
                scales[k][0] = 0;
                #region The alpha Pass
                for (int i = 0; i < N; i++)
                {
                    alphabars[k][0, i] = pi[i] * queryGuassian(observationsCollection[k][0], mus[i], sigmas[i]);
                    scales[k][0] += alphabars[k][0, i];
                }
                scales[k][0] = 1 / (scales[k][0]);

                for (int i = 0; i < N; i++)
                {
                    alphahats[k][0, i] = scales[k][0]*alphabars[k][0,i];
                }

                for (int t = 1; t < times[k]; t++)
                {
                    scales[k][t] = 0;
                    for (int i = 0; i < N; i++)
                    {
                        alphabars[k][t, i] = 0;
                        for (int j = 0; j < N; j++)
                        {
                            alphabars[k][t, i] += alphahats[k][t - 1, j] * A.getTransitionProb(j, i);
                        }
                        alphabars[k][t, i] *= queryGuassian(observationsCollection[k][t], mus[i], sigmas[i]);
                        scales[k][t] += alphabars[k][t, i];
                    }
                    scales[k][t] = 1 / (scales[k][t]);
                    for (int i = 0; i < N; i++)
                    {
                        alphahats[k][t, i] = scales[k][t]*alphabars[k][t,i];
                    }
                }

                #endregion

                #region The beta pass
                for (int i = 1; i < N; i++)
                {
                    betahats[k][times[k] - 1, i] = scales[k][times[k] - 1];
                }
                for (int t = times[k] - 2; t >= 0; t--)
                {
                    for (int i = 0; i < N; i++)
                    {
                        betahats[k][t, i] = 0;
                        for (int j = 0; j < N; j++)
                        {
                            betahats[k][t, i] += A.getTransitionProb(i, j) * queryGuassian(observationsCollection[k][t + 1], mus[j], sigmas[j]) * betahats[k][t + 1, j];
                        }
                        betahats[k][t, i] *= scales[k][t];
                    }
                }
                #endregion

                #region The gamma pass
                for (int t = 0; t < times[k] - 1; t++)
                {
                    for (int i = 0; i < N; i++)
                    {
                        for (int j = 0; j < N; j++)
                        {
                            digammas[k][t, i, j] = alphahats[k][t, i] * A.getTransitionProb(i, j) *
                                queryGuassian(observationsCollection[k][t + 1], mus[j], sigmas[j]) * betahats[k][t + 1, j];
                        }
                        gammas[k][t, i] = alphahats[k][t, i] * betahats[k][t, i] * (1 / scales[k][t]);
                    }
                }
                #endregion
            }

            #region re-estimate pi
            DenseVector newPi = new DenseVector(N);
            double numer, denom, piComp;
            for (int i = 0; i < N; i++)
            {
                numer = 0; denom = 0; piComp = 0;
                for (int k = 0; k < K; k++)
                {
                    numer += gammas[k][0, i];
                }
                for (int j = 0; j < numer; j++)
                {
                    for (int k = 0; k < K; k++)
                    {
                        denom += gammas[k][0, j];
                    }
                }
                piComp = numer / denom;
                newPi[i] = piComp;
            }

            #endregion

            #region re-estimate A
            DenseMatrix newA;
            double[,] newAarray = new double[N, N];
            for (int i = 0; i < N; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    numer = 0; denom = 0;

                    //Can these be simplified with the gammas?
                    for (int k = 0; k < K; k++)
                    {
                        for (int t = 0; t < times[k] - 1; t++)
                        {
                            numer += alphahats[k][t, i] * A.getTransitionProb(i, j) *
                                queryGuassian(observationsCollection[k][t + 1], mus[j], sigmas[j]) * betahats[k][t + 1, j];
                        }
                    }

                    for (int k = 0; k < K; k++)
                    {
                        for (int t = 0; t < times[k] - 1; t++)
                        {
                            denom += alphahats[k][t, i] * betahats[k][t, i] * (1 / scales[k][t]);
                        }
                    }
                    newAarray[i, j] = (numer / denom);
                }

            }
            newA = new DenseMatrix(newAarray);

            #endregion

            #region re-estimate mus
            DenseVector[] newMus = new DenseVector[N];
            //Initialize and zero the new mus
            for (int j = 0; j < N; j++)
            {
                newMus[j] = new DenseVector(observationsCollection[0][0].Count);
                for (int l = 0; l < observationsCollection[0][0].Count; l++)
                {
                    newMus[j][l] = 0;
                }

            }
            for (int j = 0; j < N; j++)
            {
                denom = 0;
                for (int k = 0; k < K; k++)
                {
                    for (int t = 0; t < times[k]; t++)
                    {
                        newMus[j] += gammas[k][t, j] * observationsCollection[k][t];
                        denom += gammas[k][t, j];
                    }
                }
                newMus[j] = (newMus[j] / denom);
            }
            #endregion

            #region re-estimate Sigmas
            DenseMatrix[] newSigmas = new DenseMatrix[N];
            DenseMatrix temp = new DenseMatrix(observationsCollection[0][0].Count);
            DenseVector tempvec = new DenseVector(observationsCollection[0][0].Count);
            for (int j = 0; j < N; j++)
            {
                newSigmas[j] = new DenseMatrix(observationsCollection[0][0].Count);
                for (int l = 0; l < observationsCollection[0][0].Count; l++)
                {
                    for (int m = 0; m < observationsCollection[0][0].Count; m++)
                    {
                        newSigmas[j][l, m] = 0;
                    }
                }

            }

            for (int j = 0; j < N; j++)
            {
                denom = 0;
                for (int k = 0; k < K; k++)
                {
                    for (int t = 0; t < times[k]; t++)
                    {
                        tempvec = observationsCollection[k][t] - newMus[j];
                        temp = DenseVector.OuterProduct(tempvec, tempvec);
                        newSigmas[j] += temp;

                        denom += gammas[k][t, j];
                    }
                }
                newSigmas[j] = newSigmas[j] * (1 / denom);
            }
            #endregion

            pi = newPi;
            A = new MarkovChain(newA);
            mus = newMus;
            sigmas = newSigmas;
        }