簡體   English   中英

在 R 中擬合平滑樣條曲線(GAM 函數):擬合樣條曲線所需的結數誤差 - 結要求增加

[英]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 包gpsgps.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]]$xtgpsfit$smooth[[1]]$xt中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM