Handle Missing Values with brms

Paul Bürkner

2022-12-14

イントロダクション

実世界の多くのデータセットには、様々な理由で欠損値が含まれている。一般に、これらの欠損値を処理するためのオプションは非常に多くある。最も簡単な解決策は、1つ以上の変数が欠落しているデータセットからすべての行を削除することである。しかし、値が完全にランダムに欠落していない場合、これは分析にバイアスをもたらす可能性がある。したがって、私たちは通常、何らかの方法で欠損値をインプットしたいのである。ここでは、brmsを用いた2つの一般的なアプローチについて考えてむ。(1)多重代入でモデルフィッティングのに欠損値を代入する、(2)モデルフィッティングの*最中にその場で欠損値を代入する [^1] .簡単な例として、参加者の agebmi (肥満度)、hyp (高血圧)、chl (血清総コレステロール)の情報を含む nhanes データセットを使用することにする。この vignette の目的では、agechl によって bmi を予測することに主に関心がある。

data("nhanes", package = "mice")
head(nhanes)
  age  bmi hyp chl
1   1   NA  NA  NA
2   2 22.7   1 187
3   1   NA   1 187
4   3   NA  NA  NA
5   1 20.4   1 113
6   3   NA  NA 184

モデルフィッティングの前に代入を行う

実際のモデルフィッティングが行われる前に、欠損データをインプットすることができる多くのアプローチがある。統計的な観点からは、多重代入は最良の解決策の1つである。各欠損値は1回ではなく、m 回インプットされ、合計 m の完全にインプットされたデータセットになる。そして、これらのデータセットのそれぞれに別々にモデルを適合させることができ、その後、モデル間で結果がプールされる。多重代入のために広く適用されているパッケージの1つが

mice (Buuren & Groothuis-Oudshoorn, 2010)を使用し、以下ではbrmsと併用して使用することにする。のデフォルト設定を適用する。

mice、これはすべての変数が他のすべての変数の欠損値をインプットするために使用され、変数の特性に基づいて自動的に選択された代入関数が使用されることを意味する。

library(mice)
imp <- mice(nhanes, m = 5, print = FALSE)

今、私たちは imp オブジェクト内に m = 5 インプットされたデータセットが格納されている。実際には、欠損によって引き起こされる不確実性を正確に説明するために、おそらく 100 imputed data setsの領域でさえも、5 以上のものが必要だろう (Zhou & Reiter, 2010).もちろん、これは計算負荷を増加させるので、この vignette の目的のために m = 5 に固執する。m の値に関わらず、これらのデータセットを抽出し、実際のモデルフィッティング関数にデータフレームのリストとして渡すか、imp を直接渡すかのどちらかになる。後者は brmsmice によってインプットされたデータに対して特別なサポートを提供しているため、うまくいく。後者の方がタイピングが少ないので、後者のアプローチをとる。複数のインプットされたデータセットに brms で目的のモデルをフィットさせるのは簡単である。

fit_imp1 <- brm_multiple(bmi ~ age*chl, data = imp, chains = 2)

返される適合モデルは、すべての m サブモデルの事後ドローを含む通常の brmsfit オブジェクトである。古典的な統計学では、モデル間のプーリングは必ずしも簡単ではないが、ベイズのフレームワークでは些細なことである。ここでは、複数のインプットされたデータセットの結果をプールすることは、単にサブモデルの事後ドローを結合することで達成される。従って、プーリングについて全く心配することなく、すべての後処理方法をすぐに使用することができる。

summary(fit_imp1)
 Family: gaussian 
  Links: mu = identity; sigma = identity 
Formula: bmi ~ age * chl 
   Data: imp (Number of observations: 25) 
  Draws: 10 chains, each with iter = 2000; warmup = 1000; thin = 1;
         total post-warmup draws = 10000

Population-Level Effects: 
          Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
Intercept    16.92      8.06     0.94    32.38 1.15       45      336
age           0.31      4.55    -8.55     8.95 1.09       78      497
chl           0.08      0.04    -0.01     0.17 1.23       31      131
age:chl      -0.02      0.02    -0.06     0.03 1.10       68     2380

Family Specific Parameters: 
      Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma     3.34      0.66     2.30     4.86 1.26       29      312

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).

要約出力では、いくつかの Rhat の値が \(1.1\) よりも高いことに気づいた。これは収束の問題がある可能性を示している。複数のインプットされたデータセットに基づくモデルでは、これはしばしば偽陽性となる。異なるサブモデルのチェーンは、異なるデータに適合させたので、互いに正確に重ならないだろう。の右側にあるチェーンを見ることができる。

plot(fit_imp1, variable = "^b", regex = TRUE)

このような非重畳的な連鎖は、実際には収束の問題がないのに、高い Rhat 値を意味する。したがって、サブモデルの収束を個別に調査する必要がある。

round(fit_imp1$rhats, 2)
  b_Intercept b_age b_chl b_age.chl sigma lprior lp__
1        1.01     1  1.01      1.01  1.01   1.01 1.00
2        1.00     1  1.00      1.00  1.00   1.00 1.00
3        1.00     1  1.00      1.00  1.00   1.00 1.00
4        1.00     1  1.00      1.00  1.01   1.01 1.01
5        1.00     1  1.00      1.00  1.00   1.00 1.00

各サブモデ ルの収束は良好であるように見える。したがって、さらに後処理を進め、結果を解釈することができる。例えば、agechl の複合効果を調査することができる。

conditional_effects(fit_imp1, "age:chl")

要約すると、多重代入の利点は明らかである:モデル適合関数が、データセットがインプットされたことを事前に知る必要がないため、あらゆる種類のモデルに適用できる。また、完全なベイズ法を使用する場合、サブモデル間のプーリングについて心配する必要はない。唯一の欠点は、モデルフィッティングに要する時間である。ベイズモデルの推定は、1つのデータセットですでにかなり時間がかかり、多重代入を行う場合はさらに遅くなる。

他の多重代入パッケージとの互換性

brmsmice をビルトインでサポートしている。しかし、brm_multiple は、data の引数にデータフレームのリスト を入力として受け付けるので、あらゆる種類の多重代入パッケージをサポートする。したがって、あなたは、単にリストの形でインプットされたデータフレームを抽出する必要があり、それを brm_multiple に渡すことができる。 ほとんどの多重代入パッケージは、このタスクのためのいくつかの組み込み関数を持っている。例えば、mi パッケージを使用する場合、単に mi::complete 関数を呼び出して目的の出力を得る必要がある。

モデルフィッティング中の代入

モデルフィッティング中の代入は、一般的にモデルフィッティング前の代入よりも複雑であると考えられている。これはbrmsで欠損値をインプットする場合にも言えることであるが、おそらくその程度は多少小さくなる。bmiage、そして chl で予測するという目標を持った nhanes データをもう一度考えてみよう。age には欠損値がないので、bmichl だけは特別に注意する必要がある。モデルには2つのことを指示す必要がある。(1)どの変数が欠損値を含み、どのように予測されるべきか、(2)これらのインプットされた変数のうちどれが予測変数として使用されるべきか、である。brms** では、以下のように行う。

bform <- bf(bmi | mi() ~ age * mi(chl)) +
  bf(chl | mi() ~ age) + set_rescor(FALSE)
fit_imp2 <- brm(bform, data = nhanes)

bmi だけでなく chl も予測するので、モデルは多変量になる(brms の多変量構文の詳細については vignette("brms_multivariate") を参照)。私たちは、式 [^2] の左辺に | mi() を加えることによって、両変数の欠落が除外されるのではなく、モデル化されることを保証する。chl の推定欠損値が bmi の予測に使われることを保証するために、bmi の数式の右側に mi(chl) を書く。要約は、両方の応答変数の係数を得るので、少し雑然としているが、それを除けば、通常の方法で係数を解釈することができる。

summary(fit_imp2)
 Family: MV(gaussian, gaussian) 
  Links: mu = identity; sigma = identity
         mu = identity; sigma = identity 
Formula: bmi | mi() ~ age * mi(chl) 
         chl | mi() ~ age 
   Data: nhanes (Number of observations: 25) 
  Draws: 4 chains, each with iter = 2000; warmup = 1000; thin = 1;
         total post-warmup draws = 4000

Population-Level Effects: 
              Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
bmi_Intercept    13.88      8.59    -3.23    31.17 1.00     1732     2258
chl_Intercept   141.92     25.14    92.58   192.26 1.00     2449     2407
bmi_age           2.74      5.36    -7.68    13.41 1.00     1516     2077
chl_age          28.50     13.39     1.34    54.05 1.00     2371     2244
bmi_michl         0.10      0.05     0.01     0.19 1.00     1838     2357
bmi_michl:age    -0.03      0.02    -0.08     0.02 1.00     1607     2235

Family Specific Parameters: 
          Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS
sigma_bmi     3.37      0.76     2.25     5.20 1.01     1346     1683
sigma_chl    40.36      7.78    28.59    58.31 1.00     2022     2510

Draws were sampled using sampling(NUTS). For each parameter, Bulk_ESS
and Tail_ESS are effective sample size measures, and Rhat is the potential
scale reduction factor on split chains (at convergence, Rhat = 1).
conditional_effects(fit_imp2, "age:chl", resp = "bmi")

結果は多重代入から得られるものとかなり似ているが、一般的にはそうでない場合もあるので注意が必要である。多重代入では、デフォルトですべての変数を他のすべての変数に基づいて代入するのに対し、「1ステップ」アプローチでは、代入に使用する変数を明示的に指定しなければならないのである。したがって、間違いなく、多重代入は適用がより簡単である。ワンステップ’アプローチの明らかな利点は、m 回ではなく、一度だけモデルを適合させる必要があるということである。また、brms のフレームワークでは、標準的な多重代入ソフトウェアでは簡単に達成できない、多階層構造と複雑な非線形関係を欠損値の代入に使用することができる。一方、Stan(*brms**のエンジン)は離散パラメータを推定することができないため、離散変数をインプットすることは現在不可能である。

測定誤差と欠損値の組み合わせ

brms の欠損値項は、欠損値だけでなく、測定誤差、あるいはその任意の組み合わせも扱うことができない。実際、欠測値とは測定誤差が無限大の値であると考えることができる。したがって、mi の用語は、現在では非推奨となっている me の用語を自然に(そしていくぶん冗長に)一般化したものである。chl という変数を、ある既知の誤差を含みながら測定したとする。

nhanes$se <- rexp(nrow(nhanes), 2)

そして、この情報をモデルに取り込むには、次のようにすればよい。

bform <- bf(bmi | mi() ~ age * mi(chl)) +
  bf(chl | mi(se) ~ age) + set_rescor(FALSE)
fit_imp3 <- brm(bform, data = nhanes)

モデルの集計や後処理は通常通り行える。

[^1] 実は、応答変数の欠測にのみ適用される3つ目のアプローチがある。欠損回答をインプットしたい場合、観測された回答を用いてモデルをフィットし、事後予測によってモデルをフィットした後に、欠損回答をインプットするのである。つまり、欠損応答に対応する予測値を predict メソッドに供給する。

[^2] : bmi は他の変数の予測変数としては使われないので、bmi には本当に必要ない。したがって、次のようにすることもできる。 – impute missing values of bmi after model fitting by means of posterior を予測する。

参考文献

Buuren, S. V. & Groothuis-Oudshoorn, K. (2010). mice: Multivariate imputation by chained equations in R. Journal of Statistical Software, 1-68. doi.org/10.18637/jss.v045.i03

Zhou, X. & Reiter, J. P. (2010). A Note on Bayesian Inference After Multiple Imputation. The American Statistician, 64(2), 159-163. doi.org/10.1198/tast.2010.09109