Інтервали довіри прогнозів для нелінійної змішаної моделі (nlme)


12

Я хотів би отримати 95% довірчі інтервали для прогнозів нелінійної змішаної nlmeмоделі. Оскільки для цього не передбачено нічого стандартного nlme, мені було цікаво, чи правильно використовувати метод "інтервалів прогнозування населення", як це викладено в книзі книги Бен Болкер в контексті моделей, що відповідають максимальній вірогідності , заснованих на ідеї перекомпонування параметрів фіксованого ефекту на основі дисперсійно-коваріаційної матриці пристосованої моделі, імітуючи прогнози на основі цього, а потім приймаючи 95% відсотків цих прогнозів, щоб отримати 95% довірчі інтервали?

Код для цього виглядає так: (я тут використовую дані "Loblolly" з nlmeдовідкового файлу)

library(effects)
library(nlme)
library(MASS)

fm1 <- nlme(height ~ SSasymp(age, Asym, R0, lrc),
    data = Loblolly,
    fixed = Asym + R0 + lrc ~ 1,
    random = Asym ~ 1,
    start = c(Asym = 103, R0 = -8.5, lrc = -3.3))

xvals=seq(min(Loblolly$age),max(Loblolly$age),length.out=100)
nresamp=1000
pars.picked = mvrnorm(nresamp, mu = fixef(fm1), Sigma = vcov(fm1)) # pick new parameter values by sampling from multivariate normal distribution based on fit
yvals = matrix(0, nrow = nresamp, ncol = length(xvals))

for (i in 1:nresamp) 
{
    yvals[i,] = sapply(xvals,function (x) SSasymp(x,pars.picked[i,1], pars.picked[i,2], pars.picked[i,3]))
} 

quant = function(col) quantile(col, c(0.025,0.975)) # 95% percentiles
conflims = apply(yvals,2,quant) # 95% confidence intervals

Тепер, коли я маю свої межі довіри, я створюю графік:

meany = sapply(xvals,function (x) SSasymp(x,fixef(fm1)[[1]], fixef(fm1)[[2]], fixef(fm1)[[3]]))

par(cex.axis = 2.0, cex.lab=2.0)
plot(0, type='n', xlim=c(3,25), ylim=c(0,65), axes=F, xlab="age", ylab="height");
axis(1, at=c(3,1:5 * 5), labels=c(3,1:5 * 5)) 
axis(2, at=0:6 * 10, labels=0:6 * 10)   

for(i in 1:14)
{
    data = subset(Loblolly, Loblolly$Seed == unique(Loblolly$Seed)[i])   
    lines(data$age, data$height, col = "red", lty=3)
}

lines(xvals,meany, lwd=3)
lines(xvals,conflims[1,])
lines(xvals,conflims[2,])

Ось сюжет із 95% довірчими інтервалами, отриманими таким чином:

Усі дані (червоні лінії), засоби та межі довіри (чорні лінії)

Чи підходить цей підхід, чи існують інші чи кращі підходи для розрахунку 95% довірчих інтервалів за прогнозами нелінійної змішаної моделі? Я не зовсім впевнений, як боротися зі структурою випадкових ефектів моделі ... Чи повинен бути середній показник, можливо, за рівнем випадкових ефектів? Або було б нормально мати інтервали довіри для середнього предмета, які, здавалося б, ближче до того, що я маю зараз?


Тут не виникає питання. Будьте зрозумілі, про що ви питаєте.
adunaic

Я спробував сформулювати питання точніше зараз ...
Піт ван ден Берг

Як я вже коментував, коли ви запитували це раніше про переповнення стека, я не переконаний, що припущення про нормальність для нелінійних параметрів є виправданим.
Роланд

Я не читав книги Бена, але він, схоже, не посилається на змішані моделі в цій главі. Можливо, вам слід уточнити це, посилаючись на його книгу.
Роланд

Так, це було в контексті моделей з максимальною вірогідністю, але ідея повинна бути такою ж ... Я вже зараз це уточнив ...
Piet van den Berg

Відповіді:


10

Те, що ви тут зробили, виглядає розумним. Коротка відповідь полягає в тому, що здебільшого питання прогнозування довірчих інтервалів від змішаних моделей та від нелінійних моделей є більш-менш ортогональними , тобто потрібно турбуватися про обидва набори проблем, але вони не мають (що я знаю ) взаємодіяти будь-якими дивними способами.

  • Проблеми змішаної моделі : ви намагаєтесь передбачити на рівні населення чи групи? Як ви враховуєте мінливість параметрів випадкових ефектів? Ви обумовлюєтесь спостереженнями на рівні групи чи ні?
  • Проблеми з нелінійною моделлю : чи нормальне розподіл вибірки параметрів? Як я можу пояснити нелінійність під час поширення помилки?

Я вважаю, що ви прогнозуєте на рівні населення та будуєте інтервали довіри як рівень населення - іншими словами, ви намагаєтеся побудувати прогнозовані значення типової групи, не враховуючи різницю між групами у вашій впевненості інтервали. Це спрощує проблеми зі змішаною моделлю. На наступних графіках порівнюються три підходи (див. Нижче для скидання коду):

  • Інтервали прогнозування кількості населення : це підхід, який ви спробували вище. Він передбачає, що модель правильна і що розподіли вибірки параметрів фіксованого ефекту є багатоваріантними нормальними; він також ігнорує невизначеність параметрів випадкових ефектів
  • завантажувальна програма : я реалізував ієрархічну завантажувальну систему; ми поновлюємо вибір як на рівні груп, так і всередині груп. Відбір проб всередині групи відбирає залишки та додає їх до прогнозів. Такий підхід робить найменшими припущення.
  • дельта-метод : це передбачає як багатоваріантну нормальність розподілу вибірки, так і те, що нелінійність є досить слабкою, щоб дозволити наближення другого порядку.

Ми також могли б зробити параметричне завантаження ...

Ось КІ, накреслені разом із даними ...

введіть тут опис зображення

... але ми навряд чи можемо побачити відмінності.

Збільшення масштабу за рахунок віднімання прогнозованих значень (червоний = завантажувальний, синій = ІПП, синій = метод дельти)

введіть тут опис зображення

У цьому випадку інтервали завантаження фактично є найвужчими (наприклад, імовірно, розподіл вибірки параметрів насправді трохи тонше хвостовий, ніж нормальний), в той час як інтервали ІПП та дельта-методу дуже схожі між собою.

library(nlme)
library(MASS)

fm1 <- nlme(height ~ SSasymp(age, Asym, R0, lrc),
            data = Loblolly,
            fixed = Asym + R0 + lrc ~ 1,
            random = Asym ~ 1,
            start = c(Asym = 103, R0 = -8.5, lrc = -3.3))

xvals <-  with(Loblolly,seq(min(age),max(age),length.out=100))
nresamp <- 1000
## pick new parameter values by sampling from multivariate normal distribution based on fit
pars.picked <- mvrnorm(nresamp, mu = fixef(fm1), Sigma = vcov(fm1))

## predicted values: useful below
pframe <- with(Loblolly,data.frame(age=xvals))
pframe$height <- predict(fm1,newdata=pframe,level=0)

## utility function
get_CI <- function(y,pref="") {
    r1 <- t(apply(y,1,quantile,c(0.025,0.975)))
    setNames(as.data.frame(r1),paste0(pref,c("lwr","upr")))
}

set.seed(101)
yvals <- apply(pars.picked,1,
               function(x) { SSasymp(xvals,x[1], x[2], x[3]) }
)
c1 <- get_CI(yvals)

## bootstrapping
sampfun <- function(fitted,data,idvar="Seed") {
    pp <- predict(fitted,levels=1)
    rr <- residuals(fitted)
    dd <- data.frame(data,pred=pp,res=rr)
    ## sample groups with replacement
    iv <- levels(data[[idvar]])
    bsamp1 <- sample(iv,size=length(iv),replace=TRUE)
    bsamp2 <- lapply(bsamp1,
        function(x) {
        ## within groups, sample *residuals* with replacement
        ddb <- dd[dd[[idvar]]==x,]
        ## bootstrapped response = pred + bootstrapped residual
        ddb$height <- ddb$pred +
            sample(ddb$res,size=nrow(ddb),replace=TRUE)
        return(ddb)
    })
    res <- do.call(rbind,bsamp2)  ## collect results
    if (is(data,"groupedData"))
        res <- groupedData(res,formula=formula(data))
    return(res)
}

pfun <- function(fm) {
    predict(fm,newdata=pframe,level=0)
}

set.seed(101)
yvals2 <- replicate(nresamp,
                    pfun(update(fm1,data=sampfun(fm1,Loblolly,"Seed"))))
c2 <- get_CI(yvals2,"boot_")

## delta method
ss0 <- with(as.list(fixef(fm1)),SSasymp(xvals,Asym,R0,lrc))
gg <- attr(ss0,"gradient")
V <- vcov(fm1)
delta_sd <- sqrt(diag(gg %*% V %*% t(gg)))
c3 <- with(pframe,data.frame(delta_lwr=height-1.96*delta_sd,
                             delta_upr=height+1.96*delta_sd))

pframe <- data.frame(pframe,c1,c2,c3)

library(ggplot2); theme_set(theme_bw())
ggplot(Loblolly,aes(age,height))+
    geom_line(alpha=0.2,aes(group=Seed))+
    geom_line(data=pframe,col="red")+
    geom_ribbon(data=pframe,aes(ymin=lwr,ymax=upr),colour=NA,alpha=0.3,
                fill="blue")+
    geom_ribbon(data=pframe,aes(ymin=boot_lwr,ymax=boot_upr),
                colour=NA,alpha=0.3,
                fill="red")+
    geom_ribbon(data=pframe,aes(ymin=delta_lwr,ymax=delta_upr),
                colour=NA,alpha=0.3,
                fill="cyan")


ggplot(Loblolly,aes(age))+
    geom_hline(yintercept=0,lty=2)+
    geom_ribbon(data=pframe,aes(ymin=lwr-height,ymax=upr-height),
                colour="blue",
                fill=NA)+
    geom_ribbon(data=pframe,aes(ymin=boot_lwr-height,ymax=boot_upr-height),
                colour="red",
                fill=NA)+
    geom_ribbon(data=pframe,aes(ymin=delta_lwr-height,ymax=delta_upr-height),
                colour="cyan",
                fill=NA)

Тож якщо я правильно розумію, це будуть інтервали довіри для типової групи. Чи маєте ви також уявлення про те, як можна було б включати зміни між групами у ваші інтервали довіри? Чи повинен тоді середній показник перевищувати рівні випадкових ефектів?
Tom Wenseleers
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.