Define custom families (i.e. response distribution) for use in
brms models. It allows users to benefit from the modeling
flexibility of brms, while applying their self-defined likelihood
functions. All of the post-processing methods for brmsfit
objects can be made compatible with custom families.
See vignette("brms_customfamilies")
for more details.
For a list of built-in families see brmsfamily
.
custom_family( name, dpars = "mu", links = "identity", type = c("real", "int"), lb = NA, ub = NA, vars = NULL, loop = TRUE, specials = NULL, threshold = "flexible", log_lik = NULL, posterior_predict = NULL, posterior_epred = NULL, predict = NULL, fitted = NULL, env = parent.frame() )
name | Name of the custom family. |
---|---|
dpars | Names of the distributional parameters of
the family. One parameter must be named |
links | Names of the link functions of the distributional parameters. |
type | Indicates if the response distribution is
continuous ( |
lb | Vector of lower bounds of the distributional
parameters. Defaults to |
ub | Vector of upper bounds of the distributional
parameters. Defaults to |
vars | Names of variables that are part of the likelihood function
without being distributional parameters. That is, |
loop | Logical; Should the likelihood be evaluated via a loop
( |
specials | A character vector of special options to enable for this custom family. Currently for internal use only. |
threshold | Optional threshold type for custom ordinal families. Ignored for non-ordinal families. |
log_lik | Optional function to compute log-likelihood values of
the model in R. This is only relevant if one wants to ensure
compatibility with method |
posterior_predict | Optional function to compute posterior prediction of
the model in R. This is only relevant if one wants to ensure compatibility
with method |
posterior_epred | Optional function to compute expected values of the
posterior predictive distribution of the model in R. This is only relevant
if one wants to ensure compatibility with method
|
predict | Deprecated alias of `posterior_predict`. |
fitted | Deprecated alias of `posterior_epred`. |
env | An |
An object of class customfamily
inheriting
from class brmsfamily
.
The corresponding probability density or mass Stan
functions need to have the same name as the custom family.
That is if a family is called myfamily
, then the
Stan functions should be called myfamily_lpdf
or
myfamily_lpmf
depending on whether it defines a
continuous or discrete distribution.
if (FALSE) { ## demonstrate how to fit a beta-binomial model ## generate some fake data phi <- 0.7 n <- 300 z <- rnorm(n, sd = 0.2) ntrials <- sample(1:10, n, replace = TRUE) eta <- 1 + z mu <- exp(eta) / (1 + exp(eta)) a <- mu * phi b <- (1 - mu) * phi p <- rbeta(n, a, b) y <- rbinom(n, ntrials, p) dat <- data.frame(y, z, ntrials) # define a custom family beta_binomial2 <- custom_family( "beta_binomial2", dpars = c("mu", "phi"), links = c("logit", "log"), lb = c(NA, 0), type = "int", vars = "vint1[n]" ) # define the corresponding Stan density function stan_density <- " real beta_binomial2_lpmf(int y, real mu, real phi, int N) { return beta_binomial_lpmf(y | N, mu * phi, (1 - mu) * phi); } " stanvars <- stanvar(scode = stan_density, block = "functions") # fit the model fit <- brm(y | vint(ntrials) ~ z, data = dat, family = beta_binomial2, stanvars = stanvars) summary(fit) # define a *vectorized* custom family (no loop over observations) # notice also that 'vint' no longer has an observation index beta_binomial2_vec <- custom_family( "beta_binomial2", dpars = c("mu", "phi"), links = c("logit", "log"), lb = c(NA, 0), type = "int", vars = "vint1", loop = FALSE ) # define the corresponding Stan density function stan_density_vec <- " real beta_binomial2_lpmf(int[] y, vector mu, real phi, int[] N) { return beta_binomial_lpmf(y | N, mu * phi, (1 - mu) * phi); } " stanvars_vec <- stanvar(scode = stan_density_vec, block = "functions") # fit the model fit_vec <- brm(y | vint(ntrials) ~ z, data = dat, family = beta_binomial2_vec, stanvars = stanvars_vec) summary(fit_vec) }