def calcxi(self, observ, alpha=None, beta=None): if alpha is None: alpha = self._calcalpha(observ) if beta is None: beta = self._calcbeta(observ) xi = np.zeros((len(observ), self.n, self.n), dtype=self.precision) for t in xrange(len(observ) - 1): normalizer = safemath.LOGZERO for i in xrange(self.n): for j in xrange(self.n): xi[t][i][j] = safemath.safelnprod( alpha[t][i], safemath.safelnprod( safemath.safeln(self.A[i][j]), safemath.safelnprod( safemath.safeln(self.B[j][t + 1]), beta[t + 1][j]))) normalizer = safemath.safelnsum(normalizer, xi[t][i][j]) for i in xrange(self.n): for j in xrange(self.n): xi[t][i][j] = safemath.safelnprod(xi[t][i][j], -1 * normalizer) return xi
def calcgamma(self, alpha, beta, seqlen): gamma = np.zeros((seqlen, self.n), dtype=self.precision) for t in xrange(seqlen): normalizer = safemath.LOGZERO for i in xrange(self.n): gamma[t][i] = safemath.safelnprod(alpha[t][i], beta[t][i]) normalizer = safemath.safelnsum(normalizer, gamma[t][i]) for i in xrange(self.n): gamma[t][i] = safemath.safelnprod(gamma[t][i], -1 * normalizer) return gamma
def calcbeta(self, observ): beta = np.zeros((len(observ), self.n), dtype=self.precision) # induction for t in xrange(len(observ) - 2, -1, -1): for i in xrange(self.n): logbeta = safemath.LOGZERO for j in xrange(self.n): logbeta = safemath.safelnsum( logbeta, safemath.safelnprod( safemath.safeln(self.A[i][j]), safemath.safelnprod( safemath.safeln(self.B[j][t + 1]), beta[t + 1][j]))) beta[t][i] = logbeta return beta
def viterbi(self, observ): self.calcB(observ) delta = np.zeros((len(observ), self.n), dtype=self.precision) psi = np.zeros((len(observ), self.n), dtype=np.int32) for t in xrange(len(observ)): for j in xrange(self.n): delta[t][j] = safemath.LOGZERO psi[t][j] = 0 # init for x in xrange(self.n): delta[0][x] = safemath.safelnprod(safemath.safeln(self.pi[x]), safemath.safeln(self.B[x][0])) # induction for t in xrange(1, len(observ)): for j in xrange(self.n): for i in xrange(self.n): if safemath.safeislt(delta[t][j], (safemath.safelnprod( delta[t - 1][i], safemath.safeln(self.A[i][j])))): delta[t][j] = safemath.safelnprod( delta[t - 1][i], safemath.safeln(self.A[i][j])) psi[t][j] = i delta[t][j] = safemath.safelnprod( delta[t][j], safemath.safeln(self.B[j][t])) # find max prob in time T p_max = safemath.LOGZERO path = np.zeros(len(observ), dtype=np.int32) for i in xrange(self.n): if safemath.safeislt(p_max, delta[len(observ) - 1][i]): p_max = delta[len(observ) - 1][i] path[len(observ) - 1] = i # backtracking for i in xrange(1, len(observ)): path[len(observ) - i - 1] = psi[len(observ) - i][path[len(observ) - i]] return path
def calcalpha(self, observ): alpha = np.ones((len(observ), self.n), dtype=self.precision) # allocation # init stage - alpha_1(x) = pi(x)b_x(O1) for x in xrange(self.n): alpha[0][x] = safemath.safelnprod(safemath.safeln(self.pi[x]), safemath.safeln(self.B[x][0])) # induction for t in xrange(1, len(observ)): for j in xrange(self.n): logalpha = safemath.LOGZERO for i in xrange(self.n): logalpha = safemath.safelnsum( logalpha, safemath.safelnprod(alpha[t - 1][i], safemath.safeln(self.A[i][j]))) alpha[t][j] = safemath.safelnprod( logalpha, safemath.safeln(self.B[j][t])) return alpha
def reestimateA(self, observ, xi, gamma): new_A = np.zeros((self.n, self.n), dtype=self.precision) for i in xrange(self.n): for j in xrange(self.n): numer = safemath.LOGZERO denom = safemath.LOGZERO for t in xrange(len(observ) - 1): numer = safemath.safelnsum(numer, xi[t][i][j]) denom = safemath.safelnsum(denom, gamma[t][i]) new_A[i][j] = safemath.safeexp( safemath.safelnprod(numer, -1 * denom)) return new_A