Fit4BS | R Documentation |
Fit 4 variants of penalized B-splines to noisy (x, y)
data simulated from g(x)
and compare their MSE performance under repeated simulations.
Fit4BS(x, y, k, m = 2, knots = NULL, domain = NULL, periodic = FALSE,
select = c("os", "sps", "nps", "gps"))
MSE4BS(x, g, k, m = 2, knots = NULL, domain = NULL, periodic = FALSE,
n2s.ratio = 0.2, n.sim = 100, nc = 1,
select = c("os", "sps", "nps", "gps"))
x , y |
|
g |
the true generative function |
k |
number of interior knots to place. This gives |
m |
penalty order. Can be 1, 2 or 3. |
knots |
a sequence of interior knots on which non-uniform B-splines are constructed for "os", "nps" and "gps" (see Details). Will be automatically placed at equal quantiles of |
domain |
a vector of two values giving domain interval |
periodic |
TRUE to fit a periodic spline; FALSE to fit an ordinary spline. |
n2s.ratio |
a noise-to-signal ratio that is used when simulating noisy |
n.sim |
number of simulations. |
nc |
number of CPU cores to use for parallel simulations. |
select |
a character vector giving names (see Details) of the variants to fit. |
The 4 variants of penalized B-splines are:
O-spline ("os"): non-uniform B-splines + derivative penalty;
standard P-spline ("sps"): uniform B-splines + standard difference penalty;
naive P-spline ("nps"): non-uniform B-splines + standard difference penalty;
general P-spline ("gps"): non-uniform B-splines + general difference penalty.
They are constructed with cubic B-splines on k
interior knots, penalized with an order-m
derivative or difference penalty. By default, quantile knots are placed automatically for "os", "nps" and "gps". But this can be overridden by user-specified interior knots through argument knots
.
A list of 4 fitted "gam" models, with components "os", "sps", "nps" and "gps". A component may be empty (with value NULL
) if it is excluded from select
.
Zheyuan Li zheyuan.li@bath.edu
Li, Z. and Cao, J. (2022). General P-Splines for Non-Uniform B-Splines.
## Not run:
require(mgcv)
require(gps.mgcv)
## a U-shaped curve
g <- function (x) abs(x) ^ 3 - 0.2 * x ^ 4
## number of data
n <- 400
## noise-to-signal ratio
n2s.ratio <- 0.4
## number of interior knots
k <- 40
## (x, y) data
x <- qnorm(seq.int(pnorm(-3), pnorm(3), length.out = n))
gx <- g(x)
y <- rnorm(length(gx), gx, n2s.ratio * sd(gx))
## fit 4 variants of penalized B-splines
fit <- Fit4BS(x, y, k)
## plot a fitted penalized B-spline against observed (x, y) data and true function g(x)
## gamfit: a fitted GAM model, should only have a single s(x) term of B-spline class
## x, y: observed (x, y) data
## g: the true function g(x)
PlotXYFit <- function (gamfit, x, y, g) {
## g must be a function
if (!is.function(g)) stop("g is not a function!")
## plot (x, y) data
plot(x, y, col = 8, ann = FALSE)
## observed x-values may not be evenly spaced
## to plot g(x), we'd better use evenly spaced x-values
nx <- length(x)
xg <- seq.int(min(x), max(x), length.out = nx)
lines(xg, g(xg), col = 2, lwd = 2)
## show knot location
abline(v = gamfit$smooth[[1]]$knots, lty = 2, col = 8)
## plot estimated f(x) at xg
yh <- predict(gamfit, newdata = data.frame(x = xg))
lines(xg, yh, lwd = 2)
}
## compare 4 variants of penalized B-splines
op <- par(no.readonly = TRUE)
layout(matrix(c(1, 2, 3, 4, 5, 5), nrow = 2))
par(mar = c(2, 2, 1.5, 0.5))
## O-spline
PlotXYFit(fit$os, x, y, g)
title("O-spline")
## standard P-spline
PlotXYFit(fit$sps, x, y, g)
title("standard P-spline")
## naive P-spline
PlotXYFit(fit$nps, x, y, g)
title("naive P-spline")
## general P-spline
PlotXYFit(fit$gps, x, y, g)
title("general P-spline")
## boxplot of MSE
mse <- MSE4BS(x, g, k = k, n2s.ratio = n2s.ratio, n.sim = 100, nc = 1)
boxplot(mse, main = "MSE (100 simulations)")
par(op)
## End(Not run)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.