def test_hmm_likelihood(T=1000, K=5, D=2): # Create a true HMM A = npr.rand(K, K) A /= A.sum(axis=1, keepdims=True) A = 0.75 * np.eye(K) + 0.25 * A C = npr.randn(K, D) sigma = 0.01 # Sample from the true HMM z = np.zeros(T, dtype=int) y = np.zeros((T, D)) for t in range(T): if t > 0: z[t] = np.random.choice(K, p=A[z[t - 1]]) y[t] = C[z[t]] + np.sqrt(sigma) * npr.randn(D) # Compare to pyhsmm answer from pyhsmm.models import HMM as OldHMM from pybasicbayes.distributions import Gaussian oldhmm = OldHMM( [Gaussian(mu=C[k], sigma=sigma * np.eye(D)) for k in range(K)], trans_matrix=A, init_state_distn="uniform") true_lkhd = oldhmm.log_likelihood(y) # Make an HMM with these parameters hmm = HMM(K, D, observations="diagonal_gaussian") hmm.transitions.log_Ps = np.log(A) hmm.observations.mus = C hmm.observations.sigmasq = sigma * np.ones((K, D)) test_lkhd = hmm.log_probability(y) assert np.allclose(true_lkhd, test_lkhd)
import matplotlib import matplotlib.pyplot as plt from ssm.models import HMM # Set the parameters of the HMM T = 500 # number of time bins K = 5 # number of discrete states D = 2 # number of observed dimensions # Make an HMM with the true parameters true_hmm = HMM(K, D, observations="gaussian") z, y = true_hmm.sample(T) z_test, y_test = true_hmm.sample(T) true_ll = true_hmm.log_probability(y) # Fit models N_sgd_iters = 1000 N_em_iters = 100 print("Fitting HMM with SGD") hmm = HMM(K, D, observations="gaussian") hmm_sgd_lls = hmm.fit(y, method="sgd", num_iters=N_sgd_iters) hmm_sgd_test_ll = hmm.log_probability(y_test) hmm_sgd_smooth = hmm.smooth(y) print("Fitting HMM with EM") hmm = HMM(K, D, observations="gaussian") hmm_em_lls = hmm.fit(y, method="em", num_em_iters=N_em_iters) hmm_em_test_ll = hmm.log_probability(y_test)
import matplotlib import matplotlib.pyplot as plt from ssm.models import HMM from ssm.util import find_permutation # Set the parameters of the HMM T = 500 # number of time bins K = 5 # number of discrete states D = 2 # number of observed dimensions # Make an HMM with the true parameters true_hmm = HMM(K, D, observations="diagonal_gaussian") z, y = true_hmm.sample(T) z_test, y_test = true_hmm.sample(T) true_ll = true_hmm.log_probability(y) # Fit models N_sgd_iters = 1000 N_em_iters = 100 # A bunch of observation models that all include the # diagonal Gaussian as a special case. observations = [ "diagonal_gaussian", "gaussian", "diagonal_t", "studentst", "diagonal_ar", "ar", "diagonal_robust_ar", "robust_ar" ] # Fit with both SGD and EM methods = ["sgd", "em"]
# Make an HMM true_hmm = HMM(K, D, M, observations="categorical", observation_kwargs=dict(C=C), transitions="inputdriven") # Optionally, turn up the input weights to exaggerate the effect # true_hmm.transitions.Ws *= 3 # Create an exogenous input inpt = np.sin(2 * np.pi * np.arange(T) / 50)[:, None] + 1e-1 * npr.randn(T, M) # Sample some data from the HMM z, y = true_hmm.sample(T, input=inpt) # Compute the true log probability of the data, summing out the discrete states true_lp = true_hmm.log_probability(y, inputs=inpt) # In[3]: # Plot the data plt.figure(figsize=(8, 5)) plt.subplot(311) plt.plot(inpt) plt.xticks([]) plt.xlim(0, T) plt.ylabel("input") plt.subplot(312)