def backward(hmm, Obs, c=None): """ Calculate the probability of a partial observation sequence from t+1 to T, given some state t. Obs: observation sequence hmm: model c: the scaling coefficients from forward algorithm returns: B_t(i) """ # Number of states in observation sequence T = len(Obs) # Get index sequence of observation sequence to access the observable symbol prob distribution matrix Obs = symbol_index(hmm, Obs) # Allocate output array Beta = numpy.zeros([ hmm.N, T ], float) # Inductive Step: for t in reversed(xrange(T)): # Base Case Beta[ :, t ] = 1.0 if t == T - 1 else \ numpy.dot(hmm.A(t), (hmm.B(t + 1)[ :, Obs[ t + 1 ] ] * Beta[ :, t + 1 ])) # Inductive Step if c is not None: # Rarely, Beta might blow up when Alpha is exactly zero. This is not a problem without # scaling. For simplicity, cap Beta. # TODO: it might be safer to restart the algorithm with no scaling instead. Beta[ :, t ] = numpy.minimum(Beta[ :, t ] * c[ t ], 1e+100) # print t, Beta[:, t], c[t] #pass return Beta
def forward(hmm, Obs, scaling=True): """ Calculate the probability of an observation sequence, Obs, given the model, P(Obs|hmm). Obs: observation sequence hmm: model returns: P(Obs|hmm) """ # Number of states in observation sequence T = len(Obs) # Get index sequence of observation sequence to access the observable symbol prob distribution matrix Obs = symbol_index(hmm, Obs) # Allocate output array, scaling array Alpha = numpy.zeros([ hmm.N, T ], float) if scaling: c = numpy.zeros([ T ], float) # print 'forward sweep' # print 'Obs', Obs for t in xrange(T): # print 't', t # if t > 0: # print 'A', hmm.A(t - 1) # print 'B', hmm.B(t) # print 'Obs[t]', Obs[t] # print 'B[:, Obs[t]]', hmm.B(t)[ :, Obs[ t ] ] Alpha[ :, t ] = (hmm.Pi if t == 0 # Base Case else numpy.dot(Alpha[ :, t - 1 ], hmm.A(t - 1)) # Induction Step: ) * hmm.B(t)[ :, Obs[ t ] ] if scaling: c[ t ] = 1.0 / numpy.sum(Alpha[ :, t ]) Alpha[ :, t] = Alpha[ :, t] * c[ t ] #print t, Alpha[:, t], c[t] return (-(numpy.sum(numpy.log(c))), Alpha, c) if scaling else (numpy.sum(Alpha[ :, T - 1 ]), Alpha)
def backward(hmm, Obs, c=None): """ Calculate the probability of a partial observation sequence from t+1 to T, given some state t. Obs: observation sequence hmm: model c: the scaling coefficients from forward algorithm returns: B_t(i) """ # Number of states in observation sequence T = len(Obs) # Get index sequence of observation sequence to access the observable symbol prob distribution matrix Obs = symbol_index(hmm, Obs) # Allocate output array Beta = numpy.zeros([hmm.N, T], float) # Inductive Step: for t in reversed(xrange(T)): # Base Case Beta[ :, t ] = 1.0 if t == T - 1 else \ numpy.dot(hmm.A(t), (hmm.B(t + 1)[ :, Obs[ t + 1 ] ] * Beta[ :, t + 1 ])) # Inductive Step if c is not None: # Rarely, Beta might blow up when Alpha is exactly zero. This is not a problem without # scaling. For simplicity, cap Beta. # TODO: it might be safer to restart the algorithm with no scaling instead. Beta[:, t] = numpy.minimum(Beta[:, t] * c[t], 1e+100) # print t, Beta[:, t], c[t] #pass return Beta
def viterbi(hmm, Obs, scaling=True): """ Calculate P(Q|Obs, hmm) and yield the state sequence Q* that maximizes this probability. Obs: observation sequence hmm: model """ # Number of states in observation sequence T = len(Obs) # Get index sequence of observation sequence to access the observable symbol prob distribution matrix Obs = symbol_index(hmm, Obs) # Initialization # Delta[ i,j ] = max_q1,q2,...,qt P( q1, q2,...,qt = i, O_1, O_2,...,O_t|hmm ) # this is the highest prob along a single path at time t ending in state S_i Delta = numpy.zeros([hmm.N, T], float) # Track Maximal States Psi = numpy.zeros([hmm.N, T], int) # print 'scaling', scaling if scaling: Delta[:, 0] = _log(hmm.Pi) + _log(hmm.B(0)[:, Obs[0]]) else: Delta[:, 0] = hmm.Pi * hmm.B(0)[:, Obs[0]] # print 't', 0 # print 10 ** Delta[:, 0][numpy.newaxis].transpose() # Inductive Step: if scaling: for t in xrange(1, T): nus = Delta[:, t - 1] + _log(hmm.A(t - 1).transpose()) Delta[:, t] = nus.max(1) + _log(hmm.B(t)[:, Obs[t]]) Psi[:, t] = nus.argmax(1) # print 't', t # print 'A', # print hmm.A(t - 1) # print 'nus' # print 10 ** nus # print 'Delta' # print 10 ** Delta[:, t][numpy.newaxis].transpose() # print 'Psi' # print Psi[:, t][numpy.newaxis].transpose() else: for t in xrange(1, T): nus = Delta[:, t - 1] * hmm.A(t - 1).transpose() Delta[:, t] = nus.max(1) * hmm.B(t)[:, Obs[t]] Psi[:, t] = nus.argmax(1) # print 10 ** Delta # print Psi # Calculate State Sequence, Q*: Q_star = [numpy.argmax(Delta[:, T - 1])] for t in reversed(xrange(T - 1)): Q_star.insert(0, Psi[Q_star[0], t + 1]) return (numpy.array(Q_star), Delta, Psi)
def viterbi(hmm, Obs, scaling=True): """ Calculate P(Q|Obs, hmm) and yield the state sequence Q* that maximizes this probability. Obs: observation sequence hmm: model """ # Number of states in observation sequence T = len(Obs) # Get index sequence of observation sequence to access the observable symbol prob distribution matrix Obs = symbol_index(hmm, Obs) # Initialization # Delta[ i,j ] = max_q1,q2,...,qt P( q1, q2,...,qt = i, O_1, O_2,...,O_t|hmm ) # this is the highest prob along a single path at time t ending in state S_i Delta = numpy.zeros([ hmm.N, T ], float) # Track Maximal States Psi = numpy.zeros([ hmm.N, T ], int) # print 'scaling', scaling if scaling: Delta[ :, 0 ] = _log(hmm.Pi) + _log(hmm.B(0)[ :, Obs[ 0 ] ]) else: Delta[ :, 0 ] = hmm.Pi * hmm.B(0)[ :, Obs[ 0] ] # print 't', 0 # print 10 ** Delta[:, 0][numpy.newaxis].transpose() # Inductive Step: if scaling: for t in xrange(1, T): nus = Delta[ :, t - 1 ] + _log(hmm.A(t - 1).transpose()) Delta[ :, t ] = nus.max(1) + _log(hmm.B(t)[ :, Obs[ t ] ]) Psi[ :, t ] = nus.argmax(1) # print 't', t # print 'A', # print hmm.A(t - 1) # print 'nus' # print 10 ** nus # print 'Delta' # print 10 ** Delta[:, t][numpy.newaxis].transpose() # print 'Psi' # print Psi[:, t][numpy.newaxis].transpose() else: for t in xrange(1, T): nus = Delta[ :, t - 1 ] * hmm.A(t - 1).transpose() Delta[ :, t ] = nus.max(1) * hmm.B(t)[ :, Obs[ t ] ] Psi[ :, t ] = nus.argmax(1) # print 10 ** Delta # print Psi # Calculate State Sequence, Q*: Q_star = [ numpy.argmax(Delta[ :, T - 1 ]) ] for t in reversed(xrange(T - 1)) : Q_star.insert(0, Psi[ Q_star[ 0 ], t + 1 ]) return (numpy.array(Q_star), Delta, Psi)
def forward(hmm, Obs, scaling=True): """ Calculate the probability of an observation sequence, Obs, given the model, P(Obs|hmm). Obs: observation sequence hmm: model returns: P(Obs|hmm) """ # Number of states in observation sequence T = len(Obs) # Get index sequence of observation sequence to access the observable symbol prob distribution matrix Obs = symbol_index(hmm, Obs) # Allocate output array, scaling array Alpha = numpy.zeros([hmm.N, T], float) if scaling: c = numpy.zeros([T], float) # print 'forward sweep' # print 'Obs', Obs for t in xrange(T): # print 't', t # if t > 0: # print 'A', hmm.A(t - 1) # print 'B', hmm.B(t) # print 'Obs[t]', Obs[t] # print 'B[:, Obs[t]]', hmm.B(t)[ :, Obs[ t ] ] Alpha[:, t] = ( hmm.Pi if t == 0 # Base Case else numpy.dot(Alpha[:, t - 1], hmm.A(t - 1)) # Induction Step: ) * hmm.B(t)[:, Obs[t]] if scaling: c[t] = 1.0 / numpy.sum(Alpha[:, t]) Alpha[:, t] = Alpha[:, t] * c[t] #print t, Alpha[:, t], c[t] return (-(numpy.sum(numpy.log(c))), Alpha, c) if scaling else (numpy.sum(Alpha[:, T - 1]), Alpha)