Colab Instructions¶
If you would like to run this tutorial on Google colab, please click this link.
Once you are in the colab, follow the installation instructions below and then restart your runtime.
Just uncomment the code in the next code cell and run it!
NOTE:
You may want to switch your runtime to have a GPU or TPU. To do so, go to Runtime > Change runtime type and select the desired hardware accelerator.
Note that if you switch your runtime you have to follow the installation instructions again.
# If running this on Colab, please uncomment the next line
# !pip install hssm
Using lapse probabilities and distributions in HSSM¶
Since v0.1.2, HSSM has added the ability to model outliers in the distribution with lapse probabilities and distributions. Let's see how it works.
import bambi as bmb
import matplotlib.pyplot as plt
import hssm
import warnings
warnings.filterwarnings("ignore")
Lapse probabilities and distributions are enabled by default.¶
From v0.1.2 on, lapse probabilities and distributions are enabled by default. If left unspecified, the probability for outliers will be a fixed value of 0.05 and the distribution will be specified as Uniform(0, 10)
.
# Simulate some data
ddm_data = hssm.simulate_data(
model="ddm", theta=dict(v=0.5, a=1.5, z=0.5, t=0.1), size=1000
)
ddm_data.head()
rt | response | |
---|---|---|
0 | 0.738123 | -1.0 |
1 | 3.669316 | 1.0 |
2 | 1.302614 | 1.0 |
3 | 1.763521 | -1.0 |
4 | 2.213896 | 1.0 |
# Build the simplest model specifying only data
# Note the model output
ddm_model_default = hssm.HSSM(data=ddm_data)
ddm_model_default
Model initialized successfully.
Hierarchical Sequential Sampling Model Model: ddm Response variable: rt,response Likelihood: analytical Observations: 1000 Parameters: v: Prior: Normal(mu: 0.0, sigma: 2.0) Explicit bounds: (-inf, inf) a: Prior: HalfNormal(sigma: 2.0) Explicit bounds: (0.0, inf) z: Prior: Uniform(lower: 0.0, upper: 1.0) Explicit bounds: (0.0, 1.0) t: Prior: HalfNormal(sigma: 2.0) Explicit bounds: (0.0, inf) Lapse probability: 0.05 Lapse distribution: Uniform(lower: 0.0, upper: 20.0)
Note
Note in the above output that lapse probability and lapse distributions are at default values.
Specifying lapse probability and distribution¶
It is easy to change the lapse probability and distribution. HSSM has added two arguments, p_outlier
and lapse
to allow the lapse probability and distribution to be specified.
The optional p_outlier
accepts a float
, a dict
, or a bmb.Prior
object. When p_outlier
is specified as a single float
value, it will be considered "fixed". You can also specify a prior distribution for p_outlier
through a dict
or a bmb.Prior
object, the same way as you would when specifying priors for any other parameter. That way, the lapse probability will be considered another parameter and will be estimated during MCMC sampling.
Likewise, the lapse
argument accepts a dict
or a bmb.Prior
object to specify a fixed lapse distribution. This distribution will be considered as the one that outliers are generated from.
ddm_model_lapse = hssm.HSSM(
data=ddm_data,
p_outlier={"name": "Uniform", "lower": 0.0001, "upper": 0.5},
lapse=bmb.Prior("Uniform", lower=0.0, upper=20.0),
)
ddm_model_lapse
Model initialized successfully.
Hierarchical Sequential Sampling Model Model: ddm Response variable: rt,response Likelihood: analytical Observations: 1000 Parameters: v: Prior: Normal(mu: 0.0, sigma: 2.0) Explicit bounds: (-inf, inf) a: Prior: HalfNormal(sigma: 2.0) Explicit bounds: (0.0, inf) z: Prior: Uniform(lower: 0.0, upper: 1.0) Explicit bounds: (0.0, 1.0) t: Prior: HalfNormal(sigma: 2.0) Explicit bounds: (0.0, inf) Lapse probability: Uniform(lower: 0.0001, upper: 0.5) Lapse distribution: Uniform(lower: 0.0, upper: 20.0)
lapse_trace = ddm_model_lapse.sample()
lapse_trace
Using default initvals.
Initializing NUTS using adapt_diag... Multiprocess sampling (4 chains in 4 jobs) NUTS: [z, p_outlier, t, a, v]
Output()
Sampling 4 chains for 1_000 tune and 1_000 draw iterations (4_000 + 4_000 draws total) took 23 seconds. 100%|██████████| 4000/4000 [00:01<00:00, 2654.19it/s]
-
<xarray.Dataset> Size: 168kB Dimensions: (chain: 4, draw: 1000) Coordinates: * chain (chain) int64 32B 0 1 2 3 * draw (draw) int64 8kB 0 1 2 3 4 5 6 7 ... 993 994 995 996 997 998 999 Data variables: p_outlier (chain, draw) float64 32kB 0.01574 0.0164 ... 0.01012 0.01252 t (chain, draw) float64 32kB 0.09827 0.1512 ... 0.1614 0.1558 z (chain, draw) float64 32kB 0.4651 0.4722 0.4727 ... 0.4891 0.4993 a (chain, draw) float64 32kB 1.571 1.454 1.523 ... 1.435 1.449 v (chain, draw) float64 32kB 0.6329 0.5217 0.5652 ... 0.5189 0.5327 Attributes: created_at: 2025-07-13T13:58:06.293676+00:00 arviz_version: 0.21.0 inference_library: pymc inference_library_version: 5.21.1 sampling_time: 23.291183948516846 tuning_steps: 1000 modeling_interface: bambi modeling_interface_version: 0.15.0
-
<xarray.Dataset> Size: 32MB Dimensions: (chain: 4, draw: 1000, __obs__: 1000) Coordinates: * chain (chain) int64 32B 0 1 2 3 * draw (draw) int64 8kB 0 1 2 3 4 5 6 ... 993 994 995 996 997 998 999 * __obs__ (__obs__) int64 8kB 0 1 2 3 4 5 6 ... 994 995 996 997 998 999 Data variables: rt,response (chain, draw, __obs__) float64 32MB -2.597 -2.595 ... -1.806 Attributes: modeling_interface: bambi modeling_interface_version: 0.15.0
-
<xarray.Dataset> Size: 496kB Dimensions: (chain: 4, draw: 1000) Coordinates: * chain (chain) int64 32B 0 1 2 3 * draw (draw) int64 8kB 0 1 2 3 4 5 ... 995 996 997 998 999 Data variables: (12/17) n_steps (chain, draw) float64 32kB 7.0 7.0 7.0 ... 7.0 3.0 tree_depth (chain, draw) int64 32kB 3 3 3 4 3 3 ... 4 3 4 3 3 2 largest_eigval (chain, draw) float64 32kB nan nan nan ... nan nan perf_counter_diff (chain, draw) float64 32kB 0.007566 ... 0.003679 acceptance_rate (chain, draw) float64 32kB 0.6021 0.8763 ... 0.9702 index_in_trajectory (chain, draw) int64 32kB 7 -6 6 6 3 -3 ... -3 3 1 2 2 ... ... energy_error (chain, draw) float64 32kB 0.6817 0.1329 ... -0.02246 diverging (chain, draw) bool 4kB False False ... False False process_time_diff (chain, draw) float64 32kB 0.007476 ... 0.003676 lp (chain, draw) float64 32kB -1.948e+03 ... -1.944e+03 step_size (chain, draw) float64 32kB 0.6981 0.6981 ... 0.5802 perf_counter_start (chain, draw) float64 32kB 1.433e+06 ... 1.433e+06 Attributes: created_at: 2025-07-13T13:58:06.312112+00:00 arviz_version: 0.21.0 inference_library: pymc inference_library_version: 5.21.1 sampling_time: 23.291183948516846 tuning_steps: 1000 modeling_interface: bambi modeling_interface_version: 0.15.0
-
<xarray.Dataset> Size: 24kB Dimensions: (__obs__: 1000, rt,response_extra_dim_0: 2) Coordinates: * __obs__ (__obs__) int64 8kB 0 1 2 3 4 ... 996 997 998 999 * rt,response_extra_dim_0 (rt,response_extra_dim_0) int64 16B 0 1 Data variables: rt,response (__obs__, rt,response_extra_dim_0) float64 16kB ... Attributes: created_at: 2025-07-13T13:58:06.314769+00:00 arviz_version: 0.21.0 inference_library: pymc inference_library_version: 5.21.1 modeling_interface: bambi modeling_interface_version: 0.15.0
ddm_model_lapse.summary(lapse_trace)
mean | sd | hdi_3% | hdi_97% | mcse_mean | mcse_sd | ess_bulk | ess_tail | r_hat | |
---|---|---|---|---|---|---|---|---|---|
t | 0.129 | 0.020 | 0.093 | 0.168 | 0.000 | 0.000 | 2236.0 | 2008.0 | 1.0 |
v | 0.564 | 0.035 | 0.497 | 0.628 | 0.001 | 0.001 | 2337.0 | 2251.0 | 1.0 |
p_outlier | 0.013 | 0.008 | 0.000 | 0.029 | 0.000 | 0.000 | 2150.0 | 1410.0 | 1.0 |
z | 0.481 | 0.013 | 0.458 | 0.505 | 0.000 | 0.000 | 2335.0 | 2380.0 | 1.0 |
a | 1.488 | 0.027 | 1.438 | 1.540 | 0.001 | 0.000 | 2263.0 | 2411.0 | 1.0 |
ddm_model_lapse.plot_trace(lapse_trace)
plt.tight_layout()
Disable lapse probabilities and distributions¶
When p_outliers
is set to None
or 0, lapse probability and distributions will be ignored. They will not be included in the model output.
Note
If `p_outlier` is set to `None` or 0 but `lapse` is not set to None, you will receive a warning. Please remember to also set `lapse` to `None`.
ddm_model_no_lapse = hssm.HSSM(data=ddm_data, p_outlier=None, lapse=None)
ddm_model_no_lapse
Model initialized successfully.
Hierarchical Sequential Sampling Model Model: ddm Response variable: rt,response Likelihood: analytical Observations: 1000 Parameters: v: Prior: Normal(mu: 0.0, sigma: 2.0) Explicit bounds: (-inf, inf) a: Prior: HalfNormal(sigma: 2.0) Explicit bounds: (0.0, inf) z: Prior: Uniform(lower: 0.0, upper: 1.0) Explicit bounds: (0.0, 1.0) t: Prior: HalfNormal(sigma: 2.0) Explicit bounds: (0.0, inf)
ddm_model_no_lapse_warn = hssm.HSSM(data=ddm_data, p_outlier=0)
ddm_model_no_lapse_warn
You have specified the `lapse` argument to include a lapse distribution, but `p_outlier` is set to either 0 or None. Your lapse distribution will be ignored. Model initialized successfully.
Hierarchical Sequential Sampling Model Model: ddm Response variable: rt,response Likelihood: analytical Observations: 1000 Parameters: v: Prior: Normal(mu: 0.0, sigma: 2.0) Explicit bounds: (-inf, inf) a: Prior: HalfNormal(sigma: 2.0) Explicit bounds: (0.0, inf) z: Prior: Uniform(lower: 0.0, upper: 1.0) Explicit bounds: (0.0, 1.0) t: Prior: HalfNormal(sigma: 2.0) Explicit bounds: (0.0, inf)