def eval_fun(pop, *args): # errors = [] # for indiv in pop: # # inverse exponential with offset, y = a * exp(b/x) + c # predicted = (indiv[0] * np.exp(indiv[1] / args[0]) + indiv[2]) # errors.append(predicted - args[1]) # evaluate the population with some broadcasting pred = (pop[:, 0][:, np.newaxis] * np.exp(pop[:, 1][:, np.newaxis] / args[0][np.newaxis, :]) + pop[:, 2][:, np.newaxis]) errors = pred - args[1][np.newaxis, :] # sum of squared error # errors = np.asarray(errors) sse = np.sum(errors * errors, 1) # sae = np.sum(np.abs(errors),1) # calculate the weight with a normal kernel weights = np.log(dists.normal(mean=0.0, std=pop[:, 3]).pdf(sse)) # see if return both weights and predicted vals if save_posts: return weights, pred else: return weights
def eval_prop(indiv, subj_id): # get the true pdf for those params mod = dists.normal(indiv[0], np.exp(indiv[1])) pdf = mod.pdf(data[subj_id]['obs']) if np.any(pdf == 0): return -np.inf weight = np.log(pdf).sum() return weight
def eval_prop(indiv, subj_id): # get the true pdf for those params mod = dists.normal(indiv[0],np.exp(indiv[1])) pdf = mod.pdf(data[subj_id]['obs']) if np.any(pdf==0): return -np.inf weight = np.log(pdf).sum() return weight
def eval_prop(indiv, do_true=False): mod = dists.normal(indiv[0], indiv[1]) if do_true: pdf = mod.pdf(data) else: mdat = mod.rvs(nsamps) pdf, xx = kdensity(mdat, xx=data, nbins=2000, kernel="epanechnikov") if np.any(pdf == 0): return -np.inf weight = np.log(pdf).sum() return weight
def mmi_model_Mood_LTA_gamma_wo_RT_p0_beta(subj_input_dir,subj_out_dir,sid): # import some useful libraries import numpy as np # numerical analysis linear algebra import pandas as pd # efficient tables #import matplotlib.pyplot as plt # plotting from scipy import stats from RunDEMC.density import kdensity from RunDEMC import Model, Param, dists, calc_bpic, joint_plot from mmi_mood_LTA_gamma_wo_RT_p0_beta import MMIModel, load_mmi_data from joblib import Parallel, delayed import pickle from pathlib import Path try: import scoop from scoop import futures except ImportError: print("Error loading scoop, reverting to joblib.") scoop = None # ## Load and examine data subj_input_dir=Path(subj_input_dir) subj_out_dir=Path(subj_out_dir) pattern=f'*{sid}*.xlsx' input_file=list(subj_input_dir.glob(pattern)) print(input_file[0]) dat = load_mmi_data(input_file[0]) # In[4]: #dat.at[2, 'Choice']=='Gamble' # In[5]: # find the minimum RT for the param range min_RT = dat.loc[dat.RT>0, 'RT'].min() print('Min RT:', min_RT) # ## Use RunDEMC to fit the model to a participant's data # define model evaluation functions for RunDEMC def eval_mod(params, param_names, bdat=None): # use global dat if none based in if bdat is None: bdat = dat # turn param list into dict mod_params = {x: params[n] for n, x in enumerate(param_names)} # try: # print(mod_params['lambda']) # except: # print("Problems") if mod_params['lambda']<0 or mod_params['lambda']>=1 : return np.log(0), np.log(0) if mod_params['gamma']<0 or mod_params['gamma']>=np.inf : return np.log(0), np.log(0) # if mod_params['beta']<0 or mod_params['beta']>1 : # return np.log(0), np.log(0) # if mod_params['p0']<0 or mod_params['p0']>1 : # return np.log(0), np.log(0) if mod_params['w_LTA']<0 or mod_params['w_LTA']>=np.inf : return np.log(0), np.log(0) if mod_params['w_RPE']<0 or mod_params['w_RPE']>=np.inf : return np.log(0), np.log(0) if mod_params['b']<=-np.inf or mod_params['b']>=np.inf : return np.log(0), np.log(0) if mod_params['s_v']<=0 or mod_params['s_v']>=np.inf : return np.log(0), np.log(0) if mod_params['c']<0 or mod_params['c']>=np.inf : return np.log(0), np.log(0) ## calculate the log_likes and mood_log_likes mod_res = MMIModel(params=mod_params, ignore_non_resp=True).proc_trials(bdat.copy()) ll = mod_res.log_like.sum() mood_ll = mod_res.mood_log_like.sum() return ll,mood_ll # this is the required def for RunDEMC def eval_fun(pop, *args): bdat = args[0] pnames = args[1] if scoop and scoop.IS_RUNNING: res_tups = list(futures.map(eval_mod, [indiv for indiv in pop], [pnames]*len(pop), [bdat]*len(pop))) else: res_tups= Parallel(n_jobs=-1)(delayed(eval_mod)(indiv,pnames, bdat) for indiv in pop) likes = np.array([rt[0] for rt in res_tups]) mood_likes = np.array([rt[1] for rt in res_tups]) return likes, mood_likes def get_best_fit(m, burnin=250, verbose=True): best_ind = m.weights[burnin:].argmax() if verbose: print("Weight:", m.weights[burnin:].ravel()[best_ind]) indiv = [m.particles[burnin:,:,i].ravel()[best_ind] for i in range(m.particles.shape[-1])] pp = {} for p,v in zip(m.param_names,indiv): pp[p] = v if verbose: print('"%s": %f,'%(p,v)) return pp # ### Base model # In[20]: # set up model params params = [Param(name='gamma', display_name=r'$\gamma$', prior=dists.gamma(1.5, 0.5), ), Param(name='c', display_name=r'$c$', prior=dists.gamma(1.5, 0.5), ), # Param(name='beta', # display_name=r'$\beta$', # prior=dists.normal(0, 1.4), # transform=dists.invlogit # ), # Param(name='w', # display_name=r'$w$', # prior=dists.normal(0, 1.4), # transform=dists.invlogit # ), # Param(name='a', # display_name=r'$a$', # prior=dists.gamma(2.0, 0.5), # ), # Param(name='t0', # display_name=r'$t_0$', # prior=dists.normal(0, 1.4), # transform=lambda x: dists.invlogit(x)*min_RT, # ), # Param(name='p0', # display_name=r'$p_0$', # prior=dists.normal(0, 1.4), # transform=dists.invlogit # ), Param(name='lambda', display_name=r'$lambda', prior=dists.normal(0, 1.4), transform=dists.invlogit ), # Param(name='lambda', # display_name=r'$lambda', # prior=dists.beta(0.5, 0.5) # ), Param(name='w_LTA', display_name=r'w_{LTA}', prior=dists.normal(0, 1), transform=np.exp, inv_transform=np.log), # Param(name='w_EG', # display_name=r'w_{EG}', # prior=dists.normal(0, 1), # transform=np.exp, # inv_transform=np.log), Param(name='w_RPE', display_name=r'w_{RPE}', prior=dists.normal(0, 1), transform=np.exp, inv_transform=np.log), Param(name='b', display_name=r'b', prior=dists.normal(0, 3)), Param(name='s_v', display_name=r's_v', prior=dists.exp(3)) ] # grab the param names pnames = [p.name for p in params] m = Model('mmi', params=params, like_fun=eval_fun, like_args=(dat, pnames), init_multiplier=3, # num_chains=gsize, verbose=True) # do some burnin times = m.sample(150, burnin=True) # now map the posterior times = m.sample(650, burnin=False) # show the chains are mixing and converging #plt.plot(m.weights[30:], alpha=.3); pickle_name=subj_out_dir / f'mWgt_{sid}.pickle' print(pickle_name) pickle_out = open(pickle_name,"wb") pickle.dump(m.weights, pickle_out) pickle_out.close() #print("Best fitting params:") #pp = get_best_fit(m, burnin=250, verbose=True) print("Best fitting params:") pp = get_best_fit(m, burnin=250, verbose=True) pickle_name=subj_out_dir / f'mBFprm_{sid}.pickle' print(pickle_name) pickle_out = open(pickle_name,"wb") pickle.dump(pp, pickle_out) pickle_out.close() # In[42]: #### BPIC calculations burnin=250 log_like_prior = m.weights - m.log_likes #print(log_like_prior) weight_mood = m.posts + log_like_prior #m.posts is log_like_Mood #print(weight_mood) print("Mood_BPIC :",calc_bpic(weight_mood[burnin:])['bpic']) Mood_BPIC=calc_bpic(weight_mood[burnin:])['bpic'] pickle_name=subj_out_dir / f'Mood_BPIC_{sid}.pickle' print(pickle_name) pickle_out = open(pickle_name,"wb") pickle.dump(Mood_BPIC, pickle_out) pickle_out.close() log_like_RT = m.log_likes - m.posts weight_RT = log_like_RT + log_like_prior print("RT_BPIC :",calc_bpic(weight_RT[burnin:])['bpic']) RT_BPIC=calc_bpic(weight_RT[burnin:])['bpic'] pickle_name=subj_out_dir / f'RT_BPIC_{sid}.pickle' print(pickle_name) pickle_out = open(pickle_name,"wb") pickle.dump(RT_BPIC, pickle_out) pickle_out.close() print(calc_bpic(m.weights[burnin:])['bpic']) mBPIC=calc_bpic(m.weights[burnin:])['bpic'] pickle_name=subj_out_dir / f'Total_BPIC_{sid}.pickle' print(pickle_name) pickle_out = open(pickle_name,"wb") pickle.dump(mBPIC, pickle_out) pickle_out.close() # In[46]: # plot the param distributions (note, we did not get full posteriors, yet) # plt.figure(figsize=(12,10)) # burnin=30 # for i in range(len(m.param_names)): # plt.subplot(3,4,i+1) # plt.hist(m.particles[burnin:, :, i].flatten(), bins='auto', alpha=.5, density=True); # plt.title(m.param_names[i]) # In[ ]: pickle_name=subj_out_dir / f'mParticles_{sid}.pickle' print(pickle_name) pickle_out = open(pickle_name,"wb") pickle.dump(m.particles, pickle_out) pickle_out.close() pickle_name=subj_out_dir / f'mParams_{sid}.pickle' print(pickle_name) pickle_out = open(pickle_name,"wb") pickle.dump(m.param_names, pickle_out) pickle_out.close()
if left_coherence > right_coherence: data.at[i, 'coherence'] = str(right_coherence) + ', ' + str( left_coherence) elif right_coherence >= left_coherence: data.at[i, 'coherence'] = str(left_coherence) + ', ' + str( right_coherence) # loop through each participant for s in data.subj.unique(): subj_ind = data['subj'] == s min_rt = data[subj_ind]['rt'].min() # set up the params params = [ Param(name='a', prior=dists.trunc_normal(5.0, 20.0, lower=0.0, upper=50.0)), Param(name='b', prior=dists.normal(0.0, 5.0)), Param(name='c', prior=dists.trunc_normal(5.0, 10.0, lower=0.0, upper=30.0)), Param(name='kappa', prior=dists.normal(0.0, 1.4), transform=dists.invlogit), Param(name='beta', prior=dists.normal(0.0, 1.4), transform=dists.invlogit), Param(name='alpha', prior=dists.trunc_normal(2.5, 10.0, lower=0.0, upper=30.0)), Param(name='t0', prior=dists.uniform(0., min_rt)) ] pnames = [p.name for p in params] # instantiate model object m = Model('urdm_lca',
for c in ['+', '=', '~']: ind = (dat.condition == c) & (dat.rt < max_rt) d = { 'rt': np.log(np.array(dat[ind].rt) + log_shift), 'resp': np.array(~dat[ind]['correct'], dtype=np.int) } ddat[c] = d # store minimum RT min_rt = dat[(dat['rt'] >= 0.)]['rt'].min() # define priors params = [ Param(name='r', display_name=r'$r$', prior=dists.normal(-2.0, 1.0), transform=lambda x: dists.invlogit(x) * (20. - 0.) + (0.)), Param(name='p', display_name=r'$p$', prior=dists.normal(-0.8, 1.2), transform=lambda x: dists.invlogit(x) * (20. - 0.) + (0.)), Param(name='sd0', display_name=r'$\sigma_0$', prior=dists.normal(-1.0, 1.2), transform=lambda x: dists.invlogit(x) * (30. - 0.1) + (0.1)), Param(name='K', display_name=r'$K$', prior=dists.normal(0.0, 1.4), transform=dists.invlogit), Param(name='L', display_name=r'$L$',
import numpy as np from RunDEMC import RunDEMC, Param, dists from RunDEMC import DE from RunDEMC import joint_plot, violin_plot from RunDEMC.density import kdensity from joblib import Parallel, delayed import pylab as pl n_jobs = 2 nsamps = 20000 ndat = 1000 xx = np.linspace(-10, 10, nsamps) mu = 1.0 sd = 2.0 dmod = dists.normal(mu, sd) data = dmod.rvs(ndat) def eval_prop(indiv, do_true=False): mod = dists.normal(indiv[0], indiv[1]) if do_true: pdf = mod.pdf(data) else: mdat = mod.rvs(nsamps) pdf, xx = kdensity(mdat, xx=data, nbins=2000, kernel="epanechnikov") if np.any(pdf == 0): return -np.inf weight = np.log(pdf).sum() return weight
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## from RunDEMC import RunDEMC, Param, dists from RunDEMC import DE from RunDEMC.hierarchy import Hierarchy, HyperParam import numpy as np from joblib import Parallel, delayed # generate the data n_jobs = 1 nsubj = 4 nobs = 1000 mu = 1.0 sigma = .5 dmod_mean = dists.normal(mu, sigma) alpha = 4 beta = 10 dmod_std = dists.invgamma(alpha, beta) data = {} for s in range(nsubj): # draw a mean and std from hypers smean = dmod_mean.rvs() sstd = np.sqrt(dmod_std.rvs()) dmod = dists.normal(smean, sstd) data[s] = {'mean': smean, 'std': sstd, 'obs': dmod.rvs(nobs)} # set up model evaluation
pdf will randomly pick from hyperparam chains and provide the pdf from the supplied distribution. log_prior: convenience method for looping over params for a proposal and calling each param's pdf to get the log_like for that param. """ from RunDEMC import Model, HyperPrior, Hierarchy, Param, dists # set up the hyper priors h_alpha = HyperPrior(name='h_alpha', dist=dists.normal, params=[ Param(name='mu', prior=dists.normal(1, .5)), Param(name='sigma', prior=dists.invgamma(4, 10)) ]) h_beta = HyperPrior(name='h_beta', dist=dists.normal, params=[ Param(name='mu', prior=dists.normal(1, .5)), Param(name='sigma', prior=dists.invgamma(4, 10)) ]) # set up lower level (i.e., subject) def subj_like(pop, *args): return np.log(dists.beta(pop[:, 0], pop[:, 1]).pdf(args[0]))
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## from RunDEMC import RunDEMC, Param, dists from RunDEMC import DE from RunDEMC.hierarchy import Hierarchy,HyperParam import numpy as np from joblib import Parallel, delayed # generate the data n_jobs = 1 nsubj = 4 nobs = 1000 mu=1.0 sigma=.5 dmod_mean = dists.normal(mu,sigma) alpha=4 beta=10 dmod_std = dists.invgamma(alpha,beta) data = {} for s in range(nsubj): # draw a mean and std from hypers smean = dmod_mean.rvs() sstd = np.sqrt(dmod_std.rvs()) dmod = dists.normal(smean,sstd) data[s] = {'mean': smean, 'std': sstd, 'obs': dmod.rvs(nobs)} # set up model evaluation def eval_prop(indiv, subj_id):
pdf will randomly pick from hyperparam chains and provide the pdf from the supplied distribution. log_prior: convenience method for looping over params for a proposal and calling each param's pdf to get the log_like for that param. """ from RunDEMC import Model, HyperPrior, Hierarchy, Param, dists # set up the hyper priors h_alpha = HyperPrior(name='h_alpha', dist=dists.normal, params=[Param(name='mu', prior=dists.normal(1,.5)), Param(name='sigma', prior=dists.invgamma(4,10))]) h_beta = HyperPrior(name='h_beta', dist=dists.normal, params=[Param(name='mu', prior=dists.normal(1,.5)), Param(name='sigma', prior=dists.invgamma(4,10))]) # set up lower level (i.e., subject) def subj_like(pop, *args): return np.log(dists.beta(pop[:,0],pop[:,1]).pdf(args[0])) submods = [Model(name='subj_%s'%s, params=[Param(name='alpha', prior=h_alpha), Param(name='beta', prior=h_beta)], like_fun=subj_like,
# get name of output file out_file = 'cab_' + s[:-4] + '.tgz' # define model parameters and priors params = [ Param(name='lambda', display_name=r'$\lambda$', prior=dists.trunc_normal(.5, 2, 0, 5)), # Param(name='alpha', display_name=r'$\alpha$', prior=dists.trunc_normal(1., 4, 0, 10)), Param(name='omega', display_name=r'$\omega$', prior=dists.normal(mean=0, std=1.4), transform=dists.invlogit), Param( name='delta', display_name=r'$\delta$', prior=dists.trunc_normal(1., 10, 0, 20.0), ), Param(name='sigma', display_name=r'$\sigma$', prior=dists.normal(mean=0, std=1.4), transform=dists.invlogit), Param( name='nu', display_name=r'$\nu$', prior=dists.trunc_normal(mean=2., std=10., lower=0., upper=10.), ),
'xdata': xdata, 'ydata': ydata, 'alpha': alpha, 'beta': beta, 'sigma': sigma } # generate data nsubj = 5 alpha_sd = 10 # only across-subject variability is intercept data = [] for i in range(nsubj): alpha = dists.normal(theta_true[0], alpha_sd).rvs() data.append(gen_subj_data(alpha)) ################## # Set up the Model ################## # define the evaluation function def subj_like(pop, *args): alpha, beta, sigma = (pop[:, 0], pop[:, 1], pop[:, 2]) xdata = args[0]['xdata'] ydata = args[0]['ydata'] y_model = (alpha + beta * xdata[:, np.newaxis]).T