def fit_model_one_accumulator(df, model_settings, subj_idx): # sample: sample = Sample.from_pandas_dataframe(df=df, rt_column_name='rt', correct_column_name='response') # make model model = make_model_one_accumulator(sample=sample, model_settings=model_settings) # return model # fit: # model = fit_adjust_model(sample=sample, model=model, lossfunction=LossBIC, fitparams={'maxiter':5000}) # model = fit_adjust_model(sample=sample, model=model, lossfunction=LossRobustBIC) model = fit_adjust_model(sample=sample, model=model, lossfunction=LossRobustBICGonogo) # get params: # param_names = [component.required_parameters for component in model.dependencies] # param_names = [item for sublist in param_names for item in sublist] param_names = model.get_model_parameter_names() params = pd.DataFrame(np.atleast_2d( [p.real for p in model.get_model_parameters()]), columns=param_names) params['bic'] = model.fitresult.value() params['subj_idx'] = subj_idx return params
def fit_single_ddm(self, subject, color): """ Fit single subject ddm """ print(f'Fitting {subject}, {color} noise') data = self.data # Load Data color_df = data.loc[(data['noise_color'] == color) & (data['ID'] == subject), ['correct', 'rt', 'coherence']] color_sample = Sample.from_pandas_dataframe( color_df, rt_column_name="rt", correct_column_name="correct") # Set up and fit ddm model color_model = self.setup_model() fit_adjust_model(sample=color_sample, model=color_model, verbose=False) fit = { 'subject': subject, 'drift': float(color_model.get_model_parameters()[0]), 'bound': float(color_model.get_model_parameters()[1]), 'nondectime': float(color_model.get_model_parameters()[2]), 'fit': color_model.fitresult.value(), 'loss': color_model.fitresult.loss } return fit
def DDM_FIT(RT, ANSWER): df = [] # RT is scalles to seconds, the function takes seconds df = pd.DataFrame({'RT': RT / 1000, 'correct': ANSWER}) df.head() sample = Sample.from_pandas_dataframe(df, rt_column_name="RT", correct_column_name="correct") model = Model( name='Model', drift=DriftConstant(drift=Fittable(minval=6, maxval=25)), noise=NoiseConstant( noise=1.5), #(noise=Fittable(minval=0.5, maxval=2.5)), bound=BoundConstant(B=2.5), overlay=OverlayChain(overlays=[ OverlayNonDecision(nondectime=Fittable(minval=0, maxval=.8)), OverlayPoissonMixture(pmixturecoef=.02, rate=1) ]), dx=.001, dt=.01, T_dur=2) # Fitting this will also be fast because PyDDM can automatically # determine that DriftCoherence will allow an analytical solution. fit_model = fit_adjust_model(sample=sample, model=model, fitting_method="differential_evolution", lossfunction=LossRobustBIC, verbose=False) param = fit_model.get_model_parameters() Drift = np.asarray(param[0]) Delay = np.asarray(param[1]) return Drift, Delay
# They are applied sequentially in order. OverlayNonDecision # implements a non-decision time by shifting the # resulting distribution of response times by # `nondectime` seconds. overlay=OverlayChain(overlays=[ OverlayNonDecision(nondectime=Fittable(minval=0, maxval=.4)), OverlayPoissonMixture(pmixturecoef=.02, rate=1) ]), dx=.001, dt=.01, T_dur=2) # Fitting this will also be fast because PyDDM can automatically # determine that DriftCoherence will allow an analytical solution. fit_model_rs = fit_adjust_model(sample=roitman_sample, model=model_rs, verbose=False) display_model(fit_model_rs) fit_model_rs.parameters() # Plot the model fit to the PDFs and save the file. import ddm.plot import matplotlib.pyplot as plt ddm.plot.plot_fit_diagnostics(model=fit_model_rs, sample=roitman_sample) plt.savefig("roitman-fit.png") plt.show() # To get an intuition for how parameters affect the fit, play with the # parameters and task conditions in a GUI. ddm.plot.model_gui(model=fit_model_rs, sample=roitman_sample)
samp = sol.resample(1000) # Fit a model identical to the one described above on the newly # generated data so show that parameters can be recovered. from ddm import Fittable, Fitted from ddm.models import LossRobustBIC from ddm.functions import fit_adjust_model model_fit = Model(name='Simple model (fitted)', drift=DriftConstant(drift=Fittable(minval=0, maxval=4)), noise=NoiseConstant(noise=Fittable(minval=.5, maxval=4)), bound=BoundConstant(B=1.1), overlay=OverlayNonDecision(nondectime=Fittable(minval=0, maxval=1)), dx=.001, dt=.01, T_dur=2) fit_adjust_model(samp, model_fit, fitting_method="differential_evolution", lossfunction=LossRobustBIC, verbose=False) display_model(model_fit) model_fit.parameters() # Plot the model fit to the PDFs and save the file. import ddm.plot import matplotlib.pyplot as plt ddm.plot.plot_fit_diagnostics(model=model_fit, sample=samp) plt.savefig("simple-fit.png") plt.show() print(sol.prob_correct()) print(sol.pdf_err())
noise=NoiseConstant(noise=1), bound=BoundConstant(B=Fittable(minval=.1, maxval=1.5)), # Since we can only have one overlay, we use # OverlayChain to string together multiple overlays. # They are applied sequentially in order. OverlayNonDecision # implements a non-decision time by shifting the # resulting distribution of response times by # `nondectime` seconds. overlay=OverlayChain(overlays=[OverlayNonDecision(nondectime=Fittable(minval=0, maxval=.4)), OverlayPoissonMixture(pmixturecoef=.02, rate=1)]), dx=.001, dt=.01, T_dur=2) # Fitting this will also be fast because PyDDM can automatically # determine that DriftCoherence will allow an analytical solution. fit_model_rs = fit_adjust_model(sample=roitman_sample, model=model_rs) display_model(fit_model_rs) # Plot the model fit to the PDFs and save the file. import ddm.plot import matplotlib.pyplot as plt ddm.plot.plot_fit_diagnostics(model=fit_model_rs, sample=roitman_sample) plt.savefig("roitman-fit.png") plt.show() # To get an intuition for how parameters affect the fit, play with the # parameters and task conditions in a GUI. ddm.plot.model_gui(model=fit_model_rs, sample=roitman_sample)
# generated data so show that parameters can be recovered. from ddm import Fittable from ddm.models import LossBIC from ddm.functions import fit_adjust_model model_fit = Model( name='Simple model (fitted)', drift=DriftConstant(drift=Fittable(minval=0, maxval=4)), noise=NoiseConstant(noise=Fittable(minval=.5, maxval=4)), bound=BoundConstant(B=1.1), overlay=OverlayNonDecision(nondectime=Fittable(minval=0, maxval=1)), dx=.001, dt=.01, T_dur=2) fit_adjust_model(samp, model_fit, method="differential_evolution", lossfunction=LossBIC) display_model(model_fit) # Plot the model fit to the PDFs and save the file. import ddm.plot import matplotlib.pyplot as plt ddm.plot.plot_fit_diagnostics(model=model_fit, sample=samp) plt.savefig("simple-fit.png") plt.show() print(sol.prob_correct()) print(sol.pdf_err())
wves = sqrt( float(self.kves)**2 / (float(self.kvis)**2 + float(self.kves)**2)) wvis = sqrt( float(self.kvis)**2 / (float(self.kvis)**2 + float(self.kves)**2)) return wves * mu_ves + wvis * mu_vis from ddm import Model, Fittable from ddm.functions import fit_adjust_model from ddm.models import NoiseConstant, BoundConstant, OverlayNonDecision model = Model( name="3DMP Kiani09 Sim", drift=DriftRate(kves=Fittable(minval=0, maxval=3), kvis=Fittable(minval=3, maxval=6), acc=acc, vel=vel), bound=BoundConstant(B=Fittable(minval=50, maxval=90)), noise=NoiseConstant(noise=1), overlay=OverlayNonDecision(nondectime=Fittable(minval=.1, maxval=.4)), dx=.01, dt=.001, T_dur=2.0) fit_model = fit_adjust_model(sample=sample, model=model) #model_gui(model=model, sample=sample)
OverlayNonDecision(nondectime=Fittable(minval=0, maxval=1)), OverlayPoissonMixture(pmixturecoef=.02, rate=1) ]), dx=.001, dt=.01, T_dur=10) # Check if an analytical solution exists. Model.has_analytical_solution(model_foodc) # For the current model: True ### Fit the model to the dataset to find parameters # Use the "differential_evolution" fitting method (default, recommanded fitting method) fit_model_foodc = fit_adjust_model(sample=foodc_sample, model=model_foodc, method='differential_evolution') # Use the "simple" fitting method (much faster) # fit_model_foodc = fit_adjust_model(sample = foodc_sample, model = model_foodc, method = 'simple') # To note, In documentation the key word "method" is documented as "fitting_method", # which is actually invalid now. # Display the fitting outcome (parameters) display_model(fit_model_foodc) ### Plot import ddm.plot # import matplotlib.pyplot as plt ddm.plot.plot_fit_diagnostics(model=fit_model_foodc,
def Fit_DDM_Group_JK_ib(domain='whole'): # create a df to record the output data column_names = ['domain', 'RS_level', 'sub_omit'] + model_rDDM.get_model_parameter_names() + \ ['loss_func_value', 'criterion', 'sample_size', 'on_bound'] rDDM_fitting_jk = pd.DataFrame(columns=column_names) # decide whether to fit rDDM on the whole dataset, # the advantageous trials or disadvantageous trials if domain == 'adv': data_for_fit = data[data['domain_group'] == 1] elif domain == 'dis': data_for_fit = data[data['domain_group'] == 2] else: data_for_fit = data # fit on groups of different RS levels for group in np.sort(data_for_fit['RS_level'].unique()): data_subgroup = data_for_fit[data_for_fit['RS_level'] == group] # omit subjects one at a time for sub_omit in np.sort(data_subgroup['subject'].unique()): # find the current fitting parameters in the fit_ref where = np.where((fit_ref['domain'] == domain) & (fit_ref['RS_level'] == group) & (fit_ref['sub_omit'] == str(sub_omit))) where = int(where[0]) # allow for extra ranges from the best fitting results extra = 0.05 extra_v_dis = 0.0005 extra_v_els = 0.005 if domain == 'dis': vg_max = fit_ref.iloc[where]['vg_best'] + extra_v_dis vg_min = fit_ref.iloc[where]['vg_best'] - extra_v_dis vl_max = fit_ref.iloc[where]['vl_best'] + extra_v_dis vl_min = fit_ref.iloc[where]['vl_best'] - extra_v_dis else: vg_max = fit_ref.iloc[where]['vg_best'] + extra_v_els vg_min = fit_ref.iloc[where]['vg_best'] - extra_v_els vl_max = fit_ref.iloc[where]['vl_best'] + extra_v_els vl_min = fit_ref.iloc[where]['vl_best'] - extra_v_els fixed_max = fit_ref.iloc[where]['fixed_best'] + extra fixed_min = fit_ref.iloc[where]['fixed_best'] - extra B_max = fit_ref.iloc[where]['B_best'] + extra B_min = fit_ref.iloc[where]['B_best'] - extra x0_max = fit_ref.iloc[where]['x0_best'] + extra x0_min = fit_ref.iloc[where]['x0_best'] - extra nondectime_max = fit_ref.iloc[where]['nondectime_best'] + extra nondectime_min = fit_ref.iloc[where]['nondectime_best'] - extra # create a DDM modell based on the current fitting range model_rDDM_ib = Model( name='Risk_DDM_individual_range_fit', drift=Risk_Drift(vg=Fittable(minval=vg_min, maxval=vg_max), vl=Fittable(minval=vl_min, maxval=vl_max), fixed=Fittable(minval=fixed_min, maxval=fixed_max)), IC=Biased_Start(x0=Fittable(minval=x0_min, maxval=x0_max)), noise=NoiseConstant(noise=1), bound=BoundConstant(B=Fittable(minval=B_min, maxval=B_max)), # Uniform Mixture Model overlay=OverlayChain(overlays=[ OverlayNonDecision(nondectime=Fittable( minval=nondectime_min, maxval=nondectime_max)), OverlayUniformMixture(umixturecoef=.05) ]), dx=0.001, dt=0.001, T_dur=10) # dx=0.01, dt=0.01, T_dur=10) data_jk = data_subgroup[data_subgroup['subject'] != sub_omit] sample_size = data_jk.shape[0] # create a sample and start fitting data_jk_sample = Sample.from_pandas_dataframe( data_jk, rt_column_name="RT", correct_column_name="accept") fit_sample = fit_adjust_model( sample=data_jk_sample, model=model_rDDM_ib, fitting_method='differential_evolution') # sort out results result_list = [[domain, group, sub_omit] + fit_sample.get_model_parameters() + \ [fit_sample.fitresult.value(), fit_sample.fitresult.loss, sample_size, 0]] # 0 in the end is the place holder for the counts in the on_buond column result_df = pd.DataFrame(result_list, columns=column_names) # check whether the estimated results are on the limits of the fitting ranges if result_df['vg'][0] == vg_min or result_df['vg'][0] == vg_max: result_df['on_bound'][0] += 1 if result_df['vl'][0] == vl_min or result_df['vl'][0] == vl_max: result_df['on_bound'][0] += 1 if result_df['fixed'][0] == fixed_min or result_df['fixed'][ 0] == fixed_max: result_df['on_bound'][0] += 1 if result_df['B'][0] == B_min or result_df['B'][0] == B_max: result_df['on_bound'][0] += 1 if result_df['x0'][0] == x0_min or result_df['x0'][0] == x0_max: result_df['on_bound'][0] += 1 if result_df['nondectime'][0] == nondectime_min or result_df[ 'nondectime'][0] == nondectime_max: result_df['on_bound'][0] += 1 # append the results rDDM_fitting_jk = rDDM_fitting_jk.append(result_df, ignore_index=True) return rDDM_fitting_jk