gpt4 book ai didi

rstudent() 为 "mlm"返回不正确的结果(装有多个 LHS 的线性模型)

转载 作者:行者123 更新时间:2023-12-02 08:11:47 25 4
gpt4 key购买 nike

我知道对具有多个 LHS 的线性模型的支持是有限的。但是当可以在“mlm”对象上运行一个函数时,我希望结果是可信的。使用 rstudent 时,会产生奇怪的结果。这是一个错误还是有其他解释?

在下面的示例中,fittedAfittedB 是相同的,但在 rstudent 的情况下,第二列不同。

y <- matrix(rnorm(20), 10, 2)
x <- 1:10
fittedA <- fitted(lm(y ~ x))
fittedB <- cbind(fitted(lm(y[, 1] ~ x)), fitted(lm(y[, 2] ~ x)))
rstudentA <- rstudent(lm(y ~ x))
rstudentB <- cbind(rstudent(lm(y[, 1] ~ x)), rstudent(lm(y[, 2] ~ x)))

最佳答案

设置

set.seed(0)
y <- matrix(rnorm(20), 10, 2)
x <- 1:10
fit <- lm(y ~ x) ## class: "mlm", "lm"
fit1 <- lm(y[, 1] ~ x) ## class: "lm"
fit2 <- lm(y[, 2] ~ x) ## class: "lm"

rstudent(fit)
# [,1] [,2]
#1 0.74417620 0.89121744
#2 -0.67506054 -0.50275275
#3 0.76297805 -0.74363941
#4 0.71164461 0.01075898
#5 0.03337192 0.03355209
#6 -1.75099724 -0.02701558
#7 -1.05594284 0.56993056
#8 -0.48486883 -0.35286612
#9 -0.23468552 0.79610101
#10 2.90701182 -0.93665406

cbind(rstudent(fit1), rstudent(fit2))
# [,1] [,2]
#1 0.74417620 1.90280959
#2 -0.67506054 -0.92973971
#3 0.76297805 -1.47237918
#4 0.71164461 0.01870820
#5 0.03337192 0.06042497
#6 -1.75099724 -0.04056992
#7 -1.05594284 1.02171222
#8 -0.48486883 -0.64316472
#9 -0.23468552 1.69605079
#10 2.90701182 -1.25676088

如您所见,rstandard(fit) 仅正确返回第一个响应的结果。


为什么 rstudent 在“mlm”上失败

问题是,rstudent 没有“mlm”方法。

methods(rstudent)
#[1] rstudent.glm* rstudent.lm*

当您调用 rstudent(fit) 时,S3 方法调度机制会找到 rstudent.lm,因为 inherits(fit, "lm")。不幸的是,stats:::rstudent.lm 没有对“mlm”模型进行正确的计算。

stats:::rstudent.lm
#function (model, infl = lm.influence(model, do.coef = FALSE),
# res = infl$wt.res, ...)
#{
# res <- res/(infl$sigma * sqrt(1 - infl$hat))
# res[is.infinite(res)] <- NaN
# res
#}

lm.influence 没有为“mlm”提供正确的 sigma。底层 C 例程 C_influence 仅计算“lm”的 sigma。如果您给 lm.influence 一个“mlm”,则只返回第一个响应变量的结果。

## pass in "mlm"
.Call(stats:::C_influence, fit$qr, FALSE, residuals(fit), 10 * .Machine$double.eps)$sigma
# [1] 1.3130265 1.3216357 1.3105706 1.3171621 1.3638689 1.1374385 1.2668101
# [8] 1.3416338 1.3586428 0.9180828

## pass in "lm"
.Call(stats:::C_influence, fit1$qr, FALSE, residuals(fit1), 10 * .Machine$double.eps)$sigma
# [1] 1.3130265 1.3216357 1.3105706 1.3171621 1.3638689 1.1374385 1.2668101
# [8] 1.3416338 1.3586428 0.9180828

显然,对于“mlm”,sigma 应该是一个矩阵。现在给出这个不正确的 sigma"recycling rule"应用在 stats:::rstudent.lm 下一行的 "/" 后面,因为它左边的 res(残差)是一个矩阵,但它右边的东西是一个向量。

res <- res / (infl$sigma * sqrt(1 - infl$hat))

实际上,计算结果只对第一个响应变量是正确的;所有其余响应变量都将使用错误的 sigma


R核心团队需要修补一些诊断功能

请注意,文档页面 ?influence.measures 中列出的几乎所有函数对于“mlm”都是错误的。他们应该发出警告说“传销”方法尚未实现。

lm.influnce 需要在 C 级打补丁。一旦完成,rstudent.lm 就会在“mlm”上正常工作。

其他函数可以很容易地在 R 级别进行修补,例如,stats:::cooks.distance.lmstats:::rstandard。目前 (R 3.5.1) 它们是:

stats:::cooks.distance.lm
#function (model, infl = lm.influence(model, do.coef = FALSE),
# res = weighted.residuals(model),
# sd = sqrt(deviance(model)/df.residual(model)),
# hat = infl$hat, ...)
#{
# p <- model$rank
# res <- ((res/(sd * (1 - hat)))^2 * hat)/p
# res[is.infinite(res)] <- NaN
# res
#}

stats:::rstandard.lm
#function (model, infl = lm.influence(model, do.coef = FALSE),
# sd = sqrt(deviance(model)/df.residual(model)), type = c("sd.1",
# "predictive"), ...)
#{
# type <- match.arg(type)
# res <- infl$wt.res/switch(type, sd.1 = sd * sqrt(1 - infl$hat),
# predictive = 1 - infl$hat)
# res[is.infinite(res)] <- NaN
# res
#}

并且它们可以被修补(通过使用outer)

patched_cooks.distance.lm <-
function (model, infl = lm.influence(model, do.coef = FALSE),
res = weighted.residuals(model),
sd = sqrt(deviance(model)/df.residual(model)),
hat = infl$hat, ...)
{
p <- model$rank
res <- ((res / c(outer(1 - hat, sd))) ^ 2 * hat) / p
res[is.infinite(res)] <- NaN
res
}

patched_rstandard.lm <-
function (model, infl = lm.influence(model, do.coef = FALSE),
sd = sqrt(deviance(model)/df.residual(model)), type = c("sd.1",
"predictive"), ...)
{
type <- match.arg(type)
res <- infl$wt.res/switch(type, sd.1 = c(outer(sqrt(1 - infl$hat), sd)),
predictive = 1 - infl$hat)
res[is.infinite(res)] <- NaN
res
}

快速测试:

oo <- cbind(cooks.distance(fit1), cooks.distance(fit2))  ## correct result
all.equal(cooks.distance(fit), oo)
#[1] "Mean relative difference: 0.8211302"
all.equal(patched_cooks.distance.lm(fit), oo)
#[1] TRUE

rr <- cbind(rstandard(fit1), rstandard(fit2)) ## correct result
all.equal(rstandard(fit), rr)
#[1] "Mean relative difference: 0.5290036"
all.equal(patched_rstandard.lm(fit), rr)
#[1] TRUE

关于rstudent() 为 "mlm"返回不正确的结果(装有多个 LHS 的线性模型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46234857/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com