Plotting in HSSM¶
This tutorial demonstrates the plotting functionalities in HSSM.
While the ArviZ package provides many plotting utilities, HSSM aims complement the ArviZ package with additional types of plots specific for hierarchical sequential sampling models. In addition, HSSM also provides some plotting API directly from the HSSM model object with some additional tweaks for convenience.
Most of the plotting and summary functionalities can be found in hssm.plotting module, and additional convenience functions are exposed through the top-level HSSM model as well.
# If running this on Colab, please uncomment the next line and
# !pip install hssm
from pathlib import Path
import arviz as az
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import hssm
import hssm.plotting
%matplotlib inline
%config InlineBackend.figure_format='retina'
import warnings
warnings.filterwarnings("ignore")
Model setup¶
fixtures_dir = Path("../../tests/fixtures")
cav_data_test = pd.read_csv(fixtures_dir / "cavanagh_theta_test.csv")
cav_data_traces = az.from_netcdf(fixtures_dir / "cavanagh_idata.nc")
# For demonstration purposes,
# `cav_data_test` is a subset of the `cavanagh_theta_nn` dataset
# with 5 subjects and 100 observation each
cav_data_test
| participant_id | stim | rt | response | theta | dbs | conf | |
|---|---|---|---|---|---|---|---|
| 0 | 0 | WL | 0.928 | -1.0 | -0.521933 | 0 | LC |
| 1 | 0 | WL | 0.661 | 1.0 | -0.219645 | 1 | LC |
| 2 | 0 | WW | 2.350 | -1.0 | -0.168728 | 1 | HC |
| 3 | 0 | LL | 1.250 | -1.0 | -0.104636 | 1 | HC |
| 4 | 0 | LL | 1.170 | -1.0 | 1.122720 | 1 | HC |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 495 | 4 | WL | 0.606 | -1.0 | -0.635942 | 0 | LC |
| 496 | 4 | WL | 0.745 | -1.0 | -0.166833 | 0 | LC |
| 497 | 4 | WW | 1.320 | 1.0 | -0.283396 | 1 | HC |
| 498 | 4 | LL | 1.640 | 1.0 | 0.462584 | 1 | HC |
| 499 | 4 | WL | 0.822 | 1.0 | -0.019645 | 0 | LC |
500 rows × 7 columns
# Model parameter specification
cav_model = hssm.HSSM(
model="ddm",
data=cav_data_test,
include=[
{
"name": "v",
"prior": {
"Intercept": {"name": "Normal", "mu": 0.0, "sigma": 1.0},
"theta": {"name": "Normal", "mu": 0.0, "sigma": 1.0},
},
"formula": "v ~ theta + (1|participant_id)",
"link": "identity",
},
],
)
# Perform sampling
# cav_model.sample()
Model initialized successfully.
For demonstration purposes, we inject into the model an existing trace with posterior predictive sampling already performed. A posterior_predictive attribute is added to the traces object. A rt,response_mean variable is also added to the posterior attribute during predictive sampling.
# In practice, you would obtain this object by sampling from the model.
cav_model._inference_obj = cav_data_traces
# Sample prior predictive
# cav_model.sample_prior_predictive(draws = 1000)
# Print
cav_model.traces
<xarray.DataTree>
Group: /
├── Group: /posterior
│ Dimensions: (chain: 2, draw: 500,
│ v_1|participant_id__factor_dim: 5,
│ __obs__: 500)
│ Coordinates:
│ * chain (chain) int64 16B 0 1
│ * draw (draw) int64 4kB 0 1 2 3 ... 496 497 498 499
│ * v_1|participant_id__factor_dim (v_1|participant_id__factor_dim) <U1 20B ...
│ * __obs__ (__obs__) int64 4kB 0 1 2 3 ... 497 498 499
│ Data variables:
│ v_Intercept (chain, draw) float64 8kB ...
│ v_theta (chain, draw) float32 4kB ...
│ a (chain, draw) float32 4kB ...
│ z (chain, draw) float32 4kB ...
│ t (chain, draw) float32 4kB ...
│ v_1|participant_id_sigma (chain, draw) float32 4kB ...
│ v_1|participant_id (chain, draw, v_1|participant_id__factor_dim) float32 20kB ...
│ v (chain, draw, __obs__) float64 4MB ...
│ Attributes:
│ created_at: 2023-11-14T18:35:04.027433
│ arviz_version: 0.14.0
│ inference_library: pymc
│ inference_library_version: 5.9.1
│ sampling_time: 22.505457878112793
│ tuning_steps: 1000
│ modeling_interface: bambi
│ modeling_interface_version: 0.12.0
├── Group: /posterior_predictive
│ Dimensions: (chain: 2, draw: 500, __obs__: 500, rt,response_dim: 2)
│ Coordinates:
│ * chain (chain) int64 16B 0 1
│ * draw (draw) int64 4kB 0 1 2 3 4 5 6 ... 494 495 496 497 498 499
│ * __obs__ (__obs__) int64 4kB 0 1 2 3 4 5 ... 494 495 496 497 498 499
│ * rt,response_dim (rt,response_dim) int64 16B 0 1
│ Data variables:
│ rt,response (chain, draw, __obs__, rt,response_dim) float32 4MB ...
│ Attributes:
│ modeling_interface: bambi
│ modeling_interface_version: 0.12.0
├── Group: /sample_stats
│ Dimensions: (chain: 2, draw: 500)
│ Coordinates:
│ * chain (chain) int64 16B 0 1
│ * draw (draw) int64 4kB 0 1 2 3 4 5 ... 495 496 497 498 499
│ Data variables: (12/17)
│ energy_error (chain, draw) float64 8kB ...
│ perf_counter_diff (chain, draw) float64 8kB ...
│ energy (chain, draw) float64 8kB ...
│ max_energy_error (chain, draw) float64 8kB ...
│ smallest_eigval (chain, draw) float64 8kB ...
│ step_size_bar (chain, draw) float64 8kB ...
│ ... ...
│ perf_counter_start (chain, draw) float64 8kB ...
│ process_time_diff (chain, draw) float64 8kB ...
│ index_in_trajectory (chain, draw) int64 8kB ...
│ reached_max_treedepth (chain, draw) bool 1kB ...
│ lp (chain, draw) float64 8kB ...
│ largest_eigval (chain, draw) float64 8kB ...
│ Attributes:
│ arviz_version: 0.14.0
│ created_at: 2023-11-14T18:35:04.032437
│ inference_library: pymc
│ inference_library_version: 5.9.1
│ modeling_interface: bambi
│ modeling_interface_version: 0.12.0
│ sampling_time: 22.505457878112793
│ tuning_steps: 1000
└── Group: /observed_data
Dimensions: (__obs__: 500, rt,response_extra_dim_0: 2)
Coordinates:
* __obs__ (__obs__) int64 4kB 0 1 2 3 4 ... 496 497 498 499
* rt,response_extra_dim_0 (rt,response_extra_dim_0) int64 16B 0 1
Data variables:
rt,response (__obs__, rt,response_extra_dim_0) float32 4kB ...
Attributes:
arviz_version: 0.14.0
created_at: 2023-11-14T18:35:04.034261
inference_library: pymc
inference_library_version: 5.9.1
modeling_interface: bambi
modeling_interface_version: 0.12.0Convenience functions from the top-level hssm.HSSM model object¶
The ArviZ package provides az.summary() and az.plot_trace_dist() functions that are very frequently used. HSSM previously provided model.summary() and model.plot_trace() convenience methods, but these have been removed in v0.4.0. Please use az.summary() and az.plot_trace_dist() directly.
1. Using az.summary()¶
Use az.summary() to get a summary of the posterior distribution. Note that when some parameters are the targets of regressions, ArviZ will also plot the computed values for each regressor on each observation, which is highly inefficient. You may need to filter out computed values manually.
set(list(cav_model.traces.posterior.data_vars.keys()))
{'a',
't',
'v',
'v_1|participant_id',
'v_1|participant_id_sigma',
'v_Intercept',
'v_theta',
'z'}
az.summary(cav_data_traces)
| mean | sd | eti89_lb | eti89_ub | ess_bulk | ess_tail | r_hat | mcse_mean | mcse_sd | |
|---|---|---|---|---|---|---|---|---|---|
| v_Intercept | 0.42 | 0.27 | -0.015 | 0.83 | 261 | 235 | 1.00 | 0.017 | 0.013 |
| v_theta | 0.062 | 0.048 | -0.014 | 0.14 | 619 | 593 | 1.01 | 0.002 | 0.0014 |
| a | 1.044 | 0.024 | 1 | 1.1 | 831 | 696 | 1.00 | 0.00084 | 0.00063 |
| z | 0.504 | 0.0195 | 0.47 | 0.53 | 766 | 511 | 1.00 | 0.0007 | 0.00047 |
| t | 0.337 | 0.0134 | 0.31 | 0.36 | 645 | 411 | 1.01 | 0.00054 | 0.00038 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| v[495] | 1.05 | 0.172 | 0.78 | 1.3 | 746 | 776 | 1.00 | 0.0063 | 0.0041 |
| v[496] | 1.08 | 0.169 | 0.82 | 1.4 | 790 | 688 | 1.00 | 0.006 | 0.004 |
| v[497] | 1.08 | 0.17 | 0.81 | 1.3 | 780 | 646 | 1.00 | 0.0061 | 0.004 |
| v[498] | 1.12 | 0.17 | 0.85 | 1.4 | 860 | 699 | 1.00 | 0.0058 | 0.004 |
| v[499] | 1.09 | 0.169 | 0.82 | 1.4 | 805 | 684 | 1.00 | 0.0059 | 0.004 |
511 rows × 9 columns
Compare this with the output of ArviZ az.summary():
# Because of posterior predictive sampling, an `rt,response_mean` field was added to
# the traces object by default. ArviZ include these values by default.
# This is equivalent to calling
# cav_model.summary(include_computed_values=True)
az.summary(cav_model.traces)
| mean | sd | eti89_lb | eti89_ub | ess_bulk | ess_tail | r_hat | mcse_mean | mcse_sd | |
|---|---|---|---|---|---|---|---|---|---|
| v_Intercept | 0.42 | 0.27 | -0.015 | 0.83 | 261 | 235 | 1.00 | 0.017 | 0.013 |
| v_theta | 0.062 | 0.048 | -0.014 | 0.14 | 619 | 593 | 1.01 | 0.002 | 0.0014 |
| a | 1.044 | 0.024 | 1 | 1.1 | 831 | 696 | 1.00 | 0.00084 | 0.00063 |
| z | 0.504 | 0.0195 | 0.47 | 0.53 | 766 | 511 | 1.00 | 0.0007 | 0.00047 |
| t | 0.337 | 0.0134 | 0.31 | 0.36 | 645 | 411 | 1.01 | 0.00054 | 0.00038 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| v[495] | 1.05 | 0.172 | 0.78 | 1.3 | 746 | 776 | 1.00 | 0.0063 | 0.0041 |
| v[496] | 1.08 | 0.169 | 0.82 | 1.4 | 790 | 688 | 1.00 | 0.006 | 0.004 |
| v[497] | 1.08 | 0.17 | 0.81 | 1.3 | 780 | 646 | 1.00 | 0.0061 | 0.004 |
| v[498] | 1.12 | 0.17 | 0.85 | 1.4 | 860 | 699 | 1.00 | 0.0058 | 0.004 |
| v[499] | 1.09 | 0.169 | 0.82 | 1.4 | 805 | 684 | 1.00 | 0.0059 | 0.004 |
511 rows × 9 columns
2. Using az.plot_trace_dist()¶
Use az.plot_trace_dist() to plot trace distributions. Note that you may need to call plt.tight_layout() afterwards for better layout:
az.plot_trace_dist(cav_data_traces)
<arviz_plots.plot_collection.PlotCollection at 0x12c0d27b0>
hssm.plotting.plot_predictive(cav_model, predictive_group="posterior_predictive");
The predictive_group argument lets you choose between the posterior_predictive and the prior_predictive groups.
hssm.plotting.plot_predictive(
cav_model, predictive_group="prior_predictive", x_range=(-10, 10)
);
No prior_predictive samples found. Generating prior_predictive samples using the provided DataTree object and the original data. This will modify the provided DataTree object, or if not provided, the traces object stored inside the model.
Sampling: [a, rt,response, t, v_1|participant_id_offset, v_1|participant_id_sigma, v_Intercept, v_theta, z]
This API is designed to be a light wrapper around Seaborn's sns.histplot() API. It accepts most arguments that sns.histplot() accepts. It also returns an ax object in matplotlib, so you can manipulate it further.
ax = hssm.plotting.plot_predictive(cav_model)
sns.despine()
ax.set_ylabel("")
plt.title("Posterior Predictive Plot")
Text(0.5, 1.0, 'Posterior Predictive Plot')
You can also plot subsets of data in subplots:
hssm.plotting.plot_predictive(
cav_model,
col="participant_id",
col_wrap=3, # limits to 3 columns per row
)
<seaborn.axisgrid.FacetGrid at 0x130179e80>
hssm.plotting.plot_predictive(
cav_model,
col="participant_id",
col_wrap=3, # limits to 3 columns per row
predictive_group="prior_predictive",
)
<seaborn.axisgrid.FacetGrid at 0x130e3e350>
2-dimensional grids are also possible:
hssm.plotting.plot_predictive(
cav_model,
col="participant_id",
row="conf",
)
<seaborn.axisgrid.FacetGrid at 0x1311ba990>
When grids are used, this function returns a sns.FacetGrid object. You can also further customize your plot with this object as well. For example, you can set the titles each individual subplot according to a template or save the figure to disk (g.savefig()).
g = hssm.plotting.plot_predictive(
cav_model,
col="participant_id",
row="conf",
)
g.set_titles(template="{row_name} | Participant {col_name}")
<seaborn.axisgrid.FacetGrid at 0x1301c5a90>
hssm.plotting.plot_quantile_probability() works similarly to hssm.plotting.plot_predictive() in that when only producing one plot (no grid), it returns an axis object, and when it returns multiple plots, it produces a FacetGrid object
# Single plot, returns an axis object, which can be worked on further
ax = hssm.plotting.plot_quantile_probability(
cav_model, cond="stim", predictive_style="points"
)
ax.set_ylim(0, 3);
ax = hssm.plotting.plot_quantile_probability(
cav_model, cond="stim", predictive_style="ellipse", ellipse_confidence=0.95
)
ax.set_ylim(0, 3);
The quantile_by argument¶
An important aspect of the underlying computations in the plot_quantile_probability() function is given by the quantile_by argument.
This argument specifies an extra level of disaggregation in the quantile_probability() computations. E.g. if you pass participant_id, quantiles will first be computed at the participant level (on top of the levels you specify via grouping of the plot into subplots) and then aggregated.
The default is None so if you call this plot without specifying quantile_by, quantiles are computed at the basic subplot level.
ax = hssm.plotting.plot_quantile_probability(
cav_model,
cond="stim",
predictive_style="ellipse",
quantile_by=["participant_id"],
ellipse_confidence=0.95,
)
ax.set_ylim(0, 4)
ax.set_xlim(0.15, 0.85);
# Multiple plots, returns a FacetGrid
g = hssm.plotting.plot_quantile_probability(
cav_model,
cond="stim",
col="participant_id",
col_wrap=3,
grid_kwargs=dict(
ylim=(0, 3)
), # additional kwargs to the grid can be passed through `grid_kwargs`
)
The predictive_group argument works here too:
# Multiple plots, returns a FacetGrid
g = hssm.plotting.plot_quantile_probability(
cav_model,
cond="stim",
col="participant_id",
predictive_group="prior_predictive",
col_wrap=3,
grid_kwargs=dict(
ylim=(0, 3)
), # additional kwargs to the grid can be passed through `grid_kwargs`
)
Model Cartoon Plots¶
This part showcases the plot_model_cartoon() function, which is part of the HSSM plotting submodule.
The idea with these plots is to provide a pictorial representation of the underlying process that we recover with our model fits.
You can explore various options to include posterior uncertainty graphically in these plots.
ax_1 = hssm.plotting.plot_model_cartoon(
cav_model,
n_samples=10,
bins=20,
col="stim",
row="participant_id",
groups=["dbs"],
plot_predictive_mean=True,
plot_predictive_samples=True,
# extra arguments for the underlying plot_model_cartoon() function
n_trajectories=2,
);
No posterior_predictive samples found. Generating posterior_predictive samples using the provided DataTree object and the original data. This will modify the provided DataTree object, or if not provided, the traces object stored inside the model.
Prior Predictive¶
Note, the model cartoon plots look particularly unwieldy when using the prior predictive. If you want, take a look at the prior specifications and you can reason why and how it translates into such an unruly plot.
ax_2 = hssm.plotting.plot_model_cartoon(
cav_model,
n_samples=10,
bins=20,
col="stim",
row="participant_id",
groups=["dbs"],
plot_predictive_mean=True,
plot_predictive_samples=True,
predictive_group="prior_predictive",
# extra arguments for the underlying plot_model_cartoon() function
n_trajectories=2,
);
No split by group | Inclue posterior uncertainty¶
ax = hssm.plotting.plot_model_cartoon(
cav_model,
n_samples=100,
bins=10,
col="stim",
row="participant_id",
plot_predictive_mean=True,
plot_predictive_samples=True,
alpha_mean=1.0,
alpha_predictive=0.01,
alpha_trajectories=0.5,
# extra arguments for the underlying plot_model_cartoon() function
n_trajectories=2,
);
No posterior_predictive samples found. Generating posterior_predictive samples using the provided DataTree object and the original data. This will modify the provided DataTree object, or if not provided, the traces object stored inside the model.
ax = hssm.plotting.plot_model_cartoon(
cav_model,
n_samples=10,
bins=20,
col="stim",
row="participant_id",
groups=["dbs"],
plot_predictive_mean=True,
plot_predictive_samples=True,
predictive_group="prior_predictive",
alpha_mean=1.0,
alpha_predictive=0.01,
alpha_trajectories=0.5,
# extra arguments for the underlying plot_model_cartoon() function
n_trajectories=2,
);
N Choices¶
Data simulation¶
stim_v = [0.0, 0.75, 1.0]
stim_names = ["low", "medium", "high"]
datasets = []
a_vec = np.random.normal(loc=1.25, scale=0.3, size=5)
for v_tmp in stim_v:
for participant_id in range(5):
a_tmp = a_vec[participant_id]
data_tmp = hssm.simulate_data(
model="race_no_bias_angle_4",
theta=dict(
a=a_tmp,
v0=v_tmp,
v1=v_tmp + 0.25,
v2=v_tmp + 0.5,
v3=v_tmp + 0.75,
z=0.5,
t=0.2,
theta=0.1,
),
size=200,
)
data_tmp["stim"] = stim_names[stim_v.index(v_tmp)]
data_tmp["participant_id"] = str(participant_id)
datasets.append(data_tmp)
dataset = pd.concat(datasets).reset_index(drop=True)
param_dict = {
"v": {
"low": np.repeat(stim_v[0], 5),
"medium": np.repeat(stim_v[1], 5),
"high": np.repeat(stim_v[2], 5),
},
"a": {"participant_id"},
}
HSSM Model¶
race_model = hssm.HSSM(
model="race_no_bias_angle_4",
data=dataset,
include=[
{
"name": "v0",
"prior": {
"Intercept": {"name": "Normal", "mu": 0.0, "sigma": 1.5},
},
"formula": "v0 ~ 1 + stim",
"link": "identity",
},
{
"name": "a",
"prior": {
"Intercept": {"name": "Normal", "mu": 1.5, "sigma": 0.5},
},
"formula": "a ~ 1 + (1|participant_id)",
"link": "identity",
},
],
p_outlier=0.00,
)
Warning: You are sending unauthenticated requests to the HF Hub. Please set a HF_TOKEN to enable higher rate limits and faster downloads.
Model initialized successfully.
idata_race = race_model.sample(
sampler="numpyro",
chains=2,
cores=2,
chain_method="vectorized",
draws=500,
tune=500,
idata_kwargs=dict(log_likelihood=False), # no need to return likelihoods here
)
Using default initvals.
NUTS[numpyro]: [v3, theta, t, z, v2, v1, v0_Intercept, v0_stim, a_Intercept, a_1|participant_id_sigma, a_1|participant_id_offset]
0%| | 0/1000 [00:00<?, ?it/s]
warmup: 5%|▌ | 50/1000 [00:04<01:29, 10.65it/s, 7 steps of size 2.55e-03. acc. prob=0.73]
warmup: 10%|█ | 100/1000 [00:07<01:01, 14.69it/s, 10 steps of size 5.27e-03. acc. prob=0.76]
warmup: 15%|█▌ | 150/1000 [00:09<00:47, 17.93it/s, 12 steps of size 1.61e-01. acc. prob=0.78]
warmup: 20%|██ | 200/1000 [00:10<00:36, 22.14it/s, 6 steps of size 8.55e-02. acc. prob=0.78]
warmup: 25%|██▌ | 250/1000 [00:12<00:31, 24.04it/s, 3 steps of size 3.20e-02. acc. prob=0.78]
warmup: 30%|███ | 300/1000 [00:14<00:28, 24.93it/s, 6 steps of size 4.19e-02. acc. prob=0.78]
warmup: 35%|███▌ | 350/1000 [00:16<00:26, 24.27it/s, 12 steps of size 1.09e-01. acc. prob=0.78]
warmup: 40%|████ | 400/1000 [00:19<00:28, 20.90it/s, 24 steps of size 7.33e-02. acc. prob=0.78]
warmup: 45%|████▌ | 450/1000 [00:23<00:32, 17.11it/s, 9 steps of size 1.18e-01. acc. prob=0.79]
warmup: 50%|█████ | 500/1000 [00:26<00:28, 17.56it/s, 9 steps of size 5.52e-02. acc. prob=0.79]
sample: 55%|█████▌ | 550/1000 [00:28<00:24, 18.49it/s, 11 steps of size 5.52e-02. acc. prob=0.90]
sample: 60%|██████ | 600/1000 [00:31<00:21, 18.70it/s, 1 steps of size 5.52e-02. acc. prob=0.87]
sample: 65%|██████▌ | 650/1000 [00:34<00:20, 17.41it/s, 48 steps of size 5.52e-02. acc. prob=0.88]
sample: 70%|███████ | 700/1000 [00:41<00:23, 12.70it/s, 4 steps of size 5.52e-02. acc. prob=0.89]
sample: 75%|███████▌ | 750/1000 [00:46<00:22, 11.25it/s, 58 steps of size 5.52e-02. acc. prob=0.90]
sample: 80%|████████ | 800/1000 [00:49<00:15, 13.01it/s, 4 steps of size 5.52e-02. acc. prob=0.88]
sample: 85%|████████▌ | 850/1000 [00:51<00:10, 14.28it/s, 16 steps of size 5.52e-02. acc. prob=0.88]
sample: 90%|█████████ | 900/1000 [00:53<00:05, 16.78it/s, 61 steps of size 5.52e-02. acc. prob=0.85]
sample: 95%|█████████▌| 950/1000 [00:57<00:03, 14.92it/s, 42 steps of size 5.52e-02. acc. prob=0.86]
sample: 100%|██████████| 1000/1000 [01:02<00:00, 13.88it/s, 33 steps of size 5.52e-02. acc. prob=0.87]
sample: 100%|██████████| 1000/1000 [01:02<00:00, 16.12it/s, 33 steps of size 5.52e-02. acc. prob=0.87]
0%| | 0/1000 [00:00<?, ?it/s]
warmup: 5%|▌ | 50/1000 [00:02<00:50, 18.76it/s, 14 steps of size 7.92e-03. acc. prob=0.74]
warmup: 10%|█ | 100/1000 [00:04<00:40, 22.32it/s, 12 steps of size 3.18e-03. acc. prob=0.76]
warmup: 15%|█▌ | 150/1000 [00:07<00:44, 19.06it/s, 12 steps of size 1.57e-01. acc. prob=0.77]
warmup: 20%|██ | 200/1000 [00:10<00:41, 19.20it/s, 12 steps of size 2.69e-01. acc. prob=0.78]
warmup: 25%|██▌ | 250/1000 [00:11<00:34, 21.95it/s, 5 steps of size 1.67e-01. acc. prob=0.78]
warmup: 30%|███ | 300/1000 [00:14<00:31, 22.45it/s, 9 steps of size 6.15e-02. acc. prob=0.78]
warmup: 35%|███▌ | 350/1000 [00:16<00:28, 22.92it/s, 24 steps of size 1.47e-01. acc. prob=0.78]
warmup: 40%|████ | 400/1000 [00:18<00:25, 23.97it/s, 2 steps of size 1.20e-01. acc. prob=0.78]
warmup: 45%|████▌ | 450/1000 [00:24<00:37, 14.50it/s, 23 steps of size 2.45e-01. acc. prob=0.79]
warmup: 50%|█████ | 500/1000 [00:26<00:28, 17.26it/s, 3 steps of size 8.67e-02. acc. prob=0.78]
sample: 55%|█████▌ | 550/1000 [00:28<00:23, 19.38it/s, 12 steps of size 8.67e-02. acc. prob=0.83]
sample: 60%|██████ | 600/1000 [00:29<00:18, 22.17it/s, 2 steps of size 8.67e-02. acc. prob=0.78]
sample: 65%|██████▌ | 650/1000 [00:30<00:12, 27.65it/s, 13 steps of size 8.67e-02. acc. prob=0.71]
sample: 70%|███████ | 700/1000 [00:31<00:09, 31.03it/s, 15 steps of size 8.67e-02. acc. prob=0.70]
sample: 75%|███████▌ | 750/1000 [00:32<00:06, 36.52it/s, 4 steps of size 8.67e-02. acc. prob=0.69]
sample: 80%|████████ | 800/1000 [00:33<00:05, 35.93it/s, 19 steps of size 8.67e-02. acc. prob=0.70]
sample: 85%|████████▌ | 850/1000 [00:35<00:04, 36.80it/s, 4 steps of size 8.67e-02. acc. prob=0.70]
sample: 90%|█████████ | 900/1000 [00:36<00:02, 39.57it/s, 12 steps of size 8.67e-02. acc. prob=0.69]
sample: 95%|█████████▌| 950/1000 [00:37<00:01, 39.74it/s, 3 steps of size 8.67e-02. acc. prob=0.69]
sample: 100%|██████████| 1000/1000 [00:38<00:00, 36.02it/s, 16 steps of size 8.67e-02. acc. prob=0.70]
sample: 100%|██████████| 1000/1000 [00:38<00:00, 25.65it/s, 16 steps of size 8.67e-02. acc. prob=0.70]
There were 996 divergences after tuning. Increase `target_accept` or reparameterize.
We recommend running at least 4 chains for robust computation of convergence diagnostics
The rhat statistic is larger than 1.01 for some parameters. This indicates problems during sampling. See https://arxiv.org/abs/1903.08008 for details
The effective sample size per chain is smaller than 100 for some parameters. A higher number is needed for reliable rhat and ess computation. See https://arxiv.org/abs/1903.08008 for details
Plot¶
ax = hssm.plotting.plot_model_cartoon(
race_model,
n_samples=10,
col="stim",
row="participant_id",
plot_pp_mean=True,
plot_pp_samples=False,
n_trajectories=1,
ylims=(0, 5),
alpha_pp=0.2,
xlims=(0.0, 2),
);
No posterior_predictive samples found. Generating posterior_predictive samples using the provided DataTree object and the original data. This will modify the provided DataTree object, or if not provided, the traces object stored inside the model.