
Fit a COS Model
cos_fit.RdFits a COS model. For family = "gaussian", this fits the collapsed
posterior. Spatial preparation objects fit
tau_B_sq, sigma_sq, and phi. Non-spatial preparation
objects fit the COS submodel without spatial random effects and sample only
tau_B_sq. The fine-support nugget variance tau_sq is recovered
from tau_B_sq / mean(diag(D_h)).
For family = "binomial", the sampler uses Polya-Gamma augmentation on
the observed support, with linear predictor
\(\eta_l = offset_l + x_B(B_l)^\top\beta + \omega_B(B_l)\) for observed
support \(B_l\). Stacked over supports, this is
eta_B = offset + X_B beta + omega_B. This first implementation keeps
beta and omega_B explicit in the Markov state. There is no
Gaussian nugget variance tau_sq in the binomial likelihood.
For family = "negative_binomial", the sampler uses a fixed-size
negative-binomial likelihood with mean \(\mu_l = \exp(\eta_l)\) on observed
support \(B_l\). Stacked over supports,
eta_B = offset + X_B beta + omega_B. The size parameter is fixed by
the size argument. There is no Gaussian nugget variance
tau_sq in this likelihood.
Usage
cos_fit(prep, priors,
family = c("gaussian", "binomial", "negative_binomial", "negbin", "nb"),
trials = NULL, size = NULL, offset = NULL, n_chains = 1L, starting = NULL,
tuning = c(log_tau_B_sq = 1, log_sigma_sq = 1, z_phi = 1),
n_batch = 1000, batch_length = 25, accept_rate = 0.234,
seed = NULL, report = 100, n_threads = NULL, verbose = TRUE)
cos_summary_theta(fit, burn_in = 1,
pars = c("tau_B_sq", "tau_sq", "sigma_sq", "phi", "eff_range"),
probs = c(0.5, 0.025, 0.975), digits = 3)
cos_plot_trace(fit, burn_in = 1,
pars = c("tau_B_sq", "sigma_sq", "phi", "eff_range"))Arguments
- prep
A
"cos_prep"object.- priors
A
"cos_priors"object.- family
Response family. The default
"gaussian"uses the collapsed Gaussian COS sampler."binomial"uses a separate Polya-Gamma sampler with explicitbetaand observed-support spatial effect draws."negative_binomial"uses the same Polya-Gamma path for fixed-size count models; aliases"negbin"and"nb"are accepted.- trials
Binomial trial counts for
family = "binomial". Supply a positive integer vector of length one orlength(prep$y_B), or the name of a column inprep$B_sf.- size
Fixed negative-binomial size parameter for
family = "negative_binomial".- offset
Optional linear-predictor offset for Polya-Gamma response families. Supply
NULL, a finite numeric vector of length one orlength(prep$y_B), or the name of a column inprep$B_sf. For count models this is commonly a log exposure.- n_chains
Number of independent MCMC chains.
- starting
Optional starting values. Spatial fits use
tau_B_sq,sigma_sq, andphifor Gaussian fits. Spatial Polya-Gamma fits usesigma_sqandphi; optional beta starting values can be supplied in columns named like the fitted covariates.- tuning
Named proposal tuning vector on the transformed scale. Spatial fits use
log_tau_B_sq,log_sigma_sq, andz_phifor Gaussian fits. Spatial Polya-Gamma fits uselog_sigma_sqandz_phi. Non-spatial Polya-Gamma fits do not use a Metropolis tuning vector.- n_batch
Number of adaptive Metropolis batches.
- batch_length
Iterations per batch.
- accept_rate
Target acceptance rate.
- seed
Optional random seed.
- report
Batch reporting interval.
- n_threads
Optional number of OpenMP threads used by compiled covariance code. If
NULL, usesprep$n_threads.- verbose
Logical; if
TRUE, print sampler progress.- fit
A
"cos_fit"object.- burn_in
First retained iteration index.
- pars
Parameter names to summarize or plot.
- probs
Quantile probabilities.
- digits
Number of digits for rounded summaries.
Value
cos_fit() returns a list with class "cos_fit" containing
posterior samples and timing, a named numeric vector with user,
system, and elapsed seconds. The convenience function
cos_summary_theta() returns a parameter summary table. cos_plot_trace()
returns a ggplot2 object.
For Polya-Gamma fits, the returned object also contains
beta_samples, omega_B_samples, and eta_B_samples. These
are used directly by cos_recover_B().
Examples
if (FALSE) { # \dontrun{
library(sf)
library(raster)
library(ggplot2)
# Read the bundled example data.
chm <- raster(system.file("extdata", "example_chm.tif", package = "cosTapered"))
names(chm) <- "chm"
B_sf <- st_read(system.file("extdata", "example_B.gpkg",
package = "cosTapered"), quiet = TRUE)
truth <- readRDS(system.file("extdata", "example_truth.rds",
package = "cosTapered"))
# Users prepare the raster design matrix. Here we add an intercept layer.
intercept <- chm
intercept[] <- ifelse(is.na(getValues(chm)), NA_real_, 1)
names(intercept) <- "intercept"
X_rast <- stack(intercept, chm)
names(X_rast) <- c("intercept", "chm")
prep <- cos_prepare(
X_rast = X_rast,
B_sf = B_sf,
response_col = "y_B",
gamma = truth$gamma,
taper_code = truth$taper_code,
verbose = FALSE
)
priors <- cos_default_priors(
prep = prep,
beta_mu = c(intercept = 40, chm = 1),
beta_sd = c(intercept = 20, chm = 2),
tau_B_shape = 2,
tau_B_scale = truth$tau_B_sq_true,
sigma_shape = 2,
sigma_scale = truth$sigma_sq_true,
phi_lower = 3 / 600,
phi_upper = 3 / 80
)
fit <- cos_fit(
prep = prep,
priors = priors,
n_chains = 1,
starting = data.frame(
tau_B_sq = truth$tau_B_sq_true,
sigma_sq = truth$sigma_sq_true,
phi = truth$phi_true
),
tuning = c(log_tau_B_sq = 0.25, log_sigma_sq = 0.25, z_phi = 0.25),
n_batch = 50,
batch_length = 8,
seed = 1,
verbose = FALSE
)
summary(fit, burn_in = 100)
plot(fit, burn_in = 100)
# Compare posterior parameter samples with the known simulation values.
theta <- fit$theta_samples
theta <- theta[theta$iter >= 100, ]
theta_long <- reshape(
theta[, c("chain", "iter", "tau_B_sq", "sigma_sq", "phi", "eff_range")],
varying = c("tau_B_sq", "sigma_sq", "phi", "eff_range"),
v.names = "value",
timevar = "parameter",
times = c("tau_B_sq", "sigma_sq", "phi", "eff_range"),
direction = "long"
)
truth_df <- data.frame(
parameter = c("tau_B_sq", "sigma_sq", "phi", "eff_range"),
truth = c(truth$tau_B_sq_true, truth$sigma_sq_true,
truth$phi_true, truth$eff_range_true)
)
ggplot(theta_long, aes(x = value)) +
geom_density(fill = "grey80", color = "grey25", linewidth = 0.35) +
geom_vline(data = truth_df, aes(xintercept = truth),
color = "#c1121f", linewidth = 0.7) +
facet_wrap(~ parameter, scales = "free", ncol = 2) +
labs(title = "Posterior distributions and known simulation values",
x = NULL, y = NULL) +
theme_bw()
} # }