cf_lm: Coarse-to-fine spatial modeling (CFSM) for Gaussian response

View source: R/cf_lm.R

cf_lmR Documentation

Coarse-to-fine spatial modeling (CFSM) for Gaussian response

Description

Scalable prediction, regression, and multiscale analysis via Gaussian CFSM.

Usage

cf_lm(
  y,
  x = NULL,
  coords,
  x0 = NULL,
  coords0 = NULL,
  mod_hv,
  robust_se = TRUE,
  se_type = c("prediction", "mean"),
  se_method = c("opt", "classic"),
  keep_scales = TRUE
)

Arguments

y

Vector of response variables (N x 1).

x

Matrix of covariates (N x K).

coords

Matrix of 2-dimensional point coordinates (N x 2).

x0

Optional. Matrix of covariates at prediction sites (N0 x K).

coords0

Optional. Matrix of 2-dimensional point coordinates at prediction sites (N0 x 2).

mod_hv

Output object of the cf_lm_hv function.

robust_se

If TRUE (default), coefficient standard errors and predictive uncertainty are computed using a cluster-robust sandwich estimator accounting for local spatial correlation. Set FALSE to use naive SEs (not recommended).

se_type

Type of predictive uncertainty in pred/pred_q. "prediction" (default) returns the holdout-calibrated OBSERVATION predictive (mean uncertainty + residual variance, split-conformal SD scaling on the cf_lm_hv validation samples); the signal versions are kept in pred_signal/pred_q_signal. "mean" returns the signal (mean) uncertainty only (previous behaviour).

se_method

Cluster-robust coefficient-SE estimator (used when robust_se = TRUE). "opt" (default) splits the sandwich meat into a field-removed observation-noise part and a field part that adds the calibrated field variance back with a within-block exp(-d/h) correlation (h = median committed bandwidth); this is near-nominal. For cf_lm the noise part is rescaled to a nugget (observation-noise variance) estimated from nearest-neighbour differences of the fixed-effect residuals, because the in-sample residual is shrunk by the fitted field. A refit-free leverage leave-one-out ceiling then caps the field term, preventing over-coverage for count (Poisson) responses while leaving already-calibrated families unchanged. "classic" keeps the realised field inside the working residual (the previous behaviour), which is valid but conservative.

keep_scales

If TRUE (default), the scale-wise processes Z, Z_sd, Z0 and Z0_sd are kept in the output. They hold one column per selected scale for every sample (and prediction) site, which makes them the largest part of the fitted object for large data. With FALSE they are dropped (NULL); predictions, standard errors, sd_summary and the maps of spCFmap for the total prediction are unchanged, but sp_scalewise needs them.

Details

The spatial-process predictive variance is bounded stage by stage: the calibrated variance of stage r is \min(\tau\, pv_r, \kappa s_r^2), where pv_r is the stage's predictive variance (infinite where no knot with data reaches the site), s_r^2 the variance of the stage's fitted field over the sample sites, and \kappa rescales the caps to sum to the marginal field variance. The holdout factor \tau solves the corresponding moment equation. The predictive SD thus grows smoothly with the distance to the data and reaches the marginal field variance far from it.

Value

A list with the following elements:

beta

Regression coefficients, their standard errors, and the lower and upper limits of the 95 percent confidence intervals.

sd_summary

Standard deviation of the regression term (xb), spatial processes (spatial_scale1, spatial_scale2,...), additional learned components (effective if 'cf_lm_hv/add_learn' is not 'none'), and residuals.

e_summary

Holdout validation accuracy evaluated on the validation samples: R-squared (validation_R2), root mean squared error (validation_RMSE), and mean absolute error (validation_MAE). validation_R2 is NA when the holdout predictions are constant (no covariates and no accepted scale).

pred

Predictive means and standard deviations (sample sites). When no additional learner is active, the spatial-process contribution to the predictive SD is rescaled by a holdout-calibrated factor (stored as other$tau) estimated on the validation samples.

pred0

Predictive means and standard deviations (prediction sites).

pred_q

Predictive quantiles at the sample sites (data.frame with columns q0.005, q0.025, ..., q0.975, q0.995). With add_learn = "rf"/"lightgbm" active, the combined predictive distribution is calibrated by total conformalized quantile regression (CQR) on the validation samples; otherwise the quantiles are Gaussian about the predictive mean using the (tau-calibrated) pred_sd. pred_sd is a Gaussian-equivalent summary of these quantiles. Not stored in the object: mod$pred_q computes it on access, at the 15 levels 0.005, 0.025, 0.05, 0.1, ..., 0.9, 0.95, 0.975, 0.995; predict.cf_lm gives them at other levels and at new sites.

pred0_q

Predictive quantiles at the prediction sites; identical column structure to pred_q. NULL when prediction sites are not supplied.

bands

Bandwidth values for each scale. The i-th bandwidth corresponding to the i-th column of the Z matrix.

Z

Predictive means of the single-scale processes at each scale, corresponding to each bandwidth value (sample sites; list).

Z_sd

Predictive standard deviation of the spatial processes at each scale (sample sites; list).

Z0

Predictive mean of the spatial process at each scale (prediction sites; list).

Z0_sd

Predictive standard deviation of the spatial process at each bandwidth (prediction sites; list). Z, Z_sd, Z0 and Z0_sd are NULL when keep_scales = FALSE.

other

Other internally used output objects.

Author(s)

Daisuke Murakami

References

Murakami, D., Comber, A., Yoshida, T., Tsutsumida, N., Brunsdon, C., & Nakaya, T. (2026). Coarse-to-fine spatial modeling: A scalable, machine-learning-compatible framework. *Geographical Analysis*, 58(2), e70034. https://onlinelibrary.wiley.com/doi/10.1111/gean.70034

See Also

cf_glm, cf_lm_hv, sp_scalewise

Examples

set.seed(123)
require(sp); require(sf)
data(meuse)
data(meuse.grid)

### Data
y        <- log(meuse[,"zinc"])
coords   <- meuse[,c("x","y")]
x        <- data.frame(dist   = meuse[,"dist"],
                       ffreq2 = as.integer(meuse$ffreq == 2),
                       ffreq3 = as.integer(meuse$ffreq == 3))

### Data at prediction sites
coords0  <- meuse.grid[,c("x","y")]
x0       <- data.frame(dist   = meuse.grid[,"dist"],
                       ffreq2 = as.integer(meuse.grid$ffreq == 2),
                       ffreq3 = as.integer(meuse.grid$ffreq == 3))

### Holdout validation optimizing the number of spatial scales
mod_hv   <- cf_lm_hv(y = y, x = x, coords = coords, add_learn = "none")

### Spatial modeling and prediction
mod      <- cf_lm(y = y, x = x, x0 = x0, coords = coords, coords0 = coords0,
                 mod_hv = mod_hv)
mod

### Mapping predictive mean and standard deviations (SD)
meuse.grid$pred   <- mod$pred0$pred
meuse.grid$pred_sd<- mod$pred0$pred_sd
meuse.grid_sf     <- st_as_sf(meuse.grid, coords = c("x","y"))
plot(meuse.grid_sf[,"pred"], pch = 15, cex = 0.5, nbreaks = 20)   # Predictive mean
plot(meuse.grid_sf[,"pred_sd"], pch = 15, cex = 0.5, nbreaks = 20)# Predictive SD

### Multiscale spatial pattern/feature extraction
mod_s1<- sp_scalewise(mod,bw_range=c(1000,Inf)) # Large scale (1000 <= bandwidth)
mod_s2<- sp_scalewise(mod,bw_range=c(500,1000)) # Middle scale (500 <= bandwidth <= 1000)
mod_s3<- sp_scalewise(mod,bw_range=c(0,500))    # Small scale (bandwidth <= 500)
z1    <- mod_s1$pred0$pred                      # Predictive mean
z2    <- mod_s2$pred0$pred
z3    <- mod_s3$pred0$pred
z1_sd <- mod_s1$pred0$pred_sd                   # Predictive SD
z2_sd <- mod_s2$pred0$pred_sd
z3_sd <- mod_s3$pred0$pred_sd
meuse.grid_sf3  <- cbind(meuse.grid_sf, z1, z2, z3, z1_sd, z2_sd, z3_sd)
plot(meuse.grid_sf3[,c("z1","z2","z3")], pch = 15,
     cex = 0.5, nbreaks = 20,key.pos=4,axes=TRUE) # Predictive means
plot(meuse.grid_sf3[,c("z1_sd","z2_sd","z3_sd")], pch = 15,
     cex = 0.5, nbreaks = 20,key.pos=4,axes=TRUE) # Predictive SD

### The same fit, explored interactively over a basemap
# spCFmap(mod, crs = 28992)   # crs = the system the coordinates are in

### Prediction with predict(): the model can be fitted WITHOUT prediction
### sites (no x0, coords0) and used to predict at any sites later; the
### training data are not needed then
mod_f    <- cf_lm(y = y, x = x, coords = coords, mod_hv = mod_hv)  # no x0, coords0
p        <- predict(mod_f, x0 = x0, coords0 = coords0, probs = c(0.025, 0.975))
head(p)                                   # pred, pred_sd, q0.025, q0.975
all.equal(p$pred, mod$pred0$pred)         # same as cf_lm(..., coords0 = coords0)
head(predict(mod_f, probs = c(0.1, 0.9))) # sample sites, 80 percent interval


spCF documentation built on Oct. 5, 2026, 5:07 p.m.