我的问题是关于不必要的预测因子,即不提供任何新线性信息的变量或者是其他预测因子的线性组合的变量。如您所见,swiss
数据集有六个变量。
library(swiss)
names(swiss)
# "Fertility" "Agriculture" "Examination" "Education"
# "Catholic" "Infant.Mortality"
现在我介绍一个新变量ec
。它是Examination
和Education
的线性组合。
ec <- swiss$Examination + swiss$Catholic
当我们使用不必要的变量运行线性回归时,R会删除作为其他项的线性组合的项,并返回NA
作为它们的系数。下面的命令完美地说明了这一点。
lm(Fertility ~ . + ec, swiss)
Coefficients:
(Intercept) Agriculture Examination Education
66.9152 -0.1721 -0.2580 -0.8709
Catholic Infant.Mortality ec
0.1041 1.0770 NA
然而,当我们首先在ec
然后回归所有回归量时,如下所示:
lm(Fertility ~ ec + ., swiss)
Coefficients:
(Intercept) ec Agriculture Examination
66.9152 0.1041 -0.1721 -0.3621
Education Catholic Infant.Mortality
-0.8709 NA 1.0770
我希望Catholic
和Examination
的系数都为NA
。变量ec
是两者的线性组合,但最后Examination
的系数不是NA
,而Catholic
的系数是NA
。< / p>
有人可以解释原因吗?
答案 0 :(得分:5)
会有
NA
?
是。添加这些列不会扩大列空间。由此产生的矩阵缺乏等级。
多少
NA
?
这取决于数字等级。
number of NA = number of coefficients - rank of model matrix
在您的示例中,在介绍ec
后,会有一个NA
。更改模型公式中协变量的规范顺序基本上是对模型矩阵进行列重排。这不会改变矩阵等级,因此无论您的规范顺序如何,您始终只能获得一个NA
。
好的,但哪一个是
NA
?
lm
使用限制列旋转进行 LINPACK QR分解。协变量的顺序影响哪一个是NA
。通常,“first come,first served”原则成立,NA
的位置是可以预测的。以你的例子为例。在第一个规范中,这些共线项以Examination
,Catholic
,ec
顺序显示,因此第三个ec
具有NA
系数。在您的第二个规范中,这些字词以ec
,Examination
,Catholic
顺序显示,第三个Catholic
具有NA
系数。注意,系数估计对于规范顺序不是不变的,尽管拟合值是不变的。
如果 LAPACK 采用完整列旋转的QR分解,系数估计将对规范顺序不变。但是,NA
的位置不像 LINPACK 那样可预测,并且纯粹是用数字决定的。
基于LAPACK的QR分解在mgcv
包中实现。当使用REML估计时检测数字秩,并且将不可识别的系数报告为0(不是NA
)。因此,我们可以在线性模型估算中对lm
和gam
/ bam
进行比较。让我们首先构建一个玩具数据集。
set.seed(0)
# an initial full rank matrix
X <- matrix(runif(500 * 10), 500)
# make the last column as a random linear combination of previous 9 columns
X[, 10] <- X[, -10] %*% runif(9)
# a random response
Y <- rnorm(500)
现在我们对X
列进行随机播放,以查看NA
是否更改了lm
估算下的位置,或者0是否更改了gam
和bam
下的位置估计。
test <- function (fun = lm, seed = 0, ...) {
shuffleFit <- function (fun) {
shuffle <- sample.int(ncol(X))
Xs <- X[, shuffle]
b <- unname(coef(fun(Y ~ Xs, ...)))
back <- order(shuffle)
c(b[1], b[-1][back])
}
set.seed(seed)
oo <- t(replicate(10, shuffleFit(fun)))
colnames(oo) <- c("intercept", paste0("X", 1:ncol(X)))
oo
}
首先我们查看lm
:
test(fun = lm)
我们看到NA
通过X
的列重排改变了它的位置。估计的系数也不同。
现在我们查看gam
library(mgcv)
test(fun = gam, method = "REML")
我们发现估算对于X
的列重排是不变的,X5
的系数始终为0.
最后,我们检查bam
(bam
对于像这里的小型数据集来说速度很慢。它专为大型或超大型数据集而设计。所以下面的速度明显变慢了。
test(fun = bam, gc.level = -1)
结果与我们对gam
的结果相同。
答案 1 :(得分:3)