I am trying to fit a model with splines, and I’m struggling to understand what is happening. In brms, I have this model for some dummy data.
library(brms)
df <- data.frame(y = rnorm(10), x = 1:10)
fit_spline <- brm(y ~ s(x), df)
stancode(fit_spline)
standata(fit_spline)
// generated with brms 2.16.3
functions {
}
data {
int<lower=1> N; // total number of observations
vector[N] Y; // response variable
// data for splines
int Ks; // number of linear effects
matrix[N, Ks] Xs; // design matrix for the linear effects
// data for spline s(x)
int nb_1; // number of bases
int knots_1[nb_1]; // number of knots
// basis function matrices
matrix[N, knots_1[1]] Zs_1_1;
int prior_only; // should the likelihood be ignored?
}
transformed data {
}
parameters {
real Intercept; // temporary intercept for centered predictors
vector[Ks] bs; // spline coefficients
// parameters for spline s(x)
// standarized spline coefficients
vector[knots_1[1]] zs_1_1;
real<lower=0> sds_1_1; // standard deviations of spline coefficients
real<lower=0> sigma; // dispersion parameter
}
transformed parameters {
// actual spline coefficients
vector[knots_1[1]] s_1_1;
// compute actual spline coefficients
s_1_1 = sds_1_1 * zs_1_1;
}
model {
// likelihood including constants
if (!prior_only) {
// initialize linear predictor term
vector[N] mu = Intercept + rep_vector(0.0, N) + Xs * bs + Zs_1_1 * s_1_1;
target += normal_lpdf(Y | mu, sigma);
}
// priors including constants
target += student_t_lpdf(Intercept | 3, 0.3, 2.5);
target += student_t_lpdf(sds_1_1 | 3, 0, 2.5)
- 1 * student_t_lccdf(0 | 3, 0, 2.5);
target += std_normal_lpdf(zs_1_1);
target += student_t_lpdf(sigma | 3, 0, 2.5)
- 1 * student_t_lccdf(0 | 3, 0, 2.5);
}
generated quantities {
// actual population-level intercept
real b_Intercept = Intercept;
}
From the data section,
Xs is a vector of length N ranging from -0.126 to +0.126
Zs_1_1 is then a knots_1 x N (8x10) matrix of numbers in the range (-1, 1)
How has brms has done to calculate these, and what do they represent?
In standata(fit_splines) I also have a X variable, which isn’t in the Stan code. Is this being created extra by brms?