R函数bs()(B样条基矩阵)输出的解释
interpretation of the output of R function bs() (B-spline basis matrix)
我经常使用 B 样条进行回归。到目前为止,我从来不需要详细了解 bs
的输出:我只会选择我感兴趣的模型,然后用 lm
拟合它。但是,我现在需要在外部(非 R)代码中重现 b 样条模型。那么,bs
生成的矩阵是什么意思呢?示例:
x <- c(0.0, 11.0, 17.9, 49.3, 77.4)
bs(x, df = 3, degree = 1) # generate degree 1 (linear) B-splines with 2 internal knots
# 1 2 3
# [1,] 0.0000000 0.0000000 0.0000000
# [2,] 0.8270677 0.0000000 0.0000000
# [3,] 0.8198433 0.1801567 0.0000000
# [4,] 0.0000000 0.7286085 0.2713915
# [5,] 0.0000000 0.0000000 1.0000000
# attr(,"degree")
# [1] 1
# attr(,"knots")
# 33.33333% 66.66667%
# 13.30000 38.83333
# attr(,"Boundary.knots")
# [1] 0.0 77.4
# attr(,"intercept")
# [1] FALSE
# attr(,"class")
# [1] "bs" "basis" "matrix"
好的,所以 degree
是 1,正如我在输入中指定的那样。 knots
告诉我两个内部节点分别位于 x = 13.3000 和 x = 38.8333。看到节点处于固定分位数有点惊讶,我希望 R 能为我的数据找到最佳分位数,但当然这会使模型非线性,并且在不知道响应数据的情况下也是不可能的。 intercept = FALSE
表示基础中没有截距(这是一件好事吗?我一直被教导不要在没有截距的情况下拟合线性模型......好吧,我猜 lm
只是加了一个).
但是,矩阵呢?我真的不明白如何解释它。对于三列,我认为这意味着基函数是三个。这是有道理的:如果我有两个内部结 K1
和 K2
,我将在左边界结 B1
和 K1
之间有一个样条,在 [=20= 之间有另一个样条] 和 K2
,最后一个介于 K2
和 B2
之间,所以...三个基函数,好的。但是到底哪些是基函数呢?比如这个栏目是什么意思?
# 1
# [1,] 0.0000000
# [2,] 0.8270677
# [3,] 0.8198433
# [4,] 0.0000000
# [5,] 0.0000000
编辑:这与 . That question asks about the interpretation of the regression coefficients, but I'm a step before that: I would like to understand the meaning of the model matrix coefficients. If I try to make the same plots as suggested in 相似但不完全相同,我得到了一个混乱的情节:
b <- bs(x, df = 3, degree = 1)
b1 <- b[, 1] ## basis 1
b2 <- b[, 2] ## basis 2
b3 <- b[,3]
par(mfrow = c(1, 3))
plot(x, b1, type = "l", main = "basis 1: b1")
plot(x, b2, type = "l", main = "basis 2: b2")
plot(x, b3, type = "l", main = "basis 3: b3")
这些不能是 B 样条基函数,因为它们有太多结(每个函数应该只有一个)。
实际上允许我在 R 之外重建我的模型,所以我想我可以接受它。然而,这个答案也没有完全解释 b
矩阵的元素是什么:它处理线性回归的系数,我在这里还没有介绍。这确实是我的最终目标,但我也想了解这个中间步骤。
矩阵b
# 1 2 3
# [1,] 0.0000000 0.0000000 0.0000000
# [2,] 0.8270677 0.0000000 0.0000000
# [3,] 0.8198433 0.1801567 0.0000000
# [4,] 0.0000000 0.7286085 0.2713915
# [5,] 0.0000000 0.0000000 1.0000000
实际上只是 x
每个点的三个基函数值的矩阵,这对我来说应该是显而易见的,因为它与多项式线性模型的解释完全相同。事实上,由于边界节点是
bknots <- attr(b,"Boundary.knots")
# [1] 0.0 77.4
内部结是
iknots <- attr(b,"knots")
# 33.33333% 66.66667%
# 13.30000 38.83333
那么三个基函数,如图,是:
knots <- c(bknots[1],iknots,bknots[2])
y1 <- c(0,1,0,0)
y2 <- c(0,0,1,0)
y3 <- c(0,0,0,1)
par(mfrow = c(1, 3))
plot(knots, y1, type = "l", main = "basis 1: b1")
plot(knots, y2, type = "l", main = "basis 2: b2")
plot(knots, b3, type = "l", main = "basis 3: b3")
现在,考虑 b[,1]
# 1
# [1,] 0.0000000
# [2,] 0.8270677
# [3,] 0.8198433
# [4,] 0.0000000
# [5,] 0.0000000
这些必须是 x <- c(0.0, 11.0, 17.9, 49.3, 77.4)
中 b1
的值。事实上,b1
在knots[1] = 0
中为0,在knots[2] = 13.3000
中为1,也就是说在x[2]
(11.0)中该值必须为11/13.3 = 0.8270677
,如预期的。同样,由于 b1
对于 knots[3] = 38.83333
是 0,因此 x[3]
(17.9) 中的值必须是 (38.83333-13.3)/17.9 = 0.8198433
。因为 x[4], x[5] > knots[3] = 38.83333
,b1
在那里是 0。可以对其他两列给出类似的解释。
只是对上面@DeltaIV 的优秀答案的一个小修正(看来我无法发表评论。)
所以在b1
中,他计算b1(x[3])
的时候,通过线性插值应该是(38.83333-17.9)/(38.83333-13.3)=0.8198433
。其他一切都很完美。
注意 b1
应该是这样的
\frac{t}{13.3}I(0<=t<13.3)+\frac{38.83333-t}{38.83333-13.3}I(13.3<=t<38.83333)
我经常使用 B 样条进行回归。到目前为止,我从来不需要详细了解 bs
的输出:我只会选择我感兴趣的模型,然后用 lm
拟合它。但是,我现在需要在外部(非 R)代码中重现 b 样条模型。那么,bs
生成的矩阵是什么意思呢?示例:
x <- c(0.0, 11.0, 17.9, 49.3, 77.4)
bs(x, df = 3, degree = 1) # generate degree 1 (linear) B-splines with 2 internal knots
# 1 2 3
# [1,] 0.0000000 0.0000000 0.0000000
# [2,] 0.8270677 0.0000000 0.0000000
# [3,] 0.8198433 0.1801567 0.0000000
# [4,] 0.0000000 0.7286085 0.2713915
# [5,] 0.0000000 0.0000000 1.0000000
# attr(,"degree")
# [1] 1
# attr(,"knots")
# 33.33333% 66.66667%
# 13.30000 38.83333
# attr(,"Boundary.knots")
# [1] 0.0 77.4
# attr(,"intercept")
# [1] FALSE
# attr(,"class")
# [1] "bs" "basis" "matrix"
好的,所以 degree
是 1,正如我在输入中指定的那样。 knots
告诉我两个内部节点分别位于 x = 13.3000 和 x = 38.8333。看到节点处于固定分位数有点惊讶,我希望 R 能为我的数据找到最佳分位数,但当然这会使模型非线性,并且在不知道响应数据的情况下也是不可能的。 intercept = FALSE
表示基础中没有截距(这是一件好事吗?我一直被教导不要在没有截距的情况下拟合线性模型......好吧,我猜 lm
只是加了一个).
但是,矩阵呢?我真的不明白如何解释它。对于三列,我认为这意味着基函数是三个。这是有道理的:如果我有两个内部结 K1
和 K2
,我将在左边界结 B1
和 K1
之间有一个样条,在 [=20= 之间有另一个样条] 和 K2
,最后一个介于 K2
和 B2
之间,所以...三个基函数,好的。但是到底哪些是基函数呢?比如这个栏目是什么意思?
# 1
# [1,] 0.0000000
# [2,] 0.8270677
# [3,] 0.8198433
# [4,] 0.0000000
# [5,] 0.0000000
编辑:这与
b <- bs(x, df = 3, degree = 1)
b1 <- b[, 1] ## basis 1
b2 <- b[, 2] ## basis 2
b3 <- b[,3]
par(mfrow = c(1, 3))
plot(x, b1, type = "l", main = "basis 1: b1")
plot(x, b2, type = "l", main = "basis 2: b2")
plot(x, b3, type = "l", main = "basis 3: b3")
这些不能是 B 样条基函数,因为它们有太多结(每个函数应该只有一个)。
b
矩阵的元素是什么:它处理线性回归的系数,我在这里还没有介绍。这确实是我的最终目标,但我也想了解这个中间步骤。
矩阵b
# 1 2 3
# [1,] 0.0000000 0.0000000 0.0000000
# [2,] 0.8270677 0.0000000 0.0000000
# [3,] 0.8198433 0.1801567 0.0000000
# [4,] 0.0000000 0.7286085 0.2713915
# [5,] 0.0000000 0.0000000 1.0000000
实际上只是 x
每个点的三个基函数值的矩阵,这对我来说应该是显而易见的,因为它与多项式线性模型的解释完全相同。事实上,由于边界节点是
bknots <- attr(b,"Boundary.knots")
# [1] 0.0 77.4
内部结是
iknots <- attr(b,"knots")
# 33.33333% 66.66667%
# 13.30000 38.83333
那么三个基函数,如图
knots <- c(bknots[1],iknots,bknots[2])
y1 <- c(0,1,0,0)
y2 <- c(0,0,1,0)
y3 <- c(0,0,0,1)
par(mfrow = c(1, 3))
plot(knots, y1, type = "l", main = "basis 1: b1")
plot(knots, y2, type = "l", main = "basis 2: b2")
plot(knots, b3, type = "l", main = "basis 3: b3")
现在,考虑 b[,1]
# 1
# [1,] 0.0000000
# [2,] 0.8270677
# [3,] 0.8198433
# [4,] 0.0000000
# [5,] 0.0000000
这些必须是 x <- c(0.0, 11.0, 17.9, 49.3, 77.4)
中 b1
的值。事实上,b1
在knots[1] = 0
中为0,在knots[2] = 13.3000
中为1,也就是说在x[2]
(11.0)中该值必须为11/13.3 = 0.8270677
,如预期的。同样,由于 b1
对于 knots[3] = 38.83333
是 0,因此 x[3]
(17.9) 中的值必须是 (38.83333-13.3)/17.9 = 0.8198433
。因为 x[4], x[5] > knots[3] = 38.83333
,b1
在那里是 0。可以对其他两列给出类似的解释。
只是对上面@DeltaIV 的优秀答案的一个小修正(看来我无法发表评论。)
所以在b1
中,他计算b1(x[3])
的时候,通过线性插值应该是(38.83333-17.9)/(38.83333-13.3)=0.8198433
。其他一切都很完美。
注意 b1
应该是这样的
\frac{t}{13.3}I(0<=t<13.3)+\frac{38.83333-t}{38.83333-13.3}I(13.3<=t<38.83333)