public override void Learn(SequenceData trainingData, SequenceData validationData, SequenceData testData) {
            HMMGraph graph = new HMMGraph(trainingData.NumSymbols);

            //Add nodes and set initial and emission probabilities
            for (int i = 0; i < states; i++) {
                Node new_node = new Node();
                for (int s = 0; s < trainingData.NumSymbols; s++)
                    new_node.SetEmission(s, ran.NextDouble());
                new_node.InitialProbability = ran.NextDouble();
                graph.AddNode(new_node);
            }


            //Add random transmissions. Each node will have at most Log(n) edges in both directions
            //for (int i = 0; i < graph.Nodes.Count; i++)
            //{
            //    List<Node> shuffled = graph.Nodes.Select(e => e).ToList();
            //    Utilities.Shuffle(shuffled);
            //    int upperBound = (int)Math.Ceiling(Math.Log(graph.Nodes.Count));
            //    if (upperBound >= graph.Nodes.Count)
            //        upperBound = graph.Nodes.Count - 1;
            //    for (int p = 0; p <= upperBound; p++)
            //    {
            //        Node from = graph.Nodes[i];
            //        Node to = graph.Nodes[p];
            //        from.SetTransition(to, ran.NextDouble());
            //    }
            //}

            int numberOfTransitions = (int)Math.Ceiling(Math.Log(states));

            foreach (Node node in graph.Nodes)
            {
                for (int i = 0; i < numberOfTransitions; i++)
                {
                    Node target;
                    while (node.Transitions.ContainsKey(target = graph.Nodes[ran.Next(states)]));

                    node.SetTransition(target, ran.NextDouble());
                }
            }

            graph.Normalize();
			hmm = SparseHiddenMarkovModel.FromGraph(graph);
            hmm.Learn(trainingData.GetNonempty(), tolerance);
        }
        private HMMGraph RandomGraph(int num_symbols)
        {
            HMMGraph graph = new HMMGraph(num_symbols);

            graph.Nodes = Enumerable.Range(0, num_symbols).Select(_ => new Node()).ToList();

            foreach (Node node in graph.Nodes)
            {
                node.InitialProbability = random.NextDouble();

                foreach (Node n in graph.Nodes)
                {
                    node.SetTransition(n, random.NextDouble());
                }

                for (int i = 0; i < num_symbols; i++)
                {
                    node.SetEmission(i, random.NextDouble());
                }
            }

            return graph;
        }
        private void SplitWorstPerformingNode(HMMGraph graph, int node)
        {
            Node splitNode = graph.Nodes[node];
            Node newNode = new Node();

            graph.AddNode(newNode);

            //splitNode.InitialProbability /= 2;
            newNode.InitialProbability = splitNode.InitialProbability;

            foreach (Node n in splitNode.Transitions.Keys)
            {
                newNode.SetTransition(n, splitNode.Transitions[n]);
            }

            foreach (int i in splitNode.Emissions.Keys)
            {
                newNode.SetEmission(i, splitNode.Emissions[i]);
            }

            foreach (Node n in graph.Nodes)
            {
                if (n.Transitions.ContainsKey(splitNode))
                {
                    //n.Transitions[splitNode] /= 2;
                    n.SetTransition(newNode, n.Transitions[splitNode]);

                    Node weakestTransition = n.Transitions.Keys.Aggregate((a, b) => ((n.Transitions[b] < n.Transitions[a]) ? b : a));

                    n.Transitions.Remove(weakestTransition);
                }
            }

            graph.Normalize();
        }
        private int RemoveDeadStates(HMMGraph graph)
        {
            int deadNodes = 0;
            Dictionary<Node, bool> hasInTrans = graph.Nodes.ToDictionary(node => node, _ => false);

            foreach (Node node in graph.Nodes)
            {
                if (node.InitialProbability > 0)
                {
                    hasInTrans[node] = true;
                }

                foreach (Node trans in node.Transitions.Keys)
                {
                    hasInTrans[trans] = true;
                }
            }

            for (int i = 0; i < graph.NumNodes; i++)
            {
                if (!hasInTrans[graph.Nodes[i]])
                {
                    deadNodes++;
                    graph.Nodes.RemoveAt(i);
                    i--;

                    continue;
                }

                if (graph.Nodes[i].Transitions.Count == 0)
                {
                    foreach (Node node in graph.Nodes)
                    {
                        node.Transitions.Remove(node);
                    }

                    deadNodes++;
                    graph.Nodes.RemoveAt(i);
                    i--;
                }
            }

            return deadNodes;
        }
        private int RemoveUnpopularStates(HMMGraph graph, double[] scores)
        {
            int[] unpopularStates = Enumerable.Range(0, NumberOfStates).Where(i => (scores[i] == 0)).OrderByDescending(i => i).ToArray();

            foreach (Node node in graph.Nodes)
            {
                foreach (int unpopularState in unpopularStates)
                {
                    node.Transitions.Remove(graph.Nodes[unpopularState]);
                }
            }

            foreach (int unpopularState in unpopularStates)
            {
                graph.Nodes.RemoveAt(unpopularState);
            }

            return unpopularStates.Length;
        }
        private void CutEdges(HMMGraph graph, double epsilon)
        {
            foreach (Node node in graph.Nodes)
            {
                if (node.InitialProbability < epsilon)
                {
                    node.InitialProbability = 0;
                }

                node.Transitions = node.Transitions.Keys.Where(n => (node.Transitions[n] >= epsilon)).ToDictionary(n => n, n => node.Transitions[n]);
            }

            graph.Normalize();
        }
        private void SplitState(HMMGraph graph, int state)
        {
            Node newNode = new Node();

            foreach (Node node in graph.Nodes)
            {
                if (node.Transitions.ContainsKey(graph.Nodes[state]))
                {
                    //node.SetTransition(newNode, (node.Transitions[graph.Nodes[state]] / 2));
                    //node.Transitions[graph.Nodes[state]] /= 2;
                    node.SetTransition(newNode, random.NextDouble());
                }
            }

            foreach (Node node in graph.Nodes[state].Transitions.Keys)
            {
                //newNode.SetTransition(node, graph.Nodes[state].Transitions[node]);
                newNode.SetTransition(node, random.NextDouble());
            }

            foreach (int symbol in graph.Nodes[state].Emissions.Keys)
            {
                //newNode.SetEmission(symbol, graph.Nodes[state].Emissions[symbol]);
                newNode.SetEmission(symbol, random.NextDouble());
            }

            //newNode.InitialProbability = (graph.Nodes[state].InitialProbability / 2);
            //graph.Nodes[state].InitialProbability /= 2;
            newNode.InitialProbability = random.NextDouble();

            graph.Nodes.Add(newNode);

            graph.Normalize();
        }
Пример #8
0
        private void CutEdges(HMMGraph graph, double temperature)
        {
            foreach (Node node in graph.Nodes)
            {
                node.Transitions = node.Transitions.Keys.Where(n => (node.Transitions[n] >= temperature)).ToDictionary(n => n, n => node.Transitions[n]);
            }

            graph.Normalize();
        }