Logit模型预测的置信区间

Lm 根据线性回归的结果计算预测,并提供这些预测的置信区间。根据手册,这些区间是基于拟合的误差方差,而不是基于系数的误差区间。

另一方面,根据逻辑和泊松回归(以及其他一些方法)计算预测的 prett.glm 没有置信区间的选项。我甚至很难想象如何计算出这样的置信区间来为泊松和 Logit模型提供有意义的洞察力。

在有些情况下,为这种预测提供置信区间是否有意义?如何解读它们?这些案例的假设是什么?

64468 次浏览

通常的方法是在线性预测器的置信区间上计算一个置信区间,事情会变得更加正常(高斯) ,然后应用链接函数的逆向将线性预测器的尺度映射到响应尺度。

要做到这一点,你需要两件事;

  1. type = "link"调用 predict(),然后
  2. se.fit = TRUE呼叫 predict()

第一种方法在线性预测器的尺度上产生预测,第二种方法返回预测的标准误差。在伪代码中

## foo <- mtcars[,c("mpg","vs")]; names(foo) <- c("x","y") ## Working example data
mod <- glm(y ~ x, data = foo, family = binomial)
preddata <- with(foo, data.frame(x = seq(min(x), max(x), length = 100)))
preds <- predict(mod, newdata = preddata, type = "link", se.fit = TRUE)

然后,preds是一个包含组件 fitse.fit的列表。

线性预测器的置信区间是

critval <- 1.96 ## approx 95% CI
upr <- preds$fit + (critval * preds$se.fit)
lwr <- preds$fit - (critval * preds$se.fit)
fit <- preds$fit

critval是根据需要从 TZ(正常)分布中选择的(我现在完全忘记了使用哪种类型的 GLM 和属性是什么) ,并具有所需的覆盖率。1.96是正态分布的价值,覆盖率为95% :

> qnorm(0.975) ## 0.975 as this is upper tail, 2.5% also in lower tail
[1] 1.959964

现在对于 fituprlwr,我们需要对它们应用链接函数的逆函数。

fit2 <- mod$family$linkinv(fit)
upr2 <- mod$family$linkinv(upr)
lwr2 <- mod$family$linkinv(lwr)

现在您可以绘制所有三个和数据。

preddata$lwr <- lwr2
preddata$upr <- upr2
ggplot(data=foo, mapping=aes(x=x,y=y)) + geom_point() +
stat_smooth(method="glm", method.args=list(family=binomial)) +
geom_line(data=preddata, mapping=aes(x=x, y=upr), col="red") +
geom_line(data=preddata, mapping=aes(x=x, y=lwr), col="red")

enter image description here

我偶然发现刘文穗的 方法使用自举或模拟方法来解决泊松估计的问题。

来自作者的例子

pkgs <- c('doParallel', 'foreach')
lapply(pkgs, require, character.only = T)
registerDoParallel(cores = 4)
 

data(AutoCollision, package = "insuranceData")
df <- rbind(AutoCollision, AutoCollision)
mdl <- glm(Claim_Count ~ Age + Vehicle_Use, data = df, family = poisson(link = "log"))
new_fake <- df[1:5, 1:2]


boot_pi <- function(model, pdata, n, p) {
odata <- model$data
lp <- (1 - p) / 2
up <- 1 - lp
set.seed(2016)
seeds <- round(runif(n, 1, 1000), 0)
boot_y <- foreach(i = 1:n, .combine = rbind) %dopar% {
set.seed(seeds[i])
bdata <- odata[sample(seq(nrow(odata)), size = nrow(odata), replace = TRUE), ]
bpred <- predict(update(model, data = bdata), type = "response", newdata = pdata)
rpois(length(bpred), lambda = bpred)
}
boot_ci <- t(apply(boot_y, 2, quantile, c(lp, up)))
return(data.frame(pred = predict(model, newdata = pdata, type = "response"), lower = boot_ci[, 1], upper = boot_ci[, 2]))
}
 

boot_pi(mdl, new_fake, 1000, 0.95)


sim_pi <- function(model, pdata, n, p) {
odata <- model$data
yhat <- predict(model, type = "response")
lp <- (1 - p) / 2
up <- 1 - lp
set.seed(2016)
seeds <- round(runif(n, 1, 1000), 0)
sim_y <- foreach(i = 1:n, .combine = rbind) %dopar% {
set.seed(seeds[i])
sim_y <- rpois(length(yhat), lambda = yhat)
sdata <- data.frame(y = sim_y, odata[names(model$x)])
refit <- glm(y ~ ., data = sdata, family = poisson)
bpred <- predict(refit, type = "response", newdata = pdata)
rpois(length(bpred),lambda = bpred)
}
sim_ci <- t(apply(sim_y, 2, quantile, c(lp, up)))
return(data.frame(pred = predict(model, newdata = pdata, type = "response"), lower = sim_ci[, 1], upper = sim_ci[, 2]))
}
 

sim_pi(mdl, new_fake, 1000, 0.95)