private HMMGraph Splitstate(Node qPrime, HMMGraph graph) { Random random = new Random(); Node q1 = new Node(); foreach (Node x in graph.Nodes) { q1.SetTransition(x, random.NextDouble()); } foreach (int symbol in qPrime.Emissions.Keys) { q1.SetEmission(symbol, qPrime.Emissions[symbol]); } q1.InitialProbability = qPrime.InitialProbability; foreach (Node n in graph.Nodes) { n.Transitions[q1] = random.NextDouble(); } q1.SetTransition(q1,random.NextDouble()); graph.AddNode(q1); graph.Normalize(); return graph; }
public void RemoveNode(Node n) { foreach (Node x in this.Nodes) { x.Transitions.Remove(n); } Nodes.Remove(n); }
static HMMGraph CreateGraph(int numberOfSymbols, int numberOfStates, double outDegree) { HMMGraph graph = new HMMGraph(numberOfSymbols); double initialProbabilitySum = 0.0; for (int i = 0; i < numberOfStates; i++) { Node node = new Node(); node.InitialProbability = random.NextDouble(); initialProbabilitySum += node.InitialProbability; node.Emissions = new Dictionary<int, double>(); for (int j = 0; j < numberOfSymbols; j++) { node.Emissions.Add(j, random.NextDouble()); } double emissionSum = node.Emissions.Values.Sum(); for (int j = 0; j < numberOfSymbols; j++) { node.Emissions[j] /= emissionSum; } graph.AddNode(node); } for (int i = 0; i < numberOfStates; i++) { graph.Nodes[i].InitialProbability /= initialProbabilitySum; graph.Nodes[i].Transitions = new Dictionary<Node, double>(); int outDeg = (int)(((i % 2) == 1) ? Math.Floor(outDegree) : Math.Ceiling(outDegree)); for (int j = 0; j < outDeg; j++) { graph.Nodes[i].Transitions.Add(graph.Nodes[((i + j) % numberOfStates)], random.NextDouble()); } double transitionSum = graph.Nodes[i].Transitions.Values.Sum(); for (int j = 0; j < outDeg; j++) { graph.Nodes[i].Transitions[graph.Nodes[((i + j) % numberOfStates)]] /= transitionSum; } } return graph; }
/// <summary> /// Sets a transition. If a transition exists for the same node, it is overwritten. /// If probability is 0, the transition is removed /// </summary> /// <param name="node"></param> /// <param name="prob"></param> public void SetTransition(Node node, double prob) { if (prob == 0) { if (Transitions.ContainsKey(node)) Transitions.Remove(node); } else { if (Transitions.ContainsKey(node)) Transitions[node] = prob; else Transitions.Add(node, prob); } }
public static HMMGraph HMM2Graph(HiddenMarkovModel hmm){ HMMGraph g = new HMMGraph(hmm.Symbols); Node[] nodes = new Node[hmm.States]; for (int i = 0; i < hmm.States; i++) { nodes[i] = new Node(); g.AddNode(nodes[i]); } for (int i = 0; i < hmm.States; i++) { nodes[i].InitialProbability = hmm.Probabilities[i]; for (int j = 0; j < hmm.States; j++) nodes[i].SetTransition(nodes[j], hmm.Transitions[i, j]); for (int k = 0; k < hmm.Symbols; k++) nodes[i].SetEmission(k, hmm.Emissions[i, k]); } return g; }
private double ComputeBackward(Node n, HMMGraph G, int t, int[] O) { if (backward[t,graph.Nodes.IndexOf(n)] == UNASSIGNED) { if (t == O.Length - 1) { backward[t, graph.Nodes.IndexOf(n)] = 1.0; } else { double sum = 0; foreach (Node ni in G.Nodes) { //sum += (n.Transitions.Keys.Contains(ni) ? n.Transitions[ni] : MINIMUM_PROB) // * (ni.Emissions.Keys.Contains(O[t+1]) ? ni.Emissions[O[t + 1]] : MINIMUM_PROB) // * ComputeBackward(ni, G, t + 1, O); double trans = (n.Transitions.Keys.Contains(ni) ? n.Transitions[ni] : MINIMUM_PROB); double emis = (ni.Emissions.Keys.Contains(O[t + 1]) ? ni.Emissions[O[t + 1]] : MINIMUM_PROB); double bwd = ComputeBackward(ni, G, t + 1, O); sum += trans * emis * bwd; //if (trans == 0.0 || emis == 0.0 || bwd == 0.0) { // Console.WriteLine("stuff"); //} } backward[t, graph.Nodes.IndexOf(n)] = sum; } } return backward[t, graph.Nodes.IndexOf(n)]; }
private double ComputeForward(Node n, HMMGraph G, int t, int[] O) { if (forward[t,graph.Nodes.IndexOf(n)] == UNASSIGNED) { if (t == 0) { forward[t,graph.Nodes.IndexOf(n)] = n.InitialProbability * (n.Emissions.Keys.Contains(O[t]) ? n.Emissions[O[t]] : MINIMUM_PROB); } else { double sum = 0; foreach (Node ni in G.Nodes) { sum += ComputeForward(ni, G, t - 1, O) * (ni.Transitions.Keys.Contains(n) ? ni.Transitions[n] : MINIMUM_PROB); } forward[t, graph.Nodes.IndexOf(n)] = sum * (n.Emissions.Keys.Contains(O[t]) ? n.Emissions[O[t]] : MINIMUM_PROB); } } return forward[t, graph.Nodes.IndexOf(n)]; }
// return a relative gamma value (Unscaled) private double ComputeGamma(Node n, HMMGraph G, int t, int[] O) { //double result = (ComputeForward(n,G,t,O) * ComputeBackward(n, G, t, O)) // / ComputeLikelihood(G,O); double fwd = ComputeForward(n, G, t, O); double bwd = ComputeBackward(n, G, t, O); double likelihood = ComputeLikelihood(G, O); double result = (fwd * bwd) / likelihood; return result; }
public double ComputeGamma(Node n, HMMGraph G, int[] O) { double sum = 0; for(int t=0; t<O.Length; t++) { sum += ComputeGamma(n, G, t, O); } return sum; }
private double ComputeKsi(Node na, Node nb, HMMGraph G, int t, int[] O) { return ComputeForward(na, G, t, O) * (na.Transitions.Keys.Contains(nb) ? na.Transitions[nb] : MINIMUM_PROB) * (nb.Emissions.Keys.Contains(O[t+1]) ? nb.Emissions[O[t + 1]] : MINIMUM_PROB) * ComputeBackward(nb, G, t + 1, O); }
public HMMGraph ToGraph() { HMMGraph graph = new HMMGraph(NumberOfSymbols); for (int i = 0; i < NumberOfStates; i++) { Node node = new Node(); node.InitialProbability = initialDistribution[i]; node.Emissions = emissions[i].ToDictionary(j => j, j => emissionProbabilities[i, j]); graph.AddNode(node); } for (int i = 0; i < NumberOfStates; i++) { graph.Nodes[i].Transitions = transitionsOut[i].ToDictionary(j => graph.Nodes[j], j => transitionProbabilities[i, j]); } return graph; }
public void AddNode(Node n) { Nodes.Add(n); }
private void AssignEmissions(Node qPrime, Node q1, Node q2) { double sum = qPrime.Emissions.Values.Sum(); var emissions = (from e in qPrime.Emissions select e).OrderBy(em => em.Value).ToList(); while (q1.Emissions.Values.Sum() < sum / 2) { q1.Emissions.Add(emissions[0].Key, emissions[0].Value); emissions.RemoveAt(0); } q2.Emissions = emissions.ToDictionary(kv => kv.Key, kv => kv.Value); }
private void AssignTransitions(Node qPrime, Node q1, Node q2) { double sum = qPrime.Transitions.Values.Sum(); var trans = (from tr in qPrime.Transitions select tr).OrderBy(tra => tra.Value).ToList(); while (q1.Transitions.Values.Sum() < sum / 2) { q1.Transitions.Add(trans[0].Key, trans[0].Value); trans.RemoveAt(0); } q2.Transitions = trans.ToDictionary(kv => kv.Key, kv => kv.Value); //q1.SetTransition(q1, 0.1); //q2.SetTransition(q2, 0.1); }
// Assign incoming transitions to qPrime between q1 and q2 private void AssignIncomingTransitions(Node qPrime, Node q1, Node q2, HMMGraph graph) { #region Junk //Dictionary<Node, double> trans = new Dictionary<Node, double>(); //foreach (Node n in graph.Nodes) //{ // Dictionary<Node, double> trs = n.Transitions; // foreach (KeyValuePair<Node, double> kv in trs) // { // trans.Add(kv.Key, kv.Value); // } //} ////Dictionary<Node,double> rTrans = (from t in trans //// where t.Key == qPrime //// select t).ToDictionary(x => x.Key, x => x.Value); //List<KeyValuePair<Node,double>> rTrans = (from t in trans // where t.Key == qPrime // select t).ToList(); //var trans = (from n in graph.Nodes // select n.Transitions.ToList()).SelectMany(x => x); //var rTrans = (from kv in trans // where kv.Key == qPrime // select kv).ToList<KeyValuePair<Node,double>>(); //foreach (KeyValuePair<Node, double> kv in rTrans) { // if (rTrans.IndexOf(kv) < rTrans.Count / 2) { // kv.Key = q1; // } // else { // kv.Key = q2; // } //(rTrans.IndexOf(kv) < rTrans.Count / 2) ? (kv.Key = q1) : (kv.Key = q2); #endregion int tCount = 0; foreach (Node n in graph.Nodes) { if (n.Transitions.ContainsKey(qPrime)) { tCount++; } } int q1Count = 0; foreach (Node n in graph.Nodes) { if (n.Transitions.ContainsKey(qPrime)) { double prob = n.Transitions[qPrime]; n.SetTransition(qPrime, 0); if (q1Count < tCount / 2) { n.SetTransition(q1, prob); } else { n.SetTransition(q2, prob); } } } }