def test_gradients(): K = 1 B = 3 T = 100 dt = 1.0 true_model = DiscreteTimeNetworkHawkesModelGammaMixture(K=K, B=B, dt=dt) S, R = true_model.generate(T=T) # Test with a standard Hawkes model test_model = DiscreteTimeStandardHawkesModel(K=K, B=B, dt=dt) test_model.add_data(S) # Check gradients with the initial parameters def objective(x): test_model.weights[0, :] = np.exp(x) return test_model.log_likelihood() def gradient(x): test_model.weights[0, :] = np.exp(x) return test_model.compute_gradient(0) print "Checking initial gradient: " print gradient(np.log(test_model.weights[0, :])) check_grad(objective, gradient, np.log(test_model.weights[0, :])) print "Checking gradient at true model parameters: " test_model.initialize_with_gibbs_model(true_model) print gradient(np.log(test_model.weights[0, :])) check_grad(objective, gradient, np.log(test_model.weights[0, :]))
def demo(seed=None): """ Create a discrete time Hawkes model and generate from it. :return: """ raise NotImplementedError("This example needs to be updated.") if seed is None: seed = np.random.randint(2**32) print("Setting seed to ", seed) np.random.seed(seed) C = 1 # Number of clusters in the true data K = 10 # Number of nodes T = 1000 # Number of time bins to simulate dt = 0.02 # Time bin size dt_max = 0.08 B = 3 # Number of basis functions # Sample from a sparse network Hawkes model S, true_model = sample_from_network_hawkes(C, K, T, dt, dt_max, B) # Make a new model for inference test_basis = IdentityBasis(dt, dt_max, allow_instantaneous=False) test_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, dt_max=dt_max + dt, beta=1.0, basis=test_basis, allow_self_connections=True) test_model.add_data(S) # DEBUG: Initialize with the true parameters of the network Hawkes model # test_model.initialize_with_gibbs_model(true_model) test_model.fit_with_bfgs() print("W true: ", true_model.weight_model.A * true_model.weight_model.W) print("lambda0 true: ", true_model.bias_model.lambda0) print("ll true: ", true_model.log_likelihood()) print("") print("W test: ", test_model.W) print("lambda0 test ", test_model.bias) print("ll test: ", test_model.log_likelihood()) plot_network(np.ones((K, K)), test_model.W, vmax=0.5) # Plot the rates plt.figure() for k in range(3): plt.subplot(3, 1, k + 1) plt.plot(np.arange(T) * dt, true_model.compute_rate(proc=k), '-b') plt.plot(np.arange(T) * dt, test_model.compute_rate(ks=k), '-r') plt.ioff() plt.show()
def fit_standard_hawkes_model_sgd(S, K, B, dt, dt_max, init_model=None): """ Fit :param S: :return: """ print("Fitting the data with a standard Hawkes model using SGD") # Make a new model for inference test_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, dt_max=dt_max, B=B) test_model.add_data(S, minibatchsize=256) # Initialize the test model with the init model weights if init_model is not None: test_model.weights = init_model.weights plt.ion() im = plot_network(np.ones((K, K)), test_model.W, vmax=0.5) plt.pause(0.001) # Gradient descent N_steps = 1000 samples = [] lls = [] timestamps = [] learning_rate = 0.01 * np.ones(N_steps) momentum = 0.8 * np.ones(N_steps) prev_velocity = None for itr in range(N_steps): # W,ll,grad = test_model.gradient_descent_step(stepsz=0.001) W, ll, prev_velocity = test_model.sgd_step(prev_velocity, learning_rate[itr], momentum[itr]) samples.append(test_model.copy_sample()) lls.append(ll) timestamps.append(time.clock()) if itr % 1 == 0: print("Iteration ", itr, "\t LL: ", ll) im.set_data(np.ones((K, K)) * test_model.W) plt.pause(0.001) plt.ioff() plt.figure() plt.plot(np.arange(N_steps), lls) plt.xlabel("Iteration") plt.ylabel("Log likelihood") plot_network(np.ones((K, K)), test_model.W) plt.show() return samples, timestamps
def fit_standard_hawkes_model_bfgs_noxv(S, K, dt, dt_max, output_path, W_max=None): """ Fit :param S: :return: """ # Check for existing results if os.path.exists(out_path + ".bfgs.pkl"): print "Existing BFGS results found. Loading from file." with open(output_path + ".bfgs.pkl", 'r') as f: init_model, init_time = cPickle.load(f) else: print "Fitting the data with a standard Hawkes model" # We want the max W ~ -.025 and the mean to be around 0.01 # W ~ Gamma(alpha, beta) => E[W] = alpha/beta, so beta ~100 * alpha alpha = 1.1 beta = alpha * 1.0 / 0.01 # Make a model to initialize the parameters test_basis = IdentityBasis(dt, dt_max, allow_instantaneous=True) init_model = DiscreteTimeStandardHawkesModel( K=K, dt=dt, dt_max=dt_max, alpha=alpha, beta=beta, basis=test_basis, allow_self_connections=False, W_max=W_max) init_model.add_data(S) # Initialize the background rates to their mean init_model.initialize_to_background_rate() start = time.clock() init_model.fit_with_bfgs() init_time = time.clock() - start # Save the model (sans data) with open(output_path + ".bfgs.pkl", 'w') as f: print "Saving BFGS results to ", (output_path + ".bfgs.pkl") cPickle.dump((init_model, init_time), f, protocol=-1) return init_model, init_time
T = S.shape[0] K = true_model.K B = true_model.B dt = true_model.dt dt_max = true_model.dt_max ########################################################### # Initialize with MAP estimation on a standard Hawkes model ########################################################### init_with_map = True if init_with_map: init_len = T print("Initializing with BFGS on first ", init_len, " time bins.") init_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, dt_max=dt_max, B=B, alpha=1.0, beta=1.0) init_model.add_data(S[:init_len, :]) init_model.initialize_to_background_rate() init_model.fit_with_bfgs() else: init_model = None ########################################################### # Create a test weak spike-and-slab model ########################################################### # Copy the network hypers. # Give the test model p, but not c, v, or m
def fit_standard_hawkes_model_bfgs(S, K, B, dt, dt_max, output_path, init_len=10000, xv_len=1000): """ Fit :param S: :return: """ # Check for existing results if os.path.exists(out_path + ".bfgs.pkl"): print("Existing BFGS results found. Loading from file.") with open(output_path + ".bfgs.pkl", 'r') as f: init_model, init_time = pickle.load(f) else: print("Fitting the data with a standard Hawkes model") # betas = np.logspace(-3,-0.8,num=10) betas = np.array([0.01, 0.1, 1.0, 10.0, 20.0]) # betas = np.concatenate(([0], betas)) init_models = [] S_init = S[:init_len, :] xv_ll = np.zeros(len(betas)) S_xv = S[init_len:init_len + xv_len, :] # Make a model to initialize the parameters init_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, B=B, dt_max=dt_max, beta=0.0) init_model.add_data(S_init) # Initialize the background rates to their mean init_model.initialize_to_background_rate() start = time.clock() for i, beta in enumerate(betas): print("Fitting with BFGS on first ", init_len, " time bins, beta = ", beta) init_model.beta = beta init_model.fit_with_bfgs() init_models.append(init_model.copy_sample()) # Compute the heldout likelihood on the xv data xv_ll[i] = init_model.heldout_log_likelihood(S_xv) if not np.isfinite(xv_ll[i]): xv_ll[i] = -np.inf init_time = time.clock() - start # Take the best model print("XV predictive log likelihoods: ") for beta, ll in zip(betas, xv_ll): print("Beta: %.2f\tLL: %.2f" % (beta, ll)) best_ind = np.argmax(xv_ll) print("Best beta: ", betas[best_ind]) init_model = init_models[best_ind] if best_ind == 0 or best_ind == len(betas) - 1: print("WARNING: Best BFGS model was for extreme value of beta. " \ "Consider expanding the beta range.") # Save the model (sans data) with open(output_path + ".bfgs.pkl", 'w') as f: print("Saving BFGS results to ", (output_path + ".bfgs.pkl")) pickle.dump((init_model, init_time), f, protocol=-1) return init_model, init_time
def demo(seed=None): """ Fit a weakly sparse :return: """ if seed is None: seed = np.random.randint(2**32) print "Setting seed to ", seed np.random.seed(seed) ########################################################### # Load some example data. # See data/synthetic/generate.py to create more. ########################################################### data_path = os.path.join("data", "synthetic", "synthetic_K20_C4_T10000.pkl.gz") with gzip.open(data_path, 'r') as f: S, true_model = cPickle.load(f) T = S.shape[0] K = true_model.K B = true_model.B dt = true_model.dt dt_max = true_model.dt_max ########################################################### # Initialize with MAP estimation on a standard Hawkes model ########################################################### init_with_map = True if init_with_map: init_len = T print "Initializing with BFGS on first ", init_len, " time bins." init_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, dt_max=dt_max, B=B, alpha=1.0, beta=1.0) init_model.add_data(S[:init_len, :]) init_model.initialize_to_background_rate() init_model.fit_with_bfgs() else: init_model = None ########################################################### # Create a test weak spike-and-slab model ########################################################### # Copy the network hypers. # Give the test model p, but not c, v, or m network_hypers = true_model.network_hypers.copy() network_hypers['v'] = None test_model = DiscreteTimeNetworkHawkesModelGammaMixture( K=K, dt=dt, dt_max=dt_max, B=B, basis_hypers=true_model.basis_hypers, bkgd_hypers=true_model.bkgd_hypers, impulse_hypers=true_model.impulse_hypers, weight_hypers=true_model.weight_hypers, network_hypers=network_hypers) test_model.add_data(S) # Initialize with the standard model parameters if init_model is not None: test_model.initialize_with_standard_model(init_model) ########################################################### # Fit the test model with Gibbs sampling ########################################################### N_samples = 500 samples = [] lps = [] # plls = [] for itr in xrange(N_samples): lps.append(test_model.log_probability()) # plls.append(test_model.heldout_log_likelihood(S_test, F=F_test)) samples.append(test_model.copy_sample()) print "" print "Gibbs iteration ", itr print "LP: ", lps[-1] test_model.resample_model() ########################################################### # Analyze the samples ########################################################### N_samples = len(samples) A_samples = np.array([s.weight_model.A for s in samples]) W_samples = np.array([s.weight_model.W for s in samples]) g_samples = np.array([s.impulse_model.g for s in samples]) lambda0_samples = np.array([s.bias_model.lambda0 for s in samples]) lps = np.array(lps) offset = N_samples // 2 A_mean = A_samples[offset:, ...].mean(axis=0) W_mean = W_samples[offset:, ...].mean(axis=0) g_mean = g_samples[offset:, ...].mean(axis=0) lambda0_mean = lambda0_samples[offset:, ...].mean(axis=0) plt.figure() plt.plot(np.arange(N_samples), lps, 'k') plt.xlabel("Iteration") plt.ylabel("Log probability") plt.show() # Compute the link prediction accuracy curves auc_init = roc_auc_score(true_model.weight_model.A.ravel(), init_model.W.ravel()) auc_A_mean = roc_auc_score(true_model.weight_model.A.ravel(), A_mean.ravel()) auc_W_mean = roc_auc_score(true_model.weight_model.A.ravel(), W_mean.ravel()) aucs = [] for A in A_samples: aucs.append(roc_auc_score(true_model.weight_model.A.ravel(), A.ravel())) plt.figure() plt.plot(aucs, '-r') plt.plot(auc_A_mean * np.ones_like(aucs), '--r') plt.plot(auc_W_mean * np.ones_like(aucs), '--b') plt.plot(auc_init * np.ones_like(aucs), '--k') plt.xlabel("Iteration") plt.ylabel("Link prediction AUC") plt.show() plt.ioff() plt.show()
def demo(seed=None): """ Create a discrete time Hawkes model and generate from it. :return: """ if seed is None: seed = np.random.randint(2**32) print("Setting seed to ", seed) np.random.seed(seed) ########################################################### # Load some example data. # See data/synthetic/generate.py to create more. ########################################################### data_path = os.path.join("data", "synthetic", "synthetic_K20_C4_T10000.pkl.gz") with gzip.open(data_path, 'r') as f: S, true_model = pickle.load(f) T = S.shape[0] K = true_model.K B = true_model.B dt = true_model.dt dt_max = true_model.dt_max ########################################################### # Initialize with MAP estimation on a standard Hawkes model ########################################################### init_with_map = True if init_with_map: init_len = T print("Initializing with BFGS on first ", init_len, " time bins.") init_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, dt_max=dt_max, B=B, alpha=1.0, beta=1.0) init_model.add_data(S[:init_len, :]) init_model.initialize_to_background_rate() init_model.fit_with_bfgs() else: init_model = None ########################################################### # Create a test spike and slab model ########################################################### # Copy the network hypers. # Give the test model p, but not c, v, or m network_hypers = true_model.network_hypers.copy() network_hypers['c'] = None network_hypers['v'] = None network_hypers['m'] = None test_network = StochasticBlockModel(K=K, **network_hypers) test_model = DiscreteTimeNetworkHawkesModelSpikeAndSlab( K=K, dt=dt, dt_max=dt_max, B=B, basis_hypers=true_model.basis_hypers, bkgd_hypers=true_model.bkgd_hypers, impulse_hypers=true_model.impulse_hypers, weight_hypers=true_model.weight_hypers, network=test_network) test_model.add_data(S) # F_test = test_model.basis.convolve_with_basis(S_test) # Initialize with the standard model parameters if init_model is not None: test_model.initialize_with_standard_model(init_model) # Initialize plots ln, im_net, im_clus = initialize_plots(true_model, test_model, S) ########################################################### # Fit the test model with Gibbs sampling ########################################################### N_samples = 50 samples = [] lps = [] # plls = [] for itr in range(N_samples): lps.append(test_model.log_probability()) # plls.append(test_model.heldout_log_likelihood(S_test, F=F_test)) samples.append(test_model.copy_sample()) print("") print("Gibbs iteration ", itr) print("LP: ", lps[-1]) test_model.resample_model() # Update plot if itr % 1 == 0: update_plots(itr, test_model, S, ln, im_clus, im_net) ########################################################### # Analyze the samples ########################################################### analyze_samples(true_model, init_model, samples, lps)
def demo(seed=None): """ Fit a weakly sparse :return: """ import warnings warnings.warn("This test runs but the parameters need to be tuned. " "Right now, the SVI algorithm seems to walk away from " "the MAP estimate and yield suboptimal results. " "I'm not convinced the variational inference with the " "gamma mixture provides the best estimates of the sparsity.") if seed is None: seed = np.random.randint(2**32) print("Setting seed to ", seed) np.random.seed(seed) ########################################################### # Load some example data. # See data/synthetic/generate.py to create more. ########################################################### data_path = os.path.join("data", "synthetic", "synthetic_K20_C4_T10000.pkl.gz") with gzip.open(data_path, 'r') as f: S, true_model = pickle.load(f) T = S.shape[0] K = true_model.K B = true_model.B dt = true_model.dt dt_max = true_model.dt_max ########################################################### # Initialize with MAP estimation on a standard Hawkes model ########################################################### if init_with_map: init_len = T print("Initializing with BFGS on first ", init_len, " time bins.") init_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, dt_max=dt_max, B=B, alpha=1.0, beta=1.0) init_model.add_data(S[:init_len, :]) init_model.initialize_to_background_rate() init_model.fit_with_bfgs() else: init_model = None ########################################################### # Create a test weak spike-and-slab model ########################################################### # Copy the network hypers. # Give the test model p, but not c, v, or m network_hypers = true_model.network_hypers.copy() network_hypers['C'] = 1 network_hypers['c'] = None network_hypers['v'] = None network_hypers['m'] = None test_network = StochasticBlockModel(K=K, **network_hypers) test_model = DiscreteTimeNetworkHawkesModelGammaMixture(K=K, dt=dt, dt_max=dt_max, B=B, basis_hypers=true_model.basis_hypers, bkgd_hypers=true_model.bkgd_hypers, impulse_hypers=true_model.impulse_hypers, weight_hypers=true_model.weight_hypers, network=test_network) test_model.add_data(S) # F_test = test_model.basis.convolve_with_basis(S_test) # Initialize with the standard model parameters if init_model is not None: test_model.initialize_with_standard_model(init_model) ########################################################### # Fit the test model with stochastic variational inference ########################################################### N_iters = 500 minibatchsize = 1000 delay = 1.0 forgetting_rate = 0.5 stepsize = (np.arange(N_iters) + delay)**(-forgetting_rate) samples = [] for itr in range(N_iters): print("SVI Iter: ", itr, "\tStepsize: ", stepsize[itr]) test_model.sgd_step(minibatchsize=minibatchsize, stepsize=stepsize[itr]) test_model.resample_from_mf() samples.append(test_model.copy_sample()) ########################################################### # Analyze the samples ########################################################### analyze_samples(true_model, init_model, samples)
def demo(seed=None): """ Fit a weakly sparse :return: """ if seed is None: seed = np.random.randint(2**32) print "Setting seed to ", seed np.random.seed(seed) ########################################################### # Load some example data. # See data/synthetic/generate.py to create more. ########################################################### data_path = os.path.join("data", "synthetic", "synthetic_K20_C4_T10000.pkl.gz") with gzip.open(data_path, 'r') as f: S, true_model = cPickle.load(f) T = S.shape[0] K = true_model.K B = true_model.B dt = true_model.dt dt_max = true_model.dt_max ########################################################### # Initialize with MAP estimation on a standard Hawkes model ########################################################### init_with_map = True if init_with_map: init_len = T print "Initializing with BFGS on first ", init_len, " time bins." init_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, dt_max=dt_max, B=B, alpha=1.0, beta=1.0) init_model.add_data(S[:init_len, :]) init_model.initialize_to_background_rate() init_model.fit_with_bfgs() else: init_model = None ########################################################### # Create a test weak spike-and-slab model ########################################################### # Copy the network hypers. # Give the test model p, but not c, v, or m network_hypers = true_model.network_hypers.copy() network_hypers['c'] = None network_hypers['v'] = None network_hypers['m'] = None test_model = DiscreteTimeNetworkHawkesModelGammaMixture( K=K, dt=dt, dt_max=dt_max, B=B, basis_hypers=true_model.basis_hypers, bkgd_hypers=true_model.bkgd_hypers, impulse_hypers=true_model.impulse_hypers, weight_hypers=true_model.weight_hypers, network_hypers=network_hypers) test_model.add_data(S) # F_test = test_model.basis.convolve_with_basis(S_test) # Initialize with the standard model parameters if init_model is not None: test_model.initialize_with_standard_model(init_model) # Initialize plots ln, im_net, im_clus = initialize_plots(true_model, test_model, S) ########################################################### # Fit the test model with stochastic variational inference ########################################################### N_iters = 500 minibatchsize = 500 delay = 1.0 forgetting_rate = 0.5 stepsize = (np.arange(N_iters) + delay)**(-forgetting_rate) samples = [] for itr in xrange(N_iters): print "SVI Iter: ", itr, "\tStepsize: ", stepsize[itr] test_model.sgd_step(minibatchsize=minibatchsize, stepsize=stepsize[itr]) test_model.resample_from_mf() samples.append(test_model.copy_sample()) # Update plot if itr % 1 == 0: update_plots(itr, test_model, S, ln, im_clus, im_net) ########################################################### # Analyze the samples ########################################################### analyze_samples(true_model, init_model, samples)
def fit_standard_hawkes_model_bfgs(S, K, dt, dt_max, output_path, W_max=None): """ Fit :param S: :return: """ # Check for existing results if os.path.exists(out_path + ".bfgs.pkl"): print "Existing BFGS results found. Loading from file." with open(output_path + ".bfgs.pkl", 'r') as f: init_model, init_time = cPickle.load(f) else: print "Fitting the data with a standard Hawkes model" # betas = np.logspace(-1,1.3,num=1) # betas = [ 0.0 ] # We want the max W ~ -.025 and the mean to be around 0.01 # W ~ Gamma(alpha, beta) => E[W] = alpha/beta, so beta ~100 * alpha alpha = 1.1 betas = [alpha * 1.0 / 0.01] init_models = [] xv_len = 10000 init_len = S.shape[0] - 10000 S_init = S[:init_len, :] xv_ll = np.zeros(len(betas)) S_xv = S[init_len:init_len + xv_len, :] # Make a model to initialize the parameters test_basis = IdentityBasis(dt, dt_max, allow_instantaneous=True) init_model = DiscreteTimeStandardHawkesModel( K=K, dt=dt, dt_max=dt_max, alpha=alpha, beta=0.0, basis=test_basis, allow_self_connections=False, W_max=W_max) init_model.add_data(S_init) # Initialize the background rates to their mean init_model.initialize_to_background_rate() start = time.clock() for i, beta in enumerate(betas): print "Fitting with BFGS on first ", init_len, " time bins, ", \ "beta = ", beta, "W_max = ", W_max init_model.beta = beta init_model.fit_with_bfgs() init_models.append(init_model.copy_sample()) # Compute the heldout likelihood on the xv data xv_ll[i] = init_model.heldout_log_likelihood(S_xv) if not np.isfinite(xv_ll[i]): xv_ll[i] = -np.inf init_time = time.clock() - start # Take the best model print "XV predictive log likelihoods: " for beta, ll in zip(betas, xv_ll): print "Beta: %.2f\tLL: %.2f" % (beta, ll) best_ind = np.argmax(xv_ll) print "Best beta: ", betas[best_ind] init_model = init_models[best_ind] if best_ind == 0 or best_ind == len(betas) - 1: print "WARNING: Best BFGS model was for extreme value of beta. " \ "Consider expanding the beta range." # Save the model (sans data) with open(output_path + ".bfgs.pkl", 'w') as f: print "Saving BFGS results to ", (output_path + ".bfgs.pkl") cPickle.dump((init_model, init_time), f, protocol=-1) return init_model, init_time
def demo(seed=None): """ Suppose we have a very long recording such that computing gradients of the log likelihood is quite expensive. Here we explore the use of stochastic gradient descent to fit the standard Hawkes model, which has a convex log likelihood. We first initialize the parameters using BFGS on a manageable subset of the data. Then we use SGD to refine the parameters on the entire dataset. :return: """ raise NotImplementedError("This example needs to be updated.") if seed is None: seed = np.random.randint(2**32) print("Setting seed to ", seed) np.random.seed(seed) C = 1 # Number of clusters in the true data K = 10 # Number of nodes T = 10000 # Number of time bins to simulate dt = 1.0 # Time bin size B = 3 # Number of basis functions # Sample from the network Hawkes model S, R, true_model = sample_from_network_hawkes(C, K, T, dt, B) # Make a model to initialize the parameters init_len = 256 init_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, B=B, beta=1.0) init_model.add_data(S[:init_len, :]) print("Initializing with BFGS on first ", init_len, " time bins.") init_model.fit_with_bfgs() # Make another model for inference test_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, B=B, beta=1.0) # Initialize with the BFGS parameters test_model.weights = init_model.weights # Add the data in minibatches test_model.add_data(S, minibatchsize=256) # Plot the true and inferred firing rate kplt = 0 plt.figure() plt.plot(np.arange(256), R[:256, kplt], '-k', lw=2) plt.ion() ln = plt.plot(np.arange(256), test_model.compute_rate(ks=kplt)[:256], '-r')[0] plt.show() # Gradient descent N_steps = 10000 lls = [] learning_rate = 0.01 * np.ones(N_steps) momentum = 0.8 * np.ones(N_steps) prev_velocity = None for itr in range(N_steps): W, ll, prev_velocity = test_model.sgd_step(prev_velocity, learning_rate[itr], momentum[itr]) lls.append(ll) # Update plot if itr % 5 == 0: ln.set_data(np.arange(256), test_model.compute_rate(ks=kplt)) plt.title("Iteration %d" % itr) plt.pause(0.001) plt.ioff() print("W true: ", true_model.weight_model.A * true_model.weight_model.W) print("lambda0 true: ", true_model.bias_model.lambda0) print("") print("W test: ", test_model.W) print("lambda0 test ", test_model.bias) plt.figure() plt.plot(np.arange(N_steps), lls) plt.xlabel("Iteration") plt.ylabel("Log likelihood") plot_network(np.ones((K, K)), test_model.W) plt.show()
def demo(seed=None): """ Fit a weakly sparse :return: """ import warnings warnings.warn("This test runs but the parameters need to be tuned. " "Right now, the SVI algorithm seems to walk away from " "the MAP estimate and yield suboptimal results. " "I'm not convinced the variational inference with the " "gamma mixture provides the best estimates of the sparsity.") if seed is None: seed = np.random.randint(2**32) print("Setting seed to ", seed) np.random.seed(seed) ########################################################### # Load some example data. # See data/synthetic/generate.py to create more. ########################################################### data_path = os.path.join("data", "synthetic", "synthetic_K20_C4_T10000.pkl.gz") with gzip.open(data_path, 'r') as f: S, true_model = pickle.load(f) T = S.shape[0] K = true_model.K B = true_model.B dt = true_model.dt dt_max = true_model.dt_max ########################################################### # Initialize with MAP estimation on a standard Hawkes model ########################################################### if init_with_map: init_len = T print("Initializing with BFGS on first ", init_len, " time bins.") init_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, dt_max=dt_max, B=B, alpha=1.0, beta=1.0) init_model.add_data(S[:init_len, :]) init_model.initialize_to_background_rate() init_model.fit_with_bfgs() else: init_model = None ########################################################### # Create a test weak spike-and-slab model ########################################################### # Copy the network hypers. # Give the test model p, but not c, v, or m # network_hypers = true_model.network_hypers.copy() # network_hypers['c'] = None # network_hypers['v'] = None # network_hypers['m'] = None # test_network = StochasticBlockModel(K=K, **network_hypers) test_network = StochasticBlockModel(K=K, C=1) test_model = DiscreteTimeNetworkHawkesModelGammaMixture( K=K, dt=dt, dt_max=dt_max, B=B, basis_hypers=true_model.basis_hypers, bkgd_hypers=true_model.bkgd_hypers, impulse_hypers=true_model.impulse_hypers, weight_hypers=true_model.weight_hypers, network=test_network) test_model.add_data(S) # Initialize with the standard model parameters if init_model is not None: test_model.initialize_with_standard_model(init_model) ########################################################### # Fit the test model with variational Bayesian inference ########################################################### # VB coordinate descent N_iters = 100 vlbs = [] samples = [] for itr in range(N_iters): vlbs.append(test_model.meanfield_coordinate_descent_step()) print("VB Iter: ", itr, "\tVLB: ", vlbs[-1]) if itr > 0: if (vlbs[-2] - vlbs[-1]) > 1e-1: print("WARNING: VLB is not increasing!") # Resample from variational distribution and plot test_model.resample_from_mf() samples.append(test_model.copy_sample()) ########################################################### # Analyze the samples ########################################################### N_samples = len(samples) # Compute sample statistics for second half of samples A_samples = np.array([s.weight_model.A for s in samples]) W_samples = np.array([s.weight_model.W for s in samples]) g_samples = np.array([s.impulse_model.g for s in samples]) lambda0_samples = np.array([s.bias_model.lambda0 for s in samples]) vlbs = np.array(vlbs) offset = N_samples // 2 A_mean = A_samples[offset:, ...].mean(axis=0) W_mean = W_samples[offset:, ...].mean(axis=0) g_mean = g_samples[offset:, ...].mean(axis=0) lambda0_mean = lambda0_samples[offset:, ...].mean(axis=0) # Plot the VLBs plt.figure() plt.plot(np.arange(N_samples), vlbs, 'k') plt.xlabel("Iteration") plt.ylabel("VLB") plt.show() # Compute the link prediction accuracy curves auc_init = roc_auc_score(true_model.weight_model.A.ravel(), init_model.W.ravel()) auc_A_mean = roc_auc_score(true_model.weight_model.A.ravel(), A_mean.ravel()) auc_W_mean = roc_auc_score(true_model.weight_model.A.ravel(), W_mean.ravel()) aucs = [] for A in A_samples: aucs.append(roc_auc_score(true_model.weight_model.A.ravel(), A.ravel())) plt.figure() plt.plot(aucs, '-r') plt.plot(auc_A_mean * np.ones_like(aucs), '--r') plt.plot(auc_W_mean * np.ones_like(aucs), '--b') plt.plot(auc_init * np.ones_like(aucs), '--k') plt.xlabel("Iteration") plt.ylabel("Link prediction AUC") plt.show() plt.ioff() plt.show()
def demo(seed=None): """ Create a discrete time Hawkes model and generate from it. :return: """ if seed is None: seed = np.random.randint(2**32) print "Setting seed to ", seed np.random.seed(seed) C = 1 K = 10 T = 1000 dt = 1.0 B = 3 # Create a true model p = 0.8 * np.eye(C) v = 10.0 * np.eye(C) + 20.0 * (1 - np.eye(C)) # m = 0.5 * np.ones(C) c = (0.0 * (np.arange(K) < 10) + 1.0 * (np.arange(K) >= 10)).astype(np.int) true_model = DiscreteTimeNetworkHawkesModelSpikeAndSlab(C=C, K=K, dt=dt, B=B, c=c, p=p, v=v) # Plot the true network plt.ion() plot_network(true_model.weight_model.A, true_model.weight_model.W, vmax=0.5) plt.pause(0.001) # Sample from the true model S, R = true_model.generate(T=T) # Make a new model for inference test_model = DiscreteTimeStandardHawkesModel(K=K, dt=dt, B=B, beta=1.0) test_model.add_data(S) # Plot the true and inferred firing rate kplt = 0 plt.figure() plt.plot(np.arange(T), R[:, kplt], '-k', lw=2) plt.ion() ln = plt.plot(np.arange(T), test_model.compute_rate(ks=kplt), '-r')[0] plt.show() # Gradient descent N_steps = 10000 lls = [] for itr in xrange(N_steps): W, ll, grad = test_model.gradient_descent_step(stepsz=0.001) lls.append(ll) # Update plot if itr % 5 == 0: ln.set_data(np.arange(T), test_model.compute_rate(ks=kplt)) plt.title("Iteration %d" % itr) plt.pause(0.001) plt.ioff() print "W true: ", true_model.weight_model.A * true_model.weight_model.W print "lambda0 true: ", true_model.bias_model.lambda0 print "ll true: ", true_model.log_likelihood() print "" print "W test: ", test_model.W print "lambda0 test ", test_model.bias print "ll test: ", test_model.log_likelihood() plt.figure() plt.plot(np.arange(N_steps), lls) plt.xlabel("Iteration") plt.ylabel("Log likelihood") plot_network(np.ones((K, K)), test_model.W, vmax=0.5) plt.show()