利用HMM与Viterbi算法来纠正印刷错误算法、错误、HMM、Viterbi

2023-09-11 07:08:32 作者:关键时候自保っ

我想用HMM与Viterbi算法来纠正印刷错误,我计算出所需的概率,但是当我申请Viterbi算法我得到了很糟糕的结果,我检查线路code线,我无法找到错误

 公共ForwardViterbi(字符串[]的状态,字符串[]的意见,双[] startProbability,双[,] transitionProbability,双[,] emissionProbability,双比例因子)
        {

            this.states =状态;
            this.observations =观测;
            this.startProbability = startProbability;
            this.transitionProbability = transitionProbability;
            this.emissionProbability = emissionProbability;
            this.scaleFactor =比例因子;

        }

        // ------------------------------------------------ ----------------------
        //方法

        公共无效处理(INT []的问题)
        {

            双[,] T =新的双[states.Length,3]。 //我们将存储概率序列的维特比路径
            VPATH =新INT [problem.Length]
            vProbs =新的双[problem.Length]

            //初始化Ť
            // ------------------------------------------------ ------------------
            对于(INT状态= 0;状态< states.Length;状态++)
            {
                T [状态,0] = startProbability [状态];
                T [状态1] =状态;
                T [状态,2] = startProbability [状态];
            }

            对于(INT输出= 0;输出< problem.Length;输出++)
            {

                双[,] U =新的双[states.Length,3]。 //我们将使用这个数组来计算未来的可能性

                Console.WriteLine(\ nTesting假设{0}({1}),输出的观察[问题[输出]);
                双最高= 0;

                对于(INT nextState = 0; nextState< states.Length; nextState ++)
                {
                    双总= 0;
                    双argMax = 0;
                    双valMax = 0;

                    Console.WriteLine(估计概率为未来的状态{0}({1}),nextState,各国[nextState]);
                    对于(INT状态= 0;状态< states.Length;状态++)
                    {
                        Console.WriteLine(测试状态为{0}({1}),规定[状态],状态);
                        双概率= T [状态,0];
                        双v_path = T [状态1]。
                        双v_prob = T [状态,2]。
                        双P = emissionProbability [状态,问题[输出] * transitionProbability [状态,nextState] *比例因子;
                        概率* = P;
                        v_prob * = P;
                        共有+ =概率;

                        如果(v_prob> valMax)
                        {
                            valMax = v_prob;
                            argMax = nextState;
                        }

                        Console.WriteLine(中VProbability {0} {1}具有规模{2} ^ {3},规定[nextState],v_prob,比例因子,输出+ 1);

                        如果(v_prob>最高)
                        {
                            最高= v_prob;
                            VPATH [输出] = nextState;
                            vProbs [输出] = v_prob;
                        }
                    }

                    U [nextState,0] =总;
                    U [nextState,1] = argMax;
                    U [nextState,2] = valMax;
                }
                T = U;
                Console.WriteLine(最高的概率为{0}在{2} ^ {3})状态{1}(比例因子,最高,状态[VPATH [输出],比例因子,输出+ 1);
            }


            //应用SumMax
            双总= 0;
            双ValMax = 0;

            对于(INT状态= 0;状态< states.Length;状态++)
            {
                双概率= T [状态,0];
                双v_path = T [状态1]。
                双v_prob = T [状态,2]。

                共有+ =概率;
                如果(v_prob> ValMax)
                {
                    ValMax = v_prob;
                }
            }

            Console.WriteLine(\ nAnalysis:总概率(所有路径的总和)为给定的状态,:: {0} \ n此维特比路径概率为:: {1},道达尔,ValMax);
            Console.WriteLine(以上的结果psented含{0} ^ {1}的一个比例因子$ P $,比例因子,problem.Length);

        }
 

解决方案

我刚刚检查过这实现和的一篇发表在维基百科。 这其中似乎并没有工作。在一个在维基百科目前的工作。 如果你想 - 你可以对它们进行比较,但我懒得做这种

(我已经实现解决方案,正是您的问题,描述的这里)

I want to use HMM with Viterbi Algorithm to correct typographical errors, I calculated the required probability but when I apply Viterbi algorithm I got very bad results, I checked the code line by line and I couldn't find the error

public ForwardViterbi(string[] states, string[] observations, double[] startProbability, double[,] transitionProbability, double[,] emissionProbability, double scaleFactor)
        {

            this.states = states;
            this.observations = observations;
            this.startProbability = startProbability;
            this.transitionProbability = transitionProbability;
            this.emissionProbability = emissionProbability;
            this.scaleFactor = scaleFactor;

        }

        //----------------------------------------------------------------------
        //The Methods

        public void Process(int[] problem)
        {

            double[,] T = new double[states.Length, 3];  //We will store the probability sequence for the Viterbi Path
            vPath = new int[problem.Length];
            vProbs = new double[problem.Length];

            //initialize T
            //------------------------------------------------------------------    
            for (int state = 0; state < states.Length; state++)
            {
                T[state, 0] = startProbability[state];
                T[state, 1] = state;
                T[state, 2] = startProbability[state];
            }

            for (int output = 0; output < problem.Length; output++)
            {

                double[,] U = new double[states.Length, 3];  //We will use this array to calculate the future probabilities

                Console.WriteLine("\nTesting hypothesis {0} ({1})", output, observations[problem[output]]);
                double highest = 0;

                for (int nextState = 0; nextState < states.Length; nextState++)
                {
                    double total = 0;
                    double argMax = 0;
                    double valMax = 0;

                    Console.WriteLine("  Estimating probability for future state {0} ({1})", nextState, states[nextState]);
                    for (int state = 0; state < states.Length; state++)
                    {
                        Console.WriteLine("    The testing state is {0} ({1})", states[state], state);
                        double prob = T[state, 0];
                        double v_path = T[state, 1];
                        double v_prob = T[state, 2];
                        double p = emissionProbability[state, problem[output]] * transitionProbability[state, nextState] * scaleFactor;
                        prob *= p;
                        v_prob *= p;
                        total += prob;

                        if (v_prob > valMax)
                        {
                            valMax = v_prob;
                            argMax = nextState;
                        }

                        Console.WriteLine("    VProbability of {0} is {1} with scale {2}^{3}", states[nextState], v_prob, scaleFactor, output + 1);

                        if (v_prob > highest)
                        {
                            highest = v_prob;
                            vPath[output] = nextState;
                            vProbs[output] = v_prob;
                        }
                    }

                    U[nextState, 0] = total;
                    U[nextState, 1] = argMax;
                    U[nextState, 2] = valMax;
                }
                T = U;
                Console.WriteLine("The highest probability was {0} in state {1} (scale factor of {2}^{3})", highest, states[vPath[output]], scaleFactor, output + 1);
            }


            //Apply SumMax
            double Total = 0;
            double ValMax = 0;

            for (int state = 0; state < states.Length; state++)
            {
                double prob = T[state, 0];
                double v_path = T[state, 1];
                double v_prob = T[state, 2];

                Total += prob;
                if (v_prob > ValMax)
                {
                    ValMax = v_prob;
                }
            }

            Console.WriteLine("\nAnalysis: Total probability (sum of all paths) for the given state is :: {0}\nThe Viterbi Path Probability is :: {1}", Total, ValMax);
            Console.WriteLine("The above results are presented with a scale factor of {0}^{1}", scaleFactor, problem.Length);

        }
隐马尔可夫 HMM 前 后向算法 Viterbi算法 再次总结

解决方案

I've just checked this implementation and the one published on wikipedia. This one doesn't seem to work. The one on wikipedia does work. If you want - you can compare them, but I'm lazy to do this.

(I've implemented solution for exactly your problem as described here)