def _em(self, trans, states): ''' Perform parameter estimation for a hidden Markov model (HMM). Perform parameter estimation for an HMM using multi-dimensional Gaussian states. The training observation sequences, signals, are available to the class, and states designates the initial allocation of emitting states to the signal time steps. The HMM parameters are estimated using Viterbi re-estimation. Note: It is possible that some states are never allocated any observations. Those states are then removed from the states table, effectively redusing the number of emitting states. In what follows, n_states is the original number of emitting states, while n_states' is the final number of emitting states, after those states to which no observations were assigned, have been removed. Parameters ---------- trans : (n_states+1,n_states+1) ndarray The left-to-right transition probability table. The rightmost column contains probability of transitioning to final state, and the last row the initial state's transition probabilities. Note that all the rows need to add to 1. states : (n_obs, n_states) ndarray Initial allocation of signal time-steps to states as a one-hot encoding. Thus 'states[:,j]' specifies the allocation of all the observations to state j. Return ------ trans : (n_states'+1,n_states'+1) ndarray Updated transition probability table dists : (n_states',) list Gaussian object of each component. newLL : float Log-likelihood of parameters at convergence. iters: int The number of iterations needed for convergence ''' covs, means = self._updatecovs(states) # Initialize the covariances and means using the initial state allocation dists = [Gaussian(mean=means[i], cov=covs[i]) for i in range(len(covs))] oldstates, trans, oldLL = self._calcstates(trans, dists) converged = False iters = 0 while not converged and iters < self.maxiters: covs, means = self._updatecovs(oldstates) dists = [Gaussian(mean=means[i], cov=covs[i]) for i in range(len(covs))] newstates, trans, newLL = self._calcstates(trans, dists) if abs(newLL - oldLL) / abs(oldLL) < self.rtol: converged = True oldstates, oldLL = newstates, newLL iters += 1 if iters >= self.maxiters: warn("Maximum number of iterations reached - HMM parameters may not have converged") return trans, dists, newLL, iters
def __init__(self, data, n_mix, sigma_min=0.1, sigma_max=1.0): self.data = data mu_min = min(data) mu_max = max(data) # create n-gaussians that will comprise the gaussian mixture model self.gaussians = {} # probability of each gaussians self.mix = {} # number of gaussians self.n_mix = n_mix # initialize the gaussians for i in range(0, n_mix): self.gaussians[i] = Gaussian(uniform(mu_min, mu_max), uniform(sigma_min, sigma_max)) self.mix[i] = 1/n_mix