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(); }
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(); }