-
Notifications
You must be signed in to change notification settings - Fork 7
/
README.Rmd
104 lines (87 loc) · 4.14 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# aspline
<!-- badges: start -->
[![R-CMD-check](https://github.com/goepp/aspline/workflows/R-CMD-check/badge.svg)](https://github.com/goepp/aspline/actions)
[![](https://www.r-pkg.org/badges/version/aspline)](https://cran.r-project.org/package=aspline)
<!-- badges: end -->
## What are Adaptive Splines?
This package implements [A-Spline](https://arxiv.org/abs/1808.01770) regression, an adaptive procedure for fitting splines with automatic selection of the knots.
One-dimentional B-Splines of any non-negative degree can be fitted.
This method uses a penalization approach to compensate overfitting.
The penalty is proportional to the number of knots used to support the regression spline.
Consequently, the fitted splines will have knots only where necessary and the fitted model is sparser than comparable penalized spline regressions (for instance the standard method for penalized splines: [P-splines](https://doi.org/10.1214/ss/1038425655)).
## Installation
You can install the development version from [GitHub](https://github.com/) with:
``` r
# install.packages("devtools")
devtools::install_github("goepp/aspline")
```
## Example
Below is an illustration of the A-spline procedure using the [helmet](https://github.com/goepp/aspline/blob/master/data/helmet.rda) data.
The thick line represents the fitted spline and the thin line represents the B-spline basis decomposition of the fitted curve.
```{r}
library(aspline)
library(tidyverse)
library(splines2)
data(helmet)
x <- helmet$x
y <- helmet$y
k <- 40
knots <- seq(min(x), max(x), length = k + 2)[-c(1, k + 2)]
degree <- 3
pen <- 10 ^ seq(-4, 4, 0.25)
x_seq <- seq(min(x), max(x), length = 1000)
aridge <- aspline(x, y, knots, pen, degree = degree)
a_fit <- lm(y ~ bSpline(x, knots = aridge$knots_sel[[which.min(aridge$ebic)]],
degree = degree))
X_seq <- bSpline(x_seq, knots = aridge$knots_sel[[which.min(aridge$ebic)]],
intercept = TRUE, degree = degree)
a_basis <- (X_seq %*% diag(coef(a_fit))) %>%
as.data.frame() %>%
mutate(x = x_seq) %>%
reshape2::melt(id.vars = "x", variable.name = "spline_n", value.name = "y") %>%
as_tibble() %>%
filter(y != 0)
a_predict <- data_frame(x = x_seq, pred = predict(a_fit, data.frame(x = x_seq)))
ggplot() +
geom_point(data = helmet, aes(x, y), shape = 1) +
geom_line(data = a_predict, aes(x, pred), size = 0.5) +
geom_line(data = a_basis, aes(x, y, group = spline_n), linetype = 1, size = 0.1) +
theme(legend.position = "none") +
ylab("") +
xlab("")
```
For the sake of comparision, we display here the estimated P-spline with the same data.
The thin lines also represent the B-spline basis decomposition.
```{r}
p_fit <- mgcv::gam(y ~ s(x, bs = "ps", k = length(knots) + 3 + 1, m = c(3, 2)))
X <- bSpline(x_seq, knots = knots, intercept = TRUE)
p_basis <- (X %*% diag(coef(p_fit))) %>%
as.data.frame() %>%
mutate(x = x_seq) %>%
reshape2::melt(id.vars = "x", variable.name = "spline_n", value.name = "y") %>%
as_tibble() %>%
filter(y != 0)
p_predict <- data_frame(x = x_seq, pred = predict(p_fit, data.frame(x = x_seq)))
ggplot() +
geom_point(data = helmet, aes(x, y), shape = 1) +
geom_line(data = p_predict, aes(x, pred), size = 0.5) +
geom_line(data = p_basis, aes(x, y, group = spline_n), linetype = 1, size = 0.1) +
theme(legend.position = "none") +
ylab("") + xlab("")
```
## Contact
If you encounter a bug or have a suggestion for improvement, please [raise an issue](https://github.com/goepp/aspline/issues/new) or make a pull request.
## License
This package is released under the GPLv3 License: see the `LICENSE` file or the [online text](https://www.gnu.org/licenses/gpl-3.0.en.html). In [short](https://tldrlegal.com/license/gnu-general-public-license-v3-(gpl-3)#summary), you can use, modify, and distribute (including for commerical use) this package, with the notable obligations to use the GPLv3 license for your work and to provide a copy of the present source code.