package socket; public class Viterbi { private static String[] states = { "#", "NN", "VB" }; private static String[] observations = { "I", "write", "a letter" }; private static double[] start_probability = { 0.3, 0.4, 0.3 }; private static double[][] transition_probability = { { 0.2, 0.2, 0.6 }, { 0.4, 0.1, 0.5 }, { 0.1, 0.8, 0.1 } }; private static double[][] emission_probability = { { 0.01, 0.02, 0.02 }, { 0.8, 0.01, 0.5 }, { 0.19, 0.97, 0.48 } }; private static class TNode { public int[] v_path; public double v_prob; public TNode( int[] v_path, double v_prob) { this.v_path = copyIntArray(v_path); this.v_prob = v_prob; } } private static int[] copyIntArray(int[] ia) { int[] newIa = new int[ia.length]; for (int i = 0; i < ia.length; i++) { newIa[i] = ia[i]; } return newIa; } private static int[] copyIntArray(int[] ia, int newInt) { int[] newIa = new int[ia.length + 1]; for (int i = 0; i < ia.length; i++) { newIa[i] = ia[i]; } newIa[ia.length] = newInt; return newIa; } // forwardViterbi(observations, states, start_probability, // transition_probability, emission_probability) public int[] forwardViterbi(String[] y, String[] X, double[] sp, double[][] tp, double[][] ep) { TNode[] T = new TNode[X.length]; for (int state = 0; state < X.length; state++) { int[] intArray = new int[1]; intArray[0] = state; T[state] = new TNode( intArray, sp[state] * ep[state][0]); } for (int output = 1; output < y.length; output++) { TNode[] U = new TNode[X.length]; for (int next_state = 0; next_state < X.length; next_state++) { int[] argmax = new int[0]; double valmax = 0; for (int state = 0; state < X.length; state++) { int[] v_path = copyIntArray(T[state].v_path); double v_prob = T[state].v_prob; double p = ep[next_state][output] * tp[state][next_state]; v_prob *= p; if (v_prob > valmax) { if (v_path.length == y.length) { argmax = copyIntArray(v_path); } else { argmax = copyIntArray(v_path, next_state); } valmax = v_prob; } } U[next_state] = new TNode( argmax, valmax); } T = U; } // apply sum/max to the final states: int[] argmax = new int[0]; double valmax = 0; for (int state = 0; state < X.length; state++) { int[] v_path = copyIntArray(T[state].v_path); double v_prob = T[state].v_prob; if (v_prob > valmax) { argmax = copyIntArray(v_path); valmax = v_prob; } } System.out.print("Viterbi path: ["); for (int i = 0; i < argmax.length; i++) { System.out.print(states[argmax[i]] + ", "); } System.out.println("].\n Probability of the whole system: " + valmax); return argmax; } public static void main(String[] args) throws Exception { System.out.print("\nStates: "); for (int i = 0; i < states.length; i++) { System.out.print(states[i] + ", "); } System.out.print("\n\nObservations: "); for (int i = 0; i < observations.length; i++) { System.out.print(observations[i] + ", "); } System.out.print("\n\nStart probability: "); for (int i = 0; i < states.length; i++) { System.out.print(states[i] + ": " + start_probability[i] + ", "); } System.out.println("\n\nTransition probability:"); for (int i = 0; i < states.length; i++) { System.out.print(" " + states[i] + ": {"); for (int j = 0; j < states.length; j++) { System.out.print(" " + states[j] + ": " + transition_probability[i][j] + ", "); } System.out.println("}"); } System.out.println("\n\nEmission probability:"); for (int i = 0; i < states.length; i++) { System.out.print(" " + states[i] + ": {"); for (int j = 0; j < observations.length; j++) { System.out.print(" " + observations[j] + ": " + emission_probability[i][j] + ", "); } System.out.println("}"); } Viterbi v=new Viterbi(); v.forwardViterbi(observations, states, start_probability, transition_probability, emission_probability); } }