T = 201 data = 100. * np.diff(np.log(raw_data[:(T + 1)])) my_ssm = ssms.StochVol(mu=2 * np.log(.5992), sigma=0.178, rho=0.9702) # FK models models = OrderedDict() models['bootstrap'] = ssms.Bootstrap(ssm=my_ssm, data=data) models['guided'] = ssms.GuidedPF(ssm=my_ssm, data=data) models['apf'] = ssms.AuxiliaryPF(ssm=my_ssm, data=data) # Get results results = particles.multiSMC(fk=models, N=10**3, nruns=250, moments=True) # Golden standard bigN = 10**5 bigpf = particles.SMC(fk=models['bootstrap'], N=bigN, qmc=True, moments=True) print('One SQMC run with N=%i' % bigN) bigpf.run() # PLOTS # ===== plt.style.use('ggplot') savefig = False # True if you want to save figs as pdfs # box-plots for log-likelihood evaluation plt.figure() sb.boxplot(x=[r['fk'] for r in results], y=[r['output'].logLt for r in results] ) plt.ylabel('log-likelihood estimate')
random.shuffle(data) model = LogisticRegression(data=data, prior=prior) for waste in [True, False]: if waste: N, lc = M, N0 // M res = {'M': M, 'P': lc} else: N, lc = N0 // K, K + 1 res = {'N': N, 'K': K} if alg_type == 'ibis': fk = ssps.IBIS(model=model, len_chain=lc, wastefree=waste) else: fk = ssps.AdaptiveTempering(model=model, len_chain=lc, wastefree=waste) pf = particles.SMC(fk=fk, N=N, collect=[Moments], verbose=False) print('%s, waste:%i, nsteps=%i, run %i' % (alg_type, waste, nsteps, i)) pf.run() print('CPU time (min): %.2f' % (pf.cpu_time / 60)) print('loglik: %f' % pf.logLt) res.update({ 'type': alg_type, 'out': pf.summaries, 'waste': waste, 'cpu': pf.cpu_time }) results.append(res) # plots #######
# Choice of theta_0 and range of theta's mu0 = -1. rho0 = 0.9 sigma0 = 0.3 theta0 = [mu0, rho0, sigma0] sigmas = sigma0 + np.linspace(-.199, .2, 401) thetas = [[mu0, rho0, sig] for sig in sigmas] # range of T's Ts = [10, 100, 1000] colors = {10: 'lightgray', 100: 'gray', 1000: 'black'} plt.style.use('ggplot') plt.figure() for T in Ts: print('FFBS for T=%i' % T) alg = particles.SMC(fk=fkmod(theta0, T), N=100, store_history=True) alg.run() trajs = alg.hist.backward_sampling(M=100) ll0 = log_joint_density(theta0, trajs) ess_ls = [] for theta in thetas: ll = log_joint_density(theta, trajs) ess = rs.essl(ll - ll0) ess_ls.append(ess) plt.plot(sigmas, ess_ls, label='T=%i' % T, color=colors[T]) plt.xlabel('sigma') plt.ylabel('ESS') plt.legend(loc=2) savefigs = False # change this if you want to save the plot as a PDF
config.write(f) print(f"Data saved in folder CIR{name}.") #%% Load data from saved npz file name = "20210204-225727" # Modify the name manually loader = np.load(file=f"./Records/CIR{name}/data.npz") real_x, real_y = loader.get("real_x"), loader.get("real_y") fk_PF = ssm.GuidedPF(ssm=CIR(), data=real_y) #%% Particle filter SMC_10K alg_PF = particles.SMC( fk=fk_PF, N=10000, ESSrmin=1, resampling="multinomial", store_history=True, compute_moments=False, online_smoothing=None, verbose=False, ) # Run the SMC_10K for one time. state_est(alg_PF, real_x, name="(CIR, SMC_10K)", xmin=-2, xmax=10) plt.savefig(f"./Records/CIR{name}/SMC_10K_filtering_once.png") plt.show() # Display the "residual" plot of the filtering result. evaluate.resi_plot(alg_PF, real_x, "SMC_10K") plt.savefig(f"./Records/CIR{name}/SMC_10K_residuals_once.png") #%% SMC_10K 50 repeats """ Repeated simulation is conducted in `CIR_filter_multiprocessing.py` in a parallelling way, and the corresponding results are saved in a npz file.
def smoothing_worker(method=None, N=100, fk=None, fk_info=None, add_func=None, log_gamma=None): """Generic worker for off-line smoothing algorithms. This worker may be used in conjunction with utils.multiplexer in order to run in parallel off-line smoothing algorithms. Parameters ---------- method: string ['FFBS_ON', 'FFBS_ON2', 'FFBS_QMC', 'two-filter_ON', 'two-filter_ON_prop', 'two-filter_ON2'] N: int number of particles fk: Feynman-Kac object The Feynman-Kac model for the forward filter fk_info: Feynman-Kac object (default=None) the Feynman-Kac model for the information filter; if None, set to the same Feynman-Kac model as fk, with data in reverse add_func: function, with signature (t, x, xf) additive function, at time t, for particles x=x_t and xf=x_{t+1} log_gamma: function log of function gamma (see book) Returns ------- a dict with fields: est: a ndarray of length T cpu_time """ T = fk.T if fk_info is None: fk_info = fk.__class__(ssm=fk.ssm, data=fk.data[::-1]) est = np.zeros(T - 1) if method=='FFBS_QMC': pf = particles.SQMC(fk=fk, N=N, store_history=True) else: pf = particles.SMC(fk=fk, N=N, store_history=True) tic = time.clock() pf.run() if method in ['FFBS_ON', 'FFBS_ON2', 'FFBS_QMC']: if method.startswith('FFBS_ON'): z = pf.hist.backward_sampling(N, linear_cost=(method == 'FFBS_ON')) else: z = pf.hist.backward_sampling_qmc(N) for t in range(T - 1): est[t] = np.mean(add_func(t, z[t], z[t + 1])) elif method in ['two-filter_ON2', 'two-filter_ON', 'two-filter_ON_prop']: infopf = particles.SMC(fk=fk_info, N=N, store_history=True) infopf.run() for t in range(T - 1): psi = lambda x, xf: add_func(t, x, xf) if method == 'two-filter_ON2': est[t] = pf.hist.twofilter_smoothing(t, infopf, psi, log_gamma) else: ti = T - 2 - t # t+1 for info filter if method == 'two-filter_ON_prop': modif_fwd = stats.norm.logpdf(pf.hist.X[t], loc=np.mean(infopf.hist.X[ti + 1]), scale=np.std(infopf.hist.X[ti + 1])) modif_info = stats.norm.logpdf(infopf.hist.X[ti], loc=np.mean(pf.hist.X[t + 1]), scale=np.std(pf.hist.X[t + 1])) else: modif_fwd, modif_info = None, None est[t] = pf.hist.twofilter_smoothing(t, infopf, psi, log_gamma, linear_cost=True, modif_forward=modif_fwd, modif_info=modif_info) else: print('no such method?') cpu_time = time.clock() - tic print(method + ' took %.2f s for N=%i' % (cpu_time, N)) return {'est': est, 'cpu': cpu_time}
import particles from particles import distributions as dists from particles import state_space_models # set up models, simulate and save data T = 100 mu0 = 0. phi0 = 0.9 sigma0 = .5 # true parameters ssm = state_space_models.DiscreteCox(mu=mu0, phi=phi0, sigma=sigma0) true_states, data = ssm.simulate(T) fkmod = state_space_models.Bootstrap(ssm=ssm, data=data) # run particle filter, compute trajectories N = 100 pf = particles.SMC(fk=fkmod, N=N, store_history=True) pf.run() pf.hist.compute_trajectories() # PLOT # ==== # sb.set_palette("dark") plt.style.use('ggplot') savefigs = False plt.figure() plt.xlabel('t') for n in range(N): plt.plot(pf.hist.B[:, n], 'k') if savefigs: plt.savefig('genealogy.pdf')
x): # Distribution of Y_t given X_t=x (and possibly X_{t-1}=xp) return dists.Normal(loc=0., scale=np.exp(x)) my_model = StochVol(mu=-1., rho=.9, sigma=.1) # actual model true_states, data = my_model.simulate( 100) # we simulate from the model 100 data points plt.style.use('ggplot') plt.figure() plt.plot(data) fk_model = ssm.Bootstrap(ssm=my_model, data=data) pf = particles.SMC(fk=fk_model, N=100, resampling='stratified', moments=True, store_history=True) pf.run() plt.figure() plt.plot([yt**2 for yt in data], label='data-squared') plt.plot([m['mean'] for m in pf.summaries.moments], label='filtered volatility') plt.legend() #results=particles.multiSMC(fk=fk_model,N=100,nruns=30,qmc={'SMC':False,'SQMC':True}) #results = particles.multiSMC(fk=fk_model, N=100, nruns=30, qmc={'SMC':False, 'SQMC':True}) #plt.figure() #sb.boxplot(x=[r['output'].logLt for r in results], y=[r['qmc'] for r in results]) smooth_trajectories = pf.hist.backward_sampling(10)
# N and values of M set above according to dataset ESSrmin = 0.5 nruns = 16 results = [] # runs print('Dataset: %s' % dataset_name) for M in Ms: for i in range(nruns): # need to shuffle the data for IBIS random.shuffle(data) model = LogisticRegression(data=data, prior=prior) for alg_type in ['tempering', 'ibis']: if alg_type=='ibis': fk = smc_samplers.IBIS(model, mh_options={'nsteps': M}) pf = particles.SMC(N=N, fk=fk, ESSrmin=ESSrmin, moments=True, verbose=False) else: fk = smc_samplers.AdaptiveTempering(model, ESSrmin=ESSrmin, mh_options={'nsteps': M}) pf = particles.SMC(N=N, fk=fk, ESSrmin=1., moments=True, verbose=True) # must resample at every time step when doing adaptive # tempering print('%s, M=%i, run %i' % (alg_type, M, i)) pf.run() print('CPU time (min): %.2f' % (pf.cpu_time / 60)) print('loglik: %f' % pf.logLt) res = {'M': M, 'type': alg_type, 'out': pf.summaries, 'cpu': pf.cpu_time} if alg_type=='ibis': n_eval = N * (T + M * sum([t for t in range(T) if
'sigma': dists.Gamma(a=2., b=2.), 'rho': dists.Beta(a=9., b=1.) } prior = dists.StructDist(dict_prior) mu0, sigma0, rho0 = -1.02, 0.178, 0.9702 theta0 = np.array([(mu0, rho0, sigma0)], dtype=[('mu', float), ('rho', float), ('sigma', float)]) ssm_cls = state_space_models.StochVol ssm = ssm_cls(mu=mu0, sigma=sigma0, rho=rho0) # (QMC-)FFBS as a reference N = 3000 tic = time.time() pf = particles.SMC(fk=state_space_models.Bootstrap(ssm=ssm, data=data), N=N, qmc=True, store_history=True) pf.run() smth_traj = pf.hist.backward_sampling_qmc(M=N) cpu_time_fbbs = time.time() - tic print('FFBS-QMC: run completed, took %f min' % (cpu_time_fbbs / 60.)) def reject_sv(m, s, y): """ Sample from N(m, s^2) times SV likelihood using rejection. SV likelihood (in x) corresponds to y ~ N(0, exp(x)). """ mp = m + 0.5 * s**2 * (-1. + y**2 * np.exp(-m)) ntries = 0 while True:
data=data, prior=my_prior, Nx=200, niter=1000) pg.run() # may take several seconds... plt.plot(pg.chain.theta['mu']) plt.xlabel('iter') plt.ylabel('mu') plt.figure() plt.hist(pg.chain.theta['mu'][20:], 50) plt.xlabel('mu') import particles from particles import smc_samplers as ssp fk_smc2 = ssp.SMC2(ssm_cls=StochVol, data=data, prior=my_prior, init_Nx=50, ar_to_increase_Nx=0.1) alg_smc2 = particles.SMC(fk=fk_smc2, N=500) alg_smc2.run() plt.figure() plt.scatter(alg_smc2.X.theta['mu'], alg_smc2.X.theta['rho']) plt.xlabel('mu') plt.ylabel('rho') plt.show()
T = 201 data = dts.GBP_vs_USD_9798().data[:T] my_ssm = ssms.StochVol(mu=2 * np.log(.5992), sigma=0.178, rho=0.9702) # FK models models = OrderedDict() models['bootstrap'] = ssms.Bootstrap(ssm=my_ssm, data=data) models['guided'] = ssms.GuidedPF(ssm=my_ssm, data=data) models['apf'] = ssms.AuxiliaryPF(ssm=my_ssm, data=data) # Get results results = particles.multiSMC(fk=models, N=10**3, nruns=250, collect=[Moments]) # Golden standard bigN = 10**5 bigpf = particles.SMC(fk=models['bootstrap'], N=bigN, qmc=True, collect=[Moments]) print('One SQMC run with N=%i' % bigN) bigpf.run() # PLOTS # ===== plt.style.use('ggplot') savefigs = True # False if you don't want to save plots as pdfs # box-plots for log-likelihood evaluation plt.figure() sb.boxplot(x=[r['fk'] for r in results], y=[r['output'].logLt for r in results] ) plt.ylabel('log-likelihood estimate')
'sigma': dists.Gamma(a=2., b=2.), 'rho': dists.Beta(a=9., b=1.) } prior = dists.StructDist(dict_prior) mu0, sigma0, rho0 = -1.02, 0.178, 0.9702 theta0 = np.array([(mu0, rho0, sigma0)], dtype=[('mu', float), ('rho', float), ('sigma', float)]) ssm_cls = state_space_models.StochVol ssm = ssm_cls(mu=mu0, sigma=sigma0, rho=rho0) # (QMC-)FFBS as a reference N = 3000 tic = time.time() fk = state_space_models.Bootstrap(ssm=ssm, data=data) pf = particles.SMC(fk=fk, N=N, qmc=True, store_history=True) pf.run() smth_traj = pf.hist.backward_sampling_qmc(M=N) cpu_time_fbbs = time.time() - tic print('FFBS-QMC: run completed, took %f min' % (cpu_time_fbbs / 60.)) def reject_sv(m, s, y): """ Sample from N(m, s^2) times SV likelihood using rejection. SV likelihood (in x) corresponds to y ~ N(0, exp(x)). """ mp = m + 0.5 * s**2 * (-1. + y**2 * np.exp(-m)) ntries = 0 while True: ntries += 1