[英]Fitting a smooth spline (GAM function) in R: Error in number of knots required to fit spline -- knot requirements increasing
我正在嘗試將平滑樣條曲線擬合到看起來像具有兩個峰值的數據。 首先,我將平滑樣條曲線擬合到我的數據中,以識別結的潛在位置。
library(npreg)
library(splines)
library(mgcv)
x <- c(20.70, 20.44, 20.58, 21.02, 19.90, 6.20, 8.20, 6.92, 5.86, 6.44, 6.34, 8.48, 8.46, 9.00, 9.06, 9.00, 9.06, 17.98, 18.42, 19.18, 22.88, 24.16,20.20, 23.50)
y <- c(19.884208, 12.772114, 12.932944, 5.016790, 11.405843, 3.310724, 3.950049, 3.641571, 4.073783, 4.616096, 3.425635, 7.773548, 7.498084, 9.474213, 6.162779, 11.041210, 12.618555, 6.287967, 4.286919, 3.242361, 7.571644, 3.379709, 5.274434, 8.8258)
data = data.frame(x,y)
fit_spline <- smooth.spline(x,y)
plot(x,y)
lines(fit_spline,lwd=2,col="purple")
然后,我想使用 gam 函數進行回歸,我可以在其中指定結的位置。 我收到一個錯誤, Error in smooth.construct.bs.smooth.spec(object, dk$data, dk$knots) : there should be 7 supplied knots
我不確定它在哪里繪制這個數字。 如果我提供 7 節,它說它需要 13 節……並且重復相同的錯誤。 我不清楚如何進行。
myfit <- gam(y ~ s(x, bs = 'bs', k = 3),
knots = list(x = c(1,5,20)))
my_knots <- myfit$smooth[[1]]$xp
plot(x, y, col= "grey", main = "my knots");
lines(x, myfit$linear.predictors, col = 2, lwd = 2)
abline(v = my_knots, lty = 2)
看起來您來自我之前在 2016 年的回答之一: mgcv: How to set number and/or locations of k splines ,借用我的代碼片段:
my_knots <- myfit$smooth[[1]]$xp
plot(x, y, col= "grey", main = "my knots");
lines(x, myfit$linear.predictors, col = 2, lwd = 2)
abline(v = my_knots, lty = 2)
在那個答案中,我的演示是使用三次回歸樣條( bs = 'cr'
)進行的,其中結的位置很容易做到。 但是對於 B 樣條,事情就更復雜了。 因此,將此答案作為該答案的補充。
對於mgcv中的 B 樣條類,即'bs'
為“bs”( ?b.spline
)、“ps”( ?p.spline
)或“ad”( ?adaptive.smooth
),參數k
是數字B樣條的數量,而不是結的數量。 第一個帶回家的信息是: B 樣條的數量不等於結的數量。
B樣條的結放置是一項骯臟的工作。 通常您只指定k
並且mgcv會自動為您放置節點(例如,請參閱Extract knots, basic, coefficients and predictions for P-splines in Adaptive smooth )。 如果您想自己控制結的位置,您提供的結數必須與k
兼容。 如果您不太了解 B 樣條,這可能會引起很大的混亂。
我強烈建議您閱讀我的一項工作的附錄(第 33-34 頁): General P-splines for Non-uniform B-splines ,以了解 B-splines 的一些基本知識。 確保您了解什么是域、內部結和輔助邊界結。 在下文中,我將向您展示如何使用這些知識編寫正確的代碼。
以下是如何為您的示例放置結。
## degree of spline
deg <- 3
## domain
a <- min(x)
#[1] 5.86
b <- max(x)
#[1] 24.16
## interior knots (must be between a and b)
xs <- c(6, 20)
#[1] 6 20
## domain knots
xd <- c(a, xs, b)
#[1] 5.86 6.00 20.00 24.16
## clamped auxiliary boundary knots
left.aux <- rep(a, deg)
#[1] 5.86 5.86 5.86
right.aux <- rep(b, deg)
#[1] 24.16 24.16 24.16
## complete B-spline knots
my.knots <- c(left.aux, xd, right.aux)
#[1] 5.86 5.86 5.86 5.86 6.00 20.00 24.16 24.16 24.16 24.16
以下是如何為您的示例指定k
。
my.k <- length(xs) + deg + 1
#[1] 6
現在我們可以使用mgcv 了。
myfit <- gam(y ~ s(x, bs = 'bs', k = my.k),
knots = list(x = my.knots))
#Family: gaussian
#Link function: identity
#
#Formula:
#y ~ s(x, bs = "bs", k = my.k, m = deg)
#
#Estimated degrees of freedom:
#3.81 total = 4.81
您傳入的結存儲在這里(與my.knots
一致):
## For B-spline classes, knots are stored in $knots instead of $xp
myfit$smooth[[1]]$knots
#[1] 5.86 5.86 5.86 5.86 6.00 20.00 24.16 24.16 24.16 24.16
伴隨非均勻 B 樣條的通用 P 樣條是 R 包gps和gps.mgcv 。 后一個包為mgcv引入了一個新的“gps”類,其中bs = 'ps'
和bs = 'bs'
是bs = 'gps'
的特例。 新的“gps”類使結的放置更容易,因為它會自動為您放置輔助邊界結,您只需要提供內部結。
## The package stays on GitHub for the moment
## but will be on CRAN in the future.
## You may need to first install package 'devtools' from CRAN.
devtools::install_github("ZheyuanLi/gps")
devtools::install_github("ZheyuanLi/gps.mgcv")
library(gps.mgcv)
## as same as using 'bs = 'bs''
myfit <- gam(y ~ s(x, bs = 'gps', k = my.k, xt = list(derivative = TRUE)),
knots = list(x = xs)) ## provide interior knots
## the novel general P-spline
gpsfit <- gam(y ~ s(x, bs = 'gps', k = my.k),
knots = list(x = xs)) ## provide interior knots
構造信息(域、內部結等)存儲在myfit$smooth[[1]]$xt
和gpsfit$smooth[[1]]$xt
中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.