library(CausalQueries)
library(knitr)
library(ggplot2)
library(rstan)
library(bayesplot)
rstan_options(refresh = 0)
When you update a model using CausalQueries
,
CausalQueries
generates and updates a stan
model and saves the posterior distribution over parameters in the
model.
The basic usage is:
data <- data.frame(X = rep(c(0:1), 10), Y = rep(c(0:1), 10))
model <- make_model("X -> Y") |>
update_model(data)
The posterior over parameters can be accessed thus:
inspect(model, "posterior_distribution")
#>
#> posterior_distribution
#> Summary statistics of model parameters posterior distributions:
#>
#> Distributions matrix dimensions are
#> 4000 rows (draws) by 6 cols (parameters)
#>
#> mean sd
#> X.0 0.50 0.10
#> X.1 0.50 0.10
#> Y.00 0.08 0.07
#> Y.10 0.04 0.04
#> Y.01 0.80 0.11
#> Y.11 0.08 0.08
When querying a model you can request use of the posterior
distribution with the using
argument:
model |>
query_model(
query = "Y[X=1] > Y[X=0]",
using = c("priors", "posteriors")) |>
kable(digits = 2)
query | given | using | case_level | mean | sd | cred.low | cred.high |
---|---|---|---|---|---|---|---|
Y[X=1] > Y[X=0] | - | priors | FALSE | 0.25 | 0.19 | 0.01 | 0.71 |
Y[X=1] > Y[X=0] | - | posteriors | FALSE | 0.80 | 0.11 | 0.55 | 0.96 |
You can access a summary of the parameter values and convergence
information as produced by stan
thus:
inspect(model, "stan_summary")
#>
#> stan_summary
#> Stan model summary:
#>
#> Inference for Stan model: simplexes.
#> 4 chains, each with iter=2000; warmup=1000; thin=1;
#> post-warmup draws per chain=1000, total post-warmup draws=4000.
#>
#> mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
#> X.0 0.50 0.00 0.10 0.30 0.43 0.50 0.57 0.70 2479 1
#> X.1 0.50 0.00 0.10 0.30 0.43 0.50 0.57 0.70 2479 1
#> Y.00 0.08 0.00 0.07 0.00 0.03 0.06 0.11 0.27 2197 1
#> Y.10 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.14 4898 1
#> Y.01 0.80 0.00 0.11 0.55 0.74 0.82 0.88 0.96 4042 1
#> Y.11 0.08 0.00 0.08 0.00 0.02 0.06 0.11 0.27 4581 1
#> X0.Y00 0.04 0.00 0.04 0.00 0.01 0.03 0.05 0.14 2158 1
#> X1.Y00 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.14 2278 1
#> X0.Y10 0.02 0.00 0.02 0.00 0.01 0.01 0.03 0.07 4630 1
#> X1.Y10 0.02 0.00 0.02 0.00 0.01 0.01 0.03 0.07 4638 1
#> X0.Y01 0.40 0.00 0.10 0.22 0.33 0.40 0.46 0.61 2694 1
#> X1.Y01 0.40 0.00 0.10 0.22 0.33 0.40 0.47 0.59 2860 1
#> X0.Y11 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 4301 1
#> X1.Y11 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.14 4295 1
#> lp__ -14.55 0.04 1.49 -18.17 -15.37 -14.22 -13.46 -12.64 1475 1
#>
#> Samples were drawn using NUTS(diag_e) at Wed Nov 20 11:38:56 2024.
#> For each parameter, n_eff is a crude measure of effective sample size,
#> and Rhat is the potential scale reduction factor on split chains (at
#> convergence, Rhat=1).
This summary provides information on the distribution of parameters
as well as convergence diagnostics, summarized in the Rhat
column. In the printout above the first six rows show the distribution
of the model parameters; the next eight rows show the distribution over
transformed parameters, here the causal types. The last row shows the
unnormalized log density on Stan’s unconstrained space which, as
described in Stan
documentation is intended to diagnose sampling efficiency and
evaluate approximations.
See stan documentation for further details.
If you are interested in advanced diagnostics of performance you can
save and access the raw
stan output.
Note that the summary for this raw output shows the labels used in
the generic stan
model: lambda
for the vector
of parameters, corresponding to the parameters in the parameters
dataframe (inspect(model, "parameters_df")
), and , if
saved, a vector types
for the causal types (see
inspect(model, "causal_types")
) and w
for the
event probabilities
(inspect(model, "prior_event_probabilities")
).
model |> inspect("stanfit")
#>
#> stanfit
#> Stan model summary:
#> Inference for Stan model: simplexes.
#> 4 chains, each with iter=2000; warmup=1000; thin=1;
#> post-warmup draws per chain=1000, total post-warmup draws=4000.
#>
#> mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
#> lambdas[1] 0.50 0.00 0.10 0.29 0.43 0.50 0.57 0.70 1836 1
#> lambdas[2] 0.50 0.00 0.10 0.30 0.43 0.50 0.57 0.71 1836 1
#> lambdas[3] 0.08 0.00 0.08 0.00 0.02 0.06 0.12 0.29 2147 1
#> lambdas[4] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 4020 1
#> lambdas[5] 0.80 0.00 0.11 0.52 0.74 0.82 0.88 0.95 3820 1
#> lambdas[6] 0.08 0.00 0.08 0.00 0.02 0.06 0.11 0.28 4298 1
#> types[1] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 2175 1
#> types[2] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 2120 1
#> types[3] 0.02 0.00 0.02 0.00 0.01 0.01 0.03 0.08 3734 1
#> types[4] 0.02 0.00 0.02 0.00 0.01 0.01 0.03 0.08 3938 1
#> types[5] 0.40 0.00 0.10 0.21 0.33 0.40 0.46 0.60 2105 1
#> types[6] 0.40 0.00 0.10 0.21 0.33 0.40 0.47 0.61 2243 1
#> types[7] 0.04 0.00 0.04 0.00 0.01 0.03 0.05 0.15 4060 1
#> types[8] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 3944 1
#> lp__ -14.68 0.05 1.60 -18.60 -15.50 -14.35 -13.47 -12.67 1179 1
#>
#> Samples were drawn using NUTS(diag_e) at Wed Nov 20 11:38:57 2024.
#> For each parameter, n_eff is a crude measure of effective sample size,
#> and Rhat is the potential scale reduction factor on split chains (at
#> convergence, Rhat=1).
You can then use diagnostic packages such as
bayesplot
.
model |> inspect("stanfit") |>
bayesplot::mcmc_pairs(pars = c("lambdas[3]", "lambdas[4]", "lambdas[5]", "lambdas[6]"))
#>
#> stanfit
#> Stan model summary:
#> Inference for Stan model: simplexes.
#> 4 chains, each with iter=2000; warmup=1000; thin=1;
#> post-warmup draws per chain=1000, total post-warmup draws=4000.
#>
#> mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
#> lambdas[1] 0.50 0.00 0.10 0.29 0.43 0.50 0.57 0.70 1836 1
#> lambdas[2] 0.50 0.00 0.10 0.30 0.43 0.50 0.57 0.71 1836 1
#> lambdas[3] 0.08 0.00 0.08 0.00 0.02 0.06 0.12 0.29 2147 1
#> lambdas[4] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 4020 1
#> lambdas[5] 0.80 0.00 0.11 0.52 0.74 0.82 0.88 0.95 3820 1
#> lambdas[6] 0.08 0.00 0.08 0.00 0.02 0.06 0.11 0.28 4298 1
#> types[1] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 2175 1
#> types[2] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 2120 1
#> types[3] 0.02 0.00 0.02 0.00 0.01 0.01 0.03 0.08 3734 1
#> types[4] 0.02 0.00 0.02 0.00 0.01 0.01 0.03 0.08 3938 1
#> types[5] 0.40 0.00 0.10 0.21 0.33 0.40 0.46 0.60 2105 1
#> types[6] 0.40 0.00 0.10 0.21 0.33 0.40 0.47 0.61 2243 1
#> types[7] 0.04 0.00 0.04 0.00 0.01 0.03 0.05 0.15 4060 1
#> types[8] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 3944 1
#> lp__ -14.68 0.05 1.60 -18.60 -15.50 -14.35 -13.47 -12.67 1179 1
#>
#> Samples were drawn using NUTS(diag_e) at Wed Nov 20 11:38:57 2024.
#> For each parameter, n_eff is a crude measure of effective sample size,
#> and Rhat is the potential scale reduction factor on split chains (at
#> convergence, Rhat=1).
np <- model |> inspect("stanfit") |> bayesplot::nuts_params()
#>
#> stanfit
#> Stan model summary:
#> Inference for Stan model: simplexes.
#> 4 chains, each with iter=2000; warmup=1000; thin=1;
#> post-warmup draws per chain=1000, total post-warmup draws=4000.
#>
#> mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
#> lambdas[1] 0.50 0.00 0.10 0.29 0.43 0.50 0.57 0.70 1836 1
#> lambdas[2] 0.50 0.00 0.10 0.30 0.43 0.50 0.57 0.71 1836 1
#> lambdas[3] 0.08 0.00 0.08 0.00 0.02 0.06 0.12 0.29 2147 1
#> lambdas[4] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 4020 1
#> lambdas[5] 0.80 0.00 0.11 0.52 0.74 0.82 0.88 0.95 3820 1
#> lambdas[6] 0.08 0.00 0.08 0.00 0.02 0.06 0.11 0.28 4298 1
#> types[1] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 2175 1
#> types[2] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 2120 1
#> types[3] 0.02 0.00 0.02 0.00 0.01 0.01 0.03 0.08 3734 1
#> types[4] 0.02 0.00 0.02 0.00 0.01 0.01 0.03 0.08 3938 1
#> types[5] 0.40 0.00 0.10 0.21 0.33 0.40 0.46 0.60 2105 1
#> types[6] 0.40 0.00 0.10 0.21 0.33 0.40 0.47 0.61 2243 1
#> types[7] 0.04 0.00 0.04 0.00 0.01 0.03 0.05 0.15 4060 1
#> types[8] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 3944 1
#> lp__ -14.68 0.05 1.60 -18.60 -15.50 -14.35 -13.47 -12.67 1179 1
#>
#> Samples were drawn using NUTS(diag_e) at Wed Nov 20 11:38:57 2024.
#> For each parameter, n_eff is a crude measure of effective sample size,
#> and Rhat is the potential scale reduction factor on split chains (at
#> convergence, Rhat=1).
head(np) |> kable()
Chain | Iteration | Parameter | Value |
---|---|---|---|
1 | 1 | accept_stat__ | 0.8906345 |
1 | 2 | accept_stat__ | 0.8402453 |
1 | 3 | accept_stat__ | 0.9390884 |
1 | 4 | accept_stat__ | 0.9943855 |
1 | 5 | accept_stat__ | 0.9663906 |
1 | 6 | accept_stat__ | 0.8208385 |
model |>
inspect("stanfit") |>
bayesplot::mcmc_trace(pars = "lambdas[5]", np = np)
#>
#> stanfit
#> Stan model summary:
#> Inference for Stan model: simplexes.
#> 4 chains, each with iter=2000; warmup=1000; thin=1;
#> post-warmup draws per chain=1000, total post-warmup draws=4000.
#>
#> mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
#> lambdas[1] 0.50 0.00 0.10 0.29 0.43 0.50 0.57 0.70 1836 1
#> lambdas[2] 0.50 0.00 0.10 0.30 0.43 0.50 0.57 0.71 1836 1
#> lambdas[3] 0.08 0.00 0.08 0.00 0.02 0.06 0.12 0.29 2147 1
#> lambdas[4] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 4020 1
#> lambdas[5] 0.80 0.00 0.11 0.52 0.74 0.82 0.88 0.95 3820 1
#> lambdas[6] 0.08 0.00 0.08 0.00 0.02 0.06 0.11 0.28 4298 1
#> types[1] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 2175 1
#> types[2] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 2120 1
#> types[3] 0.02 0.00 0.02 0.00 0.01 0.01 0.03 0.08 3734 1
#> types[4] 0.02 0.00 0.02 0.00 0.01 0.01 0.03 0.08 3938 1
#> types[5] 0.40 0.00 0.10 0.21 0.33 0.40 0.46 0.60 2105 1
#> types[6] 0.40 0.00 0.10 0.21 0.33 0.40 0.47 0.61 2243 1
#> types[7] 0.04 0.00 0.04 0.00 0.01 0.03 0.05 0.15 4060 1
#> types[8] 0.04 0.00 0.04 0.00 0.01 0.03 0.06 0.15 3944 1
#> lp__ -14.68 0.05 1.60 -18.60 -15.50 -14.35 -13.47 -12.67 1179 1
#>
#> Samples were drawn using NUTS(diag_e) at Wed Nov 20 11:38:57 2024.
#> For each parameter, n_eff is a crude measure of effective sample size,
#> and Rhat is the potential scale reduction factor on split chains (at
#> convergence, Rhat=1).
#> No divergences to plot.