R'deki lmer () karışık etki modeli için tahmin aralığı


37

Bir lmer () modelinden bir tahmin çevresinde bir tahmin aralığı almak istiyorum. Bununla ilgili bazı tartışmalar buldum:

http://rstudio-pubs-static.s3.amazonaws.com/24365_2803ab8299934e888a60e7b16113f619.html

http://glmm.wikidot.com/faq

fakat rastgele etkilerin belirsizliğini hesaba katmamış gibi görünüyorlar.

İşte özel bir örnek. Altın balıkla yarışıyorum. Son 100 yarış hakkında verilerim var. RE tahminlerimin ve FE tahminlerinin belirsizliğini dikkate alarak 101'ini tahmin etmek istiyorum. Balık için rastgele bir engelleme (10 farklı balık var) ve ağırlık için sabit etki (daha az ağır balık daha hızlı) içermektedir.

library("lme4")

fish <- as.factor(rep(letters[1:10], each=100))
race <- as.factor(rep(900:999, 10))
oz <- round(1 + rnorm(1000)/10, 3)
sec <- 9 + rep(1:10, rep(100,10))/10 + oz + rnorm(1000)/10

fishDat <- data.frame(fishID = fish, 
      raceID = race, fishWt = oz, time = sec)
head(fishDat)
plot(fishDat$fishID, fishDat$time)

lme1 <- lmer(time ~ fishWt + (1 | fishID), data=fishDat)
summary(lme1)

Şimdi, 101'inci yarışı tahmin etmek için. Balıklar tartıldı ve gitmeye hazır:

newDat <- data.frame(fishID = letters[1:10], 
    raceID = rep(1000, 10),
    fishWt = 1 + round(rnorm(10)/10, 3))
newDat$pred <- predict(lme1, newDat)
newDat

   fishID raceID fishWt     pred
1       a   1000  1.073 10.15348
2       b   1000  1.001 10.20107
3       c   1000  0.945 10.25978
4       d   1000  1.110 10.51753
5       e   1000  0.910 10.41511
6       f   1000  0.848 10.44547
7       g   1000  0.991 10.68678
8       h   1000  0.737 10.56929
9       i   1000  0.993 10.89564
10      j   1000  0.649 10.65480

Balık D gerçekten kendini bıraktı (1.11 oz) ve aslında her ikisi de geçmişte olduğundan daha iyi olan Balık E ve Balık F'ye kaybedeceği tahmin ediliyor. Ancak şimdi şunu söyleyebilirim ki, "Balık E (0.91 oz ağırlığında) Balık D'yi (1.11 oz ağırlığında) p olasılıkla yenecek." Lme4 kullanarak böyle bir açıklama yapmanın bir yolu var mı? Olasılığımın hem sabit hem de rastgele etkideki belirsizliğimi dikkate almasını istiyorum.

Teşekkürler!

PS predict.merModbelgelere bakarak, "Standart tahmin hatalarını hesaplama seçeneği yoktur, çünkü varyans parametrelerinde belirsizlik içeren etkin bir yöntem tanımlamak zordur; bootMerbu görevi tavsiye ederiz " ama golly, göremiyorum bootMerBunu yapmak için nasıl kullanılacağını . bootMerParametre tahminleri için önyüklemeli güven aralıklarını almak için kullanılacağı görülüyor , fakat yanılıyor olabilirim.

GÜNCELLEME S:

Tamam, sanırım yanlış soruyu soruyordum. "Balık A, ağırlığında, zamanın% 90'ı (lcl, ucl) olan bir yarış süresine sahip olacak" diyebilmek istiyorum.

Belirttiğim örnekte, 1.0 oz ağırlığındaki Fish A 9 + 0.1 + 1 = 10.1 secortalama olarak 0.1 standart sapma ile yarış süresine sahip olacak . Böylece, onun gözlenen yarış süresi arasında olacak

x <- rnorm(mean = 10.1, sd = 0.1, n=10000)
quantile(x, c(0.05,0.50,0.95))
       5%       50%       95% 
 9.938541 10.100032 10.261243 

Zamanın% 90'ı. Bana bu cevabı vermeye çalışan bir tahmin fonksiyonu istiyorum. Bütün Ayar fishWt = 1.0in newDat, yeniden çalıştırmayı (aşağıda Ben Bolker önerdiği gibi) sim ve kullanma

predFun <- function(fit) {
  predict(fit,newDat)
}
bb <- bootMer(lme1,nsim=1000,FUN=predFun, use.u = FALSE)
predMat <- bb$t

verir

> quantile(predMat[,1], c(0.05,0.50,0.95))
      5%      50%      95% 
10.01362 10.55646 11.05462 

Bu aslında nüfus ortalamasının etrafında toplanmış gibi görünüyor? FishID etkisini hesaba katmıyormuş gibi? Bunun bir örneklem büyüklüğü olabileceğini düşündüm, ancak gözlenen yarış sayısını 100'den 10000'e çıkardığımda, yine de benzer sonuçlar elde ediyorum.

Varsayılan olarak bootMerkullanımları not edeceğim use.u=FALSE. Kapak tarafında, kullanarak

bb <- bootMer(lme1,nsim=1000,FUN=predFun, use.u = TRUE)

verir

> quantile(predMat[,1], c(0.05,0.50,0.95))
      5%      50%      95% 
10.09970 10.10128 10.10270 

Bu aralık çok dar ve Fish A'nın ortalama zamanı için bir güven aralığı gibi görünüyor. Fish A'in gözlemlediği yarış süresi için ortalama yarış süresi değil, güven aralığı istiyorum. Bunu nasıl alabilirim?

GÜNCELLEME 2, NEDEN:

Ben düşündüm ben de aradığımı buldum Gelman ve Tepesi (2007) , kullanma sayfa 273. Muhtaç armpaketi.

library("arm")

Balık A için:

x.tilde <- 1    #observed fishWt for new race
sigma.y.hat <- sigma.hat(lme1)$sigma$data        #get uncertainty estimate of our model
coef.hat <- as.matrix(coef(lme1)$fishID)[1,]    #get intercept (random) and fishWt (fixed) parameter estimates
y.tilde <- rnorm(1000, coef.hat %*% c(1, x.tilde), sigma.y.hat) #simulate
quantile (y.tilde, c(.05, .5, .95))

  5%       50%       95% 
 9.930695 10.100209 10.263551 

Tüm balıklar için:

x.tilde <- rep(1,10)  #assume all fish weight 1 oz
#x.tilde <- 1 + rnorm(10)/10  #alternatively, draw random weights as in original example
sigma.y.hat <- sigma.hat(lme1)$sigma$data
coef.hat <- as.matrix(coef(lme1)$fishID)
y.tilde <- matrix(rnorm(1000, coef.hat %*% matrix(c(rep(1,10), x.tilde), nrow = 2 , byrow = TRUE), sigma.y.hat), ncol = 10, byrow = TRUE)
quantile (y.tilde[,1], c(.05, .5, .95))
       5%       50%       95% 
 9.937138 10.102627 10.234616 

Aslında bu muhtemelen istediğim şey değil. Ben sadece genel model belirsizliğini dikkate alıyorum. Diyelim ki, 5 balık K için gözlenen, 1000 balık L için gözlenen ırklar olduğu bir durumda, Balık K için öngördüğüm ile ilgili belirsizliğin, Balık L için yaptığım belirsizlikten daha büyük olması gerektiğini düşünüyorum.

Gelman ve Hill 2007'ye daha fazla bakacak. BUGS'a (veya Stan) geçmek zorunda kalacağımı hissediyorum.

GÜNCELLEME:

Belki de işleri kötü bir şekilde kavramsallaştırıyorum. predictInterval()Jared Knowles tarafından verilen fonksiyonu aşağıdaki cevaplarda kullanmak, beklediğim gibi olmayan aralıkları verir ...

library("lattice")
library("lme4")
library("ggplot2")

fish <- c(rep(letters[1:10], each = 100), rep("k", 995), rep("l", 5))
oz <- round(1 + rnorm(2000)/10, 3)
sec <- 9 + c(rep(1:10, each = 100)/10,rep(1.1, 995), rep(1.2, 5)) + oz + rnorm(2000)

fishDat <- data.frame(fishID = fish, fishWt = oz, time = sec)
dim(fishDat)
head(fishDat)
plot(fishDat$fishID, fishDat$time)

lme1 <- lmer(time ~ fishWt + (1 | fishID), data=fishDat)
summary(lme1)
dotplot(ranef(lme1, condVar = TRUE))

İki yeni balık ekledim. 995 yarış gözlemlediğimiz Balık K ve 5 yarış gözlemlediğimiz Balık L. Fish AJ için 100 yarış gözlemledik. Daha lmer()önce olduğu gibi aynı uyuyor . Baktığımızda dotplot()gelen latticepaketin:

FishID Tahminleri

Varsayılan olarak, dotplot()rastgele efektleri nokta tahminleriyle yeniden sıralar. Balık L için tahmin en üst sırada ve çok geniş bir güven aralığına sahip. Fish K üçüncü sırada ve çok dar bir güven aralığı var. Bu bana mantıklı geliyor. Fish K hakkında çok fazla veriye sahibiz, ancak Fish L hakkında çok fazla veriye sahip değiliz, bu nedenle Fish K'nın gerçek yüzme hızı hakkında tahminlerimize daha çok güveniyoruz. Şimdi, bunun Fish K için dar bir tahmin aralığı ve kullanırken Fish L için geniş bir tahmin aralığı olacağını düşünüyorum predictInterval(). Howeva:

newDat <- data.frame(fishID = letters[1:12],
                     fishWt = 1)

preds <- predictInterval(lme1, newdata = newDat, n.sims = 999)
preds
ggplot(aes(x=letters[1:12], y=fit, ymin=lwr, ymax=upr), data=preds) +
  geom_point() + 
  geom_linerange() +
  labs(x="Index", y="Prediction w/ 95% PI") + theme_bw()

Balık için Tahmini Aralık

Bu tahmin aralıklarının tümü genişlikte aynı görünüyor. Neden Fish K ile ilgili tahmimiz diğerlerini daraltmıyor? Neden Fish L için yaptığımız öngörü diğerlerinden daha geniş değil?


1
predictIntervalHem sabit hem de rastgele etki terimleri için hata / belirsizlik içerir. Gelen dotplotyalnızca nedeniyle tahmin rastgele kısmı, balık spesifik kesicilerimizden tahmin etrafında esasen belirsizliğe belirsizlik görüyoruz. Modelinizde sabit parametrede çok fazla belirsizlik varsa fishWtve bu parametre öngörülen değerin çoğunu yönlendirirse, belirli bir balık müdahalesinin etrafındaki belirsizlik önemsizdir ve aralıkların genişliğinde büyük bir fark görmezsiniz. predictIntervalSonuçlarda bunu daha netleştirmeliyiz .
jknowles

Yanıtlar:


18

Bu soru ve mükemmel alışveriş, paketteki predictIntervalfonksiyonu yaratmadaki itici güçtü merTools. bootMergitme yoludur, ancak bazı problemler için tüm modelin önyüklenmiş desteklerini üretmek için hesaplamaya uygun değildir (modelin büyük olduğu durumlarda).

Bu durumlarda, modeldeki parametrelerin dağılımlarını üretmek predictIntervaliçin arm::simfonksiyonları kullanmak ve daha sonra bu dağılımları newdatakullanıcı tarafından verilen yanıtın simüle edilmiş değerlerini üretmek için kullanmak üzere tasarlanmıştır . Kullanımı basit - yapmanız gereken tek şey:

library(merTools)
preds <- predictInterval(lme1, newdata = newDat, n.sims = 999)

predictIntervalTahmin aralıkları için aralığın ayarlanması, dağılımın ortalamanın mı yoksa ortalamanın mı raporlanacağının seçilmesi ve modelden artık varyansın dahil edilip edilmemesinin seçilmesi dahil olmak üzere başka bir dizi değer belirtebilirsiniz .

Bu, tam bir tahmin aralığı değildir, çünkü nesnedeki thetaparametrelerin değişkenliği lmerdahil edilmez, ancak diğer varyasyonların hepsi bu yöntemle yakalanır ve oldukça iyi bir yaklaşım sunar.


3
Bu harika görünüyor! Skeçten şimdi okuma . Teşekkürler!
hossibley

Tahmin aralıkları beklediğim gibi değil. Yukarıdaki güncelleme 3'e bakın.
hossibley

predictInterval()Yuvalanmış rasgele efektleri sevmiyor mu ? Örneğin msleep, ggplot2paketin veri kümesini kullanarak : mod <- lmer(sleep_total ~ bodywt + (1|vore/order), data=msleep); predInt <- predictInterval(merMod=mod, newdata=msleep) Bir hata döndürür:Error in '[.data.frame'(newdata, , j) : undefined columns selected
hossibley

İç içe geçmiş efektlerden hoşlanmadığına bahse girerim. Test odamızda herhangi bir test yaptırdığımızı sanmıyorum. GitHub’la ilgili bir konuya bakmak için dosya yazacağım. Ayrıca devtools::install_github("jknowles/merTools")ilk önce GitHub'dan dev sürümünü denemeyi tavsiye ederim .
jknowles

2
Güncelleme olarak, merTools'un en son geliştirme sürümü iç içe efektlere izin verir. Kısa süre sonra CRAN'a gönderilecek.
16'da jknowles

15

Bunu bootMer, her parametrik önyükleme kopyası için bir dizi tahmin üreterek yapın :

predFun <- function(fit) {
    predict(fit,newDat)
}
bb <- bootMer(lme1,nsim=200,FUN=predFun,seed=101)

Çıktısı bootMerçok şeffaf olmayan bir "boot"nesnede, ancak ham tahminleri $tbileşenden çıkarabiliriz .

Balık E, Balık D'yi ne kadar zaman geçirir?

predMat <- bb$t
dim(predMat) ## 200 rows (PB reps) x 10 (predictions)

Balık E'nin zamanları sütun 5'te, balık D'nin zamanları sütun 4'tedir, bu yüzden sütun 5'in sütun 4'ten daha az olduğunu bilmemiz gerekir:

mean(predMat[,5]<predMat[,4])  ## 0.57

Beklenmeyen sonuçlar alıyorum. NewDat'taki tüm balıklar için fishWt = 1'i ayarlarsam, Balık A'nın ortalama / medyan süresinin ~ 10.1, Balık B ~ 10.2, ..., Balık J ~ 11.0 olmasını beklerdim (eğitim verilerindeki zamanları olarak tanımlanır:) sec <- 9 + rep(1:10, rep(100,10))/10 + oz + rnorm(1000)/10. Kullandığımda predict(), Balık A, E ve J için tahmin süreleri beklendiği gibi 10.09, 10.49 ve 10.99'dur. Bununla birlikte, indiğiniz bootMer yöntemi için medyan zamanlar: 10.52, 10.59 ve 10.50. Daha fazla anlaşma bekler miydim?
hossibley

Olarak kullanmak use.u=TRUE: bb <- bootMer(lme1,nsim=200,FUN=predFun,seed=101,use.u=TRUE)bana istediğimi veriyor gibi görünüyor. Teşekkürler!
hossibley

Tamam, bu biraz zorlaşıyor. Sen bakmak gerekir use.uiçin argüman bootMer. Asıl soru, "sabit etkideki tesadüf ve rastgele etki" derken, "rastgele etki" ile ne kastediyorsunuz? Rasgele etkiler varyansındaki veya koşullu modlardaki (yani balıklara özgü etkiler) belirsizliği mi kastediyorsunuz ? Kullanabilirsin use.u=TRUE, ama ne istersen yapabileceğini sanmıyorum ...
Ben Bolker

Kullanırsam use.u=TRUE, o zaman "u [stay] değerleri tahmini değerlerinde sabitlenir". Bunu bir anlam olarak yorumluyorum, Balık A için rastgele etki noktası tahminimiz ne olursa olsun, isterseniz Tanrı'nın Dürüst Gerçeği olarak kabul edilir. bootMerRE nokta tahminimizde hata olmadığını varsayar. Ben kullanırsanız use.u=FALSE, yok bootMerhesaba hiç RE noktası tahminleri alabilir? Öyle görünüyor bootMerkullanarak sonuçları use.u=FALSEkullanmaya eşdeğer (veya, asimptotik eşdeğeri) re.form=NAiçinde predict()deyimi. Bu doğru mu?
hossibley

1
Bence ATM uygulanmadı, ancak koşullu modların / BLUP'ların koşullu değişkenlerini ( c(attr(ranef(lme1,condVar=TRUE)[[1]],"postVar"))bu örnekte hepsi aynı) çıkarabilir ve sonra bu değerleri örnekleyebilirsiniz.
Ben Bolker
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.