You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取/复现R中smooth.spline底层使用的设计矩阵

问题

想了解如何获取或复现R中smooth.spline函数底层使用的设计矩阵,该函数没有返回此矩阵的途径。尝试用bs函数复现,但指定相同knots时,smooth.spline拟合的参数数量比bs生成的B样条矩阵列数少1,具体复现代码如下:

n = 200
y = rnorm(n=n)
x = runif(n=n)
knots = c(0,seq(0.001,0.999,.01),1)
mod = smooth.spline(x,y,all.knots=knots,keep.stuff=TRUE)

X = bs(x,knots=knots)

dim(X)[2] #105 
length(mod$fit$coef) #104
解答

为什么参数数量差1?

smooth.spline默认使用的是自然三次样条,而splines包中的bs函数默认生成的是普通三次B样条。自然三次样条会在两个边界点(你的例子里是0和1)施加二阶导数为0的约束,这会减少1个自由度,对应参数数量就少1个。

如何复现smooth.spline的设计矩阵?

直接用splines包中的ns函数(自然样条函数)即可,它生成的就是自然三次样条的设计矩阵,列数会和smooth.spline的参数数量完全匹配:

library(splines)
# ns函数不需要把边界点(0和1)传入knots参数,手动指定Boundary.knots更清晰
X_ns = ns(x, knots = seq(0.001,0.999,.01), Boundary.knots = c(0,1))
dim(X_ns)[2] # 结果为104,和length(mod$fit$coef)一致

如果一定要用bs函数手动构造,需要额外施加自然样条的约束,但这种方法繁琐且容易出错,更推荐直接用ns函数。

另外补充:当你给smooth.spline指定all.knots时,它本质是做带惩罚的自然样条拟合;如果设置spar=0让惩罚项趋近于0,拟合出的系数就是无惩罚自然样条的系数,此时ns生成的矩阵就是对应的训练矩阵。

内容的提问来源于stack exchange,提问作者curious_dan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 08:25:04