Take for instance the following one-knot, degree two, spline:
library(splines)
library(ISLR)
fit.spline <- lm(wage~bs(age, knots=c(42), degree=2), data=Wage)
summary(fit.spline)
I see estimates that I don't expect.
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 57.349 3.950 14.518 < 2e-16 ***
bs(age, knots = c(42), degree = 2)1 59.511 5.786 10.285 < 2e-16 ***
bs(age, knots = c(42), degree = 2)2 65.722 4.076 16.122 < 2e-16 ***
bs(age, knots = c(42), degree = 2)3 37.170 9.722 3.823 0.000134 ***
Is there a way to extract the quadratic model (and its coefficients) for before and after the knot? That is, how can I extract the two quadratic models before and after the cut point of age = 42
?
Using summary(fit.spline)
yields coefficients, but (to my understanding) they are not meaningful for interpretation.
In mathematics, a spline is a special function defined piecewise by polynomials. In interpolating problems, spline interpolation is often preferred to polynomial interpolation because it yields similar results, even when using low degree polynomials, while avoiding Runge's phenomenon for higher degrees.
Spline regression modeling looks for points in the data that would indicate where changes occur. These. points are referred to as “knots.” Spline regression models provide a means of capturing these changes smoothly. and joining the segments without the usual “break” between the segments.
Linear splines allow estimating the relationship between y and x as a piecewise linear function, which is a function composed of linear segments—straight lines.
Cubic regression spline is a form of generalized linear models in regression analysis. Also known as B-spline, it is supported by a series of interior basis functions on the interval with chosen knots. Cubic regression splines are widely used on modeling nonlinear data and interaction between variables.
I was constantly asked to wrap up the idea in my original answer into a user-friendly function, able to reparametrize a fitted linear or generalized linear model with a bs
or ns
term. Eventually I rolled out a small R package SplinesUtils
at https://github.com/ZheyuanLi/SplinesUtils (with a PDF version package manual). You can install it via
## make sure you have the `devtools` package avaiable
devtools::install_github("ZheyuanLi/SplinesUtils")
The function to be used here is RegBsplineAsPiecePoly
.
library(SplinesUtils)
library(splines)
library(ISLR)
fit.spline <- lm(wage ~ bs(age, knots=c(42), degree=2), data = Wage)
ans1 <- RegBsplineAsPiecePoly(fit.spline, "bs(age, knots = c(42), degree = 2)")
ans1
#2 piecewise polynomials of degree 2 are constructed!
#Use 'summary' to export all of them.
#The first 2 are printed below.
#8.2e-15 + 4.96 * (x - 18) + 0.0991 * (x - 18) ^ 2
#61.9 + 0.2 * (x - 42) + 0.0224 * (x - 42) ^ 2
## coefficients as a matrix
ans1$PiecePoly$coef
# [,1] [,2]
#[1,] 8.204641e-15 61.91542748
#[2,] 4.959286e+00 0.20033307
#[3,] -9.914485e-02 -0.02240887
## knots
ans1$knots
#[1] 18 42 80
The function defaults to parametrize piecewise polynomials in shifted form (see ?PiecePoly
). You can set shift = FALSE
for a non-shifted version.
ans2 <- RegBsplineAsPiecePoly(fit.spline, "bs(age, knots = c(42), degree = 2)",
shift = FALSE)
ans2
#2 piecewise polynomials of degree 2 are constructed!
#Use 'summary' to export all of them.
#The first 2 are printed below.
#-121 + 8.53 * x + 0.0991 * x ^ 2
#14 + 2.08 * x + 0.0224 * x ^ 2
## coefficients as a matrix
ans2$PiecePoly$coef
# [,1] [,2]
#[1,] -121.39007747 13.97219046
#[2,] 8.52850050 2.08267822
#[3,] -0.09914485 -0.02240887
You can predict the splines with predict
.
xg <- 18:80
yg1 <- predict(ans1, xg) ## use shifted form
yg2 <- predict(ans2, xg) ## use non-shifted form
all.equal(yg1, yg2)
#[1] TRUE
But since there is an intercept in the model, the predicted values would differ from model prediction by the intercept.
yh <- predict(fit.spline, data.frame(age = xg))
intercept <- coef(fit.spline)[[1]]
all.equal(yh, yg1 + intercept, check.attributes = FALSE)
#[1] TRUE
The package has summary
, print
, plot
, predict
and solve
methods for a "PiecePoly" class. Explore the package for more.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With