Rのlmer()混合効果モデルの予測間隔


37

lmer()モデルからの予測の周りの予測区間を取得したい。これに関する議論を見つけました。

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

http://glmm.wikidot.com/faq

しかし、それらはランダム効果の不確実性を考慮していないようです。

以下に具体例を示します。私は金の魚をレースしています。過去100レースのデータがあります。RE推定値とFE推定値の不確実性を考慮して、101番目を予測したい。魚のランダムインターセプト(10種類の魚があります)と、重量の固定効果(重い魚が少ないほど速い)を含めています。

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)

さて、第101レースを予測します。魚の重量を量り、準備ができています:

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

魚Dは本当に自分自身を手放し(1.11オンス)、実際に魚Eと魚Fに負けると予測されています。どちらも過去よりも優れています。ただし、「魚E(0.91オンスの重量)は確率pで魚D(1.11オンスの重量)に勝ります」と言いたいと思います。lme4を使用してこのようなステートメントを作成する方法はありますか?確率効果と固定効果の両方の不確実性を考慮して、確率pを求めています。

ありがとう!

PSはpredict.merModドキュメントを見て、「分散パラメーターに不確実性を組み込む効率的な方法を定義するのが難しいため、予測の標準誤差を計算するオプションはありません。bootMerこのタスクに推奨します」と示唆していますが、bootMerこれを行うために使用する方法。bootMerパラメータ推定のブートストラップされた信頼区間を取得するために使用されるようですが、間違っている可能性があります。

更新されたQ:

OK、間違った質問をしていたと思う。「フィッシュA、重量オンス、レース時間は(lcl、ucl)90%です」と言いたいです。

レイアウトした例では、重量が1.0オンスのフィッシュAのレースタイムは9 + 0.1 + 1 = 10.1 sec平均で、標準偏差は0.1です。したがって、彼の観察されたレースタイムは

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 

時間の90%。その答えを与えようとする予測関数が必要です。すべてfishWt = 1.0を設定しnewDat、シミュレーションを再実行し、使用します(以下のBen Bolkerによって提案されます)

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

与える

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

これは、実際に人口の平均を中心にしているようですか?FishID効果を考慮していないかのように?サンプルサイズの問題かもしれないと思っていましたが、観察されたレースの数を100から10000に増やしても、同様の結果が得られます。

デフォルトでのbootMer使用に注意しuse.u=FALSEます。反対に、使用して

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

与える

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

その間隔は狭すぎて、魚Aの平均時間の信頼区間と思われます。Fish Aの平均レース時間ではなく、観察されたレース時間の信頼区間が必要です。どうすれば入手できますか?

更新2、ほとんど:

私は思った私は、私が探していたものを見つけゲルマンとヒル(2007) 、利用するためのページ273の必要性armパッケージを。

library("arm")

魚Aの場合:

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 

すべての魚について:

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 

実際、これはおそらく私が望んでいるものとはまったく異なります。モデル全体の不確実性のみを考慮しています。たとえば、魚Kの5つのレースと魚Lの1000のレースを観測した状況では、魚Kの予測に関連する不確実性は、魚Lの予測に関連する不確実性よりもはるかに大きいはずです。

Gelman and Hill 2007をさらに検討します。最終的にはBUGS(またはStan)に切り替える必要があるかもしれません。

3日目の更新:

おそらく、物事の概念化が不十分です。predictInterval()以下の回答でJared Knowlesによって提供された関数を使用すると、私が期待するものとはまったく異なる間隔が得られます...

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))

2つの新しい魚を追加しました。995人のレースを観察した魚Kと、5つのレースを観察した魚L。Fish AJで100レースが行われています。lmer()前と同じようにフィットします。パッケージdotplot()から見てlattice

FishIDの見積もり

デフォルトでdotplot()は、ポイント推定値によってランダム効果を並べ替えます。Fish Lの推定値は一番上の行にあり、非常に広い信頼区間があります。魚Kは3行目にあり、非常に狭い信頼区間を持っています。これは理にかなっています。Fish Kには多くのデータがありますが、Fish Lには多くのデータがないため、Fish Kの真の水泳速度についての推測に自信があります。さて、これを使用すると、Fish Kの予測間隔が狭くなり、Fish Lの予測間隔が広くなると思います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()

魚の予測間隔

これらの予測間隔はすべて同じ幅に見えます。Fish Kの予測が他の予測よりも狭くならないのはなぜですか?Fish Lの予測が他の予測よりも広くないのはなぜですか?


1
predictInterval固定効果項とランダム効果項の両方の誤差/不確実性が含まれます。ではdotplot、あなただけによる予測のランダムな部分、魚特有のインターセプトの推定値の周りに、本質的に不確実性に不確実性を見ています。モデルの固定パラメーターに多くの不確実性がありfishWt、このパラメーターが予測値の大部分を駆動する場合、特定の魚切片の不確実性は些細であり、間隔の幅に大きな違いは見られません。これをpredictInterval結果でより明確にする必要があります。
-jknowles

回答:


19

この質問と優れた交換はpredictIntervalmerToolsパッケージに関数を作成するための推進力でした。bootMer方法がありますが、一部の問題では、モデル全体のブートストラップされた再フィットを生成することは計算上実行不可能です(モデルが大きい場合)。

これらの場合、関数predictIntervalを使用arm::simしてモデル内のパラメーターの分布を生成し、それらの分布を使用newdataして、ユーザーから提供された応答のシミュレーション値を生成するように設計されています。使い方は簡単です。必要なことは次のとおりです。

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

predictInterval予測間隔の間隔の設定、分布の平均または中央値を報告するかどうかの選択、モデルからの残差分散を含めるかどうかの選択など、他の値のホスト全体を指定できます。

オブジェクトのthetaパラメーターの変動はlmer含まれていないため、完全な予測間隔ではありませんが、他のすべての変動はこの方法でキャプチャされ、かなり適切な近似が得られます。


3
これはすごいですね!今ビネットを読んで。ありがとう!
hosibley

予測間隔は、私が期待したものとはまったく異なります。上記の更新3を参照してください。
hossibley

predictInterval()入れ子になったランダム効果が好きではありませんか?例えば、使用してmsleepからデータセットをggplot2パッケージする:mod <- lmer(sleep_total ~ bodywt + (1|vore/order), data=msleep); predInt <- predictInterval(merMod=mod, newdata=msleep) エラーを返します:Error in '[.data.frame'(newdata, , j) : undefined columns selected
hossibley

ネストされたエフェクトは好きではないに違いない。私たちのテストスイートでそれをテストしたとは思わない。それを調べるために、GitHubに問題を提出します。また、GitHubのdevバージョンをdevtools::install_github("jknowles/merTools")最初に試すことをお勧めします。
jknowles

2
更新として、merToolsの最新の開発バージョンでは、ネスト効果を使用できます。まもなくCRANにプッシュされます。
jknowles

15

これを行うにbootMerは、各パラメトリックブートストラップレプリケートの予測セットを生成します。

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

の出力はbootMer非常に透明ではない"boot"オブジェクトですが、$tコンポーネントから生の予測を取得できます。

Fish EはFish Dをどのくらいの時間倒しますか?

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

魚Eの時間は列5にあり、魚Dの時間は列4にあるため、列5が列4より小さい比率を知る必要があります。

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

予期しない結果が得られています。newDatのすべての魚にfishWt = 1を設定した場合、魚Aの平均/中央時間は〜10.1、魚B〜10.2、...、魚J〜11.0(トレーニングデータの時間は定義:)sec <- 9 + rep(1:10, rep(100,10))/10 + oz + rnorm(1000)/10。を使用するとpredict()、魚A、E、およびJの予測時間は予想どおり10.09、10.49、および10.99になります。ただし、説明するbootMerメソッドの時間の中央値は10.52、10.59、および10.50です。もっと合意が期待できただろうか?
hossibley

use.u=TRUEas in:を使用すると、bb <- bootMer(lme1,nsim=200,FUN=predFun,seed=101,use.u=TRUE)欲しいものが得られるようです。ありがとう!
-hosibley

OK、これは少し注意が必要です。のuse.u引数を見る必要がありますbootMer。問題は、「固定効果とランダム効果の不確実性」と言うとき、「ランダム効果」とはどういう意味ですか?変量効果の分散、または条件付きモードの不確実性(つまり、魚固有の効果)を意味しますか?あなたは使用することができますuse.u=TRUEが、私はそれは必ずしもあなたがやりたいとは思わない...
ベンBolker

を使用する場合use.u=TRUE、「uの値は[推定値]に固定されます」。私はこれを意味として解釈します。魚Aのランダムエフェクトポイントの推定値が何であれ、それは神の正直な真実とみなされます。bootMerREポイントの推定にエラーがないことを前提としています。私が使用している場合はuse.u=FALSE、んbootMer、アカウントにすべてのREの点推定値を取りますか?思わbootMer使用して結果がuse.u=FALSE使用するのと同じです(または、漸近的当量)re.form=NApredict()声明。本当?
-hosibley

1
ATMは実装されていないと思いますが、c(attr(ranef(lme1,condVar=TRUE)[[1]],"postVar"))(この例ではすべて同じ)を使用して条件付きモード/ BLUPの条件付き差異を抽出し、それらの値をサンプリングできます。
ベンボルカー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.