Computes predictions from a bartisan() fit, at the data the model was fit
to or at new data, on any of several scales. Because every posterior draw of
every tree is retained, a prediction can be returned as its posterior mean or
as the draws themselves.
Usage
# S3 method for class 'bartisan_fit'
predict(
object,
newdata = NULL,
type = "response",
draws = FALSE,
iterations = NULL,
offset = NULL,
weights = NULL,
values = NULL,
log = FALSE,
times = NULL,
...
)Arguments
- object
a
<bartisan_fit>object; the output of a call tobartisan().- newdata
optional; a data frame at which to predict. Default is
NULLto use the data the model was fit to. Missing predictor values are allowed in the columns that had them when the model was fit, since only those columns' splitting rules carry an answer for one; a missing value anywhere else is an error. See section Missing Predictor Values in the Details ofbartisan().- type
string; the scale of the prediction. Allowable options include
"link","response"(the default),"prob","class","mean","stdlv","density","survival", and"hazard"."link"the additive predictor, one column per predictor for families that have more than one. For the accelerated failure time families it is on the scale of log time, so a difference between two units is a log time ratio. For
ph()it is reported centered over the fitted sample, so a single value is a log hazard ratio against a unit whose predictor sits at that average and a difference between two units is the log hazard ratio between them."response"the mean of the response; the median survival time for every survival family,
ph()included; and, for a response with categories, the category probabilities, there being no single mean to report."prob"category probabilities, for the binomial, ordinal and multinomial families.
"class"the most probable category, as a factor, for the same families.
"mean"the mean of the response with the category labels read as numbers, for the same families, so that
"4"counts as four. Thevaluesargument says what the categories are worth where the labels are not the numbers intended."stdlv"the additive predictor on the scale of the latent variable it indexes, for the ordinal and binomial families under the probit, logit and complementary log-log links. This puts fits with different links, or different amounts of signal, on one scale. See Details.
"density"the conditional density of the outcome given the predictors, evaluated at the observed outcome, so the
newdataargument must carry the outcome and leaving it empty uses the fitted data. This is the observation's likelihood contribution, so it is a probability for a discrete response and a survival probability for a censored time. See Details."survival"the survival function \(S(t \mid x)\) at the times given in
times, for the accelerated failure time families andph(). Returns one column per time, or a draws by rows by times array whendraws = TRUE. This makes the usual survival estimand reachable through marginaleffects; seebartisan-marginaleffects."hazard"the hazard \(h(t \mid x) = f(t \mid x) / S(t \mid x)\) at the times given in
times, the rate at which the event occurs at \(t\) among those who have survived to it, for the same families and in the same shape as"survival". The cumulative hazard is \(-\log S(t \mid x)\) and so comes from"survival".
- draws
logical; whether to return every posterior draw rather than the posterior mean. Default isFALSEto return the mean. IfTRUE, the result gains a leading dimension indexing the draws.- iterations
numeric; optional indices of the stored draws to use, between 1 and the number of draws the fit retains. Default isNULLto use all of them.- offset
numeric; an offset for the rows ofnewdata, on the link scale, given either as one value per row or as a matrix with one column per additive predictor. Used only whennewdatais supplied, and required there when the model was fit with an observation-level offset, since an offset is not a function of the predictors and so cannot be reconstructed. Default isNULLto add nothing.- weights
numeric; prior weights for the rows ofnewdata, used only bytype = "density"and ignored otherwise. For a binomial response given as proportions these are the numbers of trials, as instats::glm(). Default isNULL, which uses the weights the model was fit with whennewdatais omitted and a weight of 1 for every row when it is supplied.- values
numeric; fortype = "mean", what each response category is worth, given as a vector named for every level of the response. Default isNULLto read the level labels as numbers, which is an error rather than a guess when they cannot be read that way. Ignored with a warning for every othertype.- log
logical; fortype = "density", whether to return the log of the value. Default isFALSE. Summing the log density across observations gives a log score. Note that withdraws = FALSEthe density is averaged over the draws before the log is taken, so the result is the pointwise predictive density rather than the average log density.- times
numeric; fortype = "survival"andtype = "hazard", the times at which to report the survival function or the hazard, which must be finite and strictly positive. It has no default, because the horizon is a choice rather than a property of the fit. Ignored with a warning for every othertype.- ...
ignored; present for compatibility with the generic.
Value
With draws = FALSE, a vector with one element per observation for
"response", "mean" and "density", and for "link" and "stdlv" when
the family has a single additive predictor; a matrix of observations by
additive predictors for "link" and "stdlv" when it has more than one; a
matrix of observations by categories for "prob", and for "response" with
an ordinal or multinomial family; a matrix of observations by times for
"survival" and "hazard"; and a factor for "class", ordered when the
family is ordinal().
With draws = TRUE each of these gains a leading dimension indexing the
posterior draws, so that a vector becomes a matrix of draws by observations
and a matrix becomes an array of draws by observations by categories or by
times. On the "link" and "stdlv" scales a family with more than one
additive predictor returns a list with one draws-by-observations matrix per
predictor. "class" is a factor either way.
Details
Simulated Multinomial Probit Probabilities
The likelihood of a multinomial("probit") fit has no closed form: the
probability of a category is the chance that the largest of several correlated
Gaussian variables is the one belonging to it, which is a multivariate orthant
probability. So "prob", "class", "response" and "density" are all
simulated, using the number of replicates the family was given. Fresh draws
are taken on every call, so two calls differ by Monte Carlo error; that error
is per posterior draw and averages down over them, which makes draws = FALSE
much more accurate than any single row of draws = TRUE.
type = "stdlv"
This reports (eta - E[e]) / sd(y*) for the latent y* = eta + e, following
WeightIt::predict.ordinal_weightit()
, and makes an ordinal or
binary fit comparable across links.
The scale is sd(y*) = sqrt(var(eta) + var(e)), where var(eta) is taken
over the sample the model was fitted to, per draw, so it is a property of the
model rather than of whatever is being predicted and the same divisor is used
for new data. var(e) is whatever the link implies: 1 for the probit link,
\(\pi^2 / 3\) for the logit, \(\pi^2 / 6\) for the complementary
log-log. The location subtracts the latent error's mean, which is invisible
for the logit and probit links, whose errors are already centered, and is the
whole of the difference for the complementary log-log.
Such a model is identified only up to a common shift of its thresholds and its predictor, so the location here is a convention, and the one used is the same the cutpoints use: a predictor centered over the fitted sample. Differences on this scale, which a standardized quantity exists to support, are unaffected by that choice.
type = "density"
The measure differs across the survival families: the accelerated failure time
families, dpm_aft() included, report the density of \(\log T\), where
ph() reports the density of \(T\). The two differ by \(\sum \log t\),
so log scores are comparable within each group rather than across them, and
the type = "survival" prediction is comparable throughout. loo() takes a
scale argument that puts them on one measure.
Setting type = "density" returns NaN for an observation whose density is undefined
at any of the draws, which happens when a link the package does not compile
has been composed onto the family's own scale and its inverse does not cover
the whole additive predictor (e.g., poisson("identity"), which gives a
positive mean only where the predictor is positive). A warning reports how
many draw-by-observation values were undefined and how many returned values
that made NaN. The draws are averaged before the log is taken, so one
undefined draw is enough to make an observation NaN.
See also
bartisan() for fitting the model; bartisan-marginaleffects for averages
and contrasts of these predictions; bartisan-interop for the methods that
let other packages assess the fit
Examples
data("rhc")
set.seed(123)
# Whether a patient died, with the treatment and every
# covariate recorded on admission as candidate
# predictors
model <- death ~ rhc + age + sex + race + edu + aps +
meanbp + resp + hema + pafi + paco2 + crea + surv2m +
card
fit <- bartisan(model, data = rhc, num_trees = 10,
num_burn = 50, num_draws = 50)
#> ℹ Using `family = binomial()`.
#> ℹ Set `family` explicitly to silence this message.
# Fitted probabilities of death, averaged over the draws
head(predict(fit, type = "response"))
#> [1] 0.7959859 0.7976197 0.2008229 0.5216073 0.4393714 0.5232934
# The whole posterior for the first five patients rather
# than its mean
post <- predict(fit, newdata = rhc[1:5, ], draws = TRUE)
apply(post, 2, quantile, c(.025, .5, .975))
#> [,1] [,2] [,3] [,4] [,5]
#> 2.5% 0.7378238 0.6893544 0.1062475 0.4105328 0.3025466
#> 50% 0.7921700 0.8089335 0.1979082 0.5251180 0.4428998
#> 97.5% 0.8489815 0.8587385 0.3142898 0.6063779 0.5359435
# A held-out log score, which needs the outcome, so the
# `newdata` argument carries it
dens <- predict(fit, newdata = rhc[1:100, ],
type = "density")
sum(log(dens))
#> [1] -58.29588