23
@siero5335 #みどりぼん 2014/09/09 データ解析のための統計モデリング入門 9章: GLMのベイズモデル化と事後分布の推定 前半

みどりぼん9章前半

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: みどりぼん9章前半

@siero5335

#みどりぼん 2014/09/09

データ解析のための統計モデリング入門 9章: GLMのベイズモデル化と事後分布の推定

前半

Page 2: みどりぼん9章前半

自己紹介 Twitter ID: @siero5335

仕事: 某大学で    化学物質曝露影響の解析    測定法の開発してます    専門: 環境化学、分析化学

測定結果の解析に統計を使用

Page 3: みどりぼん9章前半

 目次

9.0:  例題データ紹介      

9.1:  種子数のポアソン回帰    

9.2:  GLMのベイズモデル化    

9.3:  無情報事前分布    

9.4:  ベイズ統計モデルの事後分布の推定    

9.4.1:  ベイズ統計モデルのコーディング  (Stan)    

9.4.2:  事後分布推定の準備    

9.4.3:  どれだけ長くMCMCサンプリングすればいいのか

Page 4: みどりぼん9章前半

 9.0:  例題データ紹介  

今回はどんなデータ? 架空植物: n = 20

x: 体サイズ y: 種子数 仮説 体サイズxiに依存して種子数yiの平均が増減する 実際は

のポアソン分布から生成したデータ

x y 3 5

3.210526 3 3.421053 6 3.631579 7 3.842105 7 4.052632 5 4.263158 9 4.473684 9 4.684211 7 4.894737 10 5.105263 12 5.315789 8 5.526316 7 5.736842 4 5.947368 4 6.157895 11 6.368421 9 6.578947 9 6.789474 8

7 6

λ = exp(1.5 + 0.1x)

Page 5: みどりぼん9章前半

 9.1:  種子数のポアソン回帰  

3 4 5 6 7

46

810

12Call:    glm(formula  =  y  ~  x,  family  =  poisson,  data  =  d)    Coefficients:  (Intercept)                        x              1.56606            0.08334        Degrees  of  Freedom:  19  Total  (i.e.  Null);    18  Residual  Null  Deviance:          15.66    Residual  Deviance:  14.17    AIC:  94.04

今回はこのGLMをベイズ統計モデルに移植し、 事後分布の推定に取り組む

図9.1  p195より引用

Page 6: みどりぼん9章前半

 9.2:  GLMのベイズモデル化  

1. 個体iの種子数yiのばらつきを平均λiのポアソン分布 に従うとする。 2. GLMの時と同様に、線形予測子と対数リンク関数で平均を と指定する。個体差は考慮しないのでランダム効果の項はなし。 3.このモデルの尤度関数: L(β1, β2)は となる。ここまではGLMといっしょ。

λi = exp(β1 + β2xi)

p(yi|λi)

β! , β! = !!

!! λ! = ! !!

(!!|β! , β! , !!)!

Page 7: みどりぼん9章前半

 9.2:  GLMのベイズモデル化  

5. 今回はベイズモデル化して事後分布を推定したい   ベイズモデルの事後分布は

に比例するので、今回の例題では以下の関係が成り立つ。

この切片β1, 傾きβ2を適切に指定できれば ベイズモデル化したGLMが得られる

(尤度) × (事前分布)

事後分布 切片β1, 傾きβ2の事前分布

β1,β2がある値の時Yが得られる確率

Page 8: みどりぼん9章前半

 9.3:  無情報事前分布  

どうやって切片β1, 傾きβ2の事前分布を推定するのか 架空植物の平均種子数を増減させる 切片、傾きの確率分布なんて分かるわけない。 [-∞, ∞]の範囲で好きな値をとっていいことにする。 → 無情報事前分布と呼ぶ。

Page 9: みどりぼん9章前半

 9.3:  無情報事前分布  

どうやって切片β1, 傾きβ2の事前分布を推定するのか 架空植物の平均種子数を増減させる 切片、傾きの確率分布なんて分かるわけない。 [-∞, ∞]の範囲で好きな値をとっていいことにする。 → 無情報事前分布と呼ぶ。 どんな確率分布? 範囲を取る一様分布 ひらべったい正規分泌

-10 -5 0 5 10

0.0

0.1

0.2

0.3

0.4

平均0, 標準偏差100の 正規分布

標準正規分布

図9.2  p197より引用

Page 10: みどりぼん9章前半

 9.3:  無情報事前分布  

どうやって切片β1, 傾きβ2の事前分布を推定するのか 架空植物の平均種子数を増減させる 切片、傾きの確率分布なんて分かるわけない。 [-∞, ∞]の範囲で好きな値をとっていいことにする。 → 無情報事前分布と呼ぶ。 どんな確率分布? 範囲を取る一様分布 ひらべったい正規分泌

Page 11: みどりぼん9章前半

 9.4.1:  ベイズ統計モデルのコーディング  (BUGS)  Model  {    for  (i  in  1:N)  {      Y[i]  ~  dpois  (  lambda  [i]  )      log  (  lambda  [i]  )  <-­‐  beta1  +  beta2  *  (X  [i]  –Mean.X  )    }    beta1  ~  dnorm  (0,  1.0E-­‐4)      beta1  ~  dnorm  (0,  1.0E-­‐4)    }  

Page 12: みどりぼん9章前半

 9.4.1:  ベイズ統計モデルのコーディング  (BUGS)  Model  {    for  (i  in  1:N)  {      Y[i]  ~  dpois  (  lambda  [i]  )      log  (  lambda  [i]  )  <-­‐  beta1  +  beta2  *  (X  [i]  –Mean.X  )    }    beta1  ~  dnorm  (0,  1.0E-­‐4)      beta1  ~  dnorm  (0,  1.0E-­‐4)    }      

 Y[1]  ~  dpois  (  lambda  [1]  )      log  (  lambda  [1]  )  <-­‐  beta1  +  beta2  *  (X  [1]  –Mean.X  )    Y[2]  ~  dpois  (  lambda  [2]  )      log  (  lambda  [2]  )  <-­‐  beta1  +  beta2  *  (X  [2]  –Mean.X  )  ・・・    Y[20]  ~  dpois  (  lambda  [20]  )      log  (  lambda  [20]  )  <-­‐  beta1  +  beta2  *  (X  [20]  –Mean.X  )

ブロック 統計モデルの記述

ブロックは以下のように展開されてWinBUGSに解釈される

iはYやlambdaについてる変数の添字

Page 13: みどりぼん9章前半

 9.4.1:  ベイズ統計モデルのコーディング  (BUGS)  

Y[i]  ~  dpois  (  lambda  [i]  )    

 個体i  の種子数Y[i]が平均 lambda  [i]  のポアソン分布    dpois  (  lambda  [i]  )に従うという意味    

log  (  lambda  [i]  )  <-­‐  beta1  +  beta2  *  (X  [i]  –Mean.X  )    

   左辺:  個体iの平均種子数lambda  [i]  は対数リンク関数に従う    

   beta1  =  切片β1      beta2  =  傾きβ2      X  [i]  =  説明変数(個体iのサイズxi)    

   Mean.X 演算高速化のために標本平均を引いて中央化  

Page 14: みどりぼん9章前半

 9.4.1:  ベイズ統計モデルのコーディング  (BUGS)  Model  {    for  (i  in  1:N)  {      Y[i]  ~  dpois  (  lambda  [i]  )      log  (  lambda  [i]  )  <-­‐  beta1  +  beta2  *  (X  [i]  –Mean.X  )    }    beta1  ~  dnorm  (0,  1.0E-­‐4)      beta2  ~  dnorm  (0,  1.0E-­‐4)    }    dnorm  (mean,  tau)  mean  =  平均  tau  =  分散の逆数    

標準偏差  =      標準偏差は100だが、リンク関数が対数なので無情報と言って良い  

パラメータβ1  ,β2の事前分布を指定  

tau  =  1.0E-­‐4なので  パラメータβ1  ,β2の事前分布は  平均0,  分散100の無情報事前分布  

Page 15: みどりぼん9章前半

 9.4.1:  ベイズ統計モデルのコーディング  (BUGS)  

無情報事前分布 切片β1

無情報事前分布 傾きβ2

ポアソン分布 平均λ[i] データ(各個体のサイズX[i]) データ

(各個体の種子数Y[i])

確率論的関係 左辺は右辺の確率分布に従う: コード上表記 “~”

決定論的関係 左辺の内容は右辺である: コード上表記 “->”

Page 16: みどりぼん9章前半

 9.4.2:  事後分布推定の準備  

手順

(1)   データの読み込み  

(2)   推定したいパラメータの初期値を指定  

(3)   RからWinBUGS読み出してデータ・初期値・サンプリング回数、コードファイル名を伝達  

(4)   WinBUGSが働く  

(5)   MCMCサンプリングが終わったら結果をRに渡す  

(6)   MCMCサンプリングの結果をR内で調べる

R2WinBUGSを使って普通は連携するが、使いやすくないので、  本書では久保先生お手製のR2WBwapper.Rを使って操作を簡易化

Page 17: みどりぼん9章前半

 9.4.2:  事後分布推定の準備  

source  (“R2WBwrapper.R”)  #ラッパー読み込み  load(“d.RData”)                                          #  (1)  必要なデータの準備  clear.data.param()                                # データ・初期値読み込みの準備    #データの設定,  set.data関数を使ってデータの中身を指定  set,data(“N”,  nrow(d))                #サンプルサイズ  set.data(“Y”,  d$y)                                  #応答変数:種子数Y[i]  set.data(“X”,  d$x)                                  #説明変数:  体サイズX[i]  set.data  (“Mean.X,  mean(d$x))  #X[i]の標本平均    #パラメータの初期値設置(2),  set.param関数で初期値設定set.param(“beta1”,  0)  set.param(“beta2”,  0)  #次スライドに続く  

Page 18: みどりぼん9章前半

 9.4.2:  事後分布推定の準備  

#サンプリング回数等の決定(3)    #MCMCサンプリングが終わったら結果をRに渡す(5)    

post.bugs  <-­‐  call.bugs(      file  =  “model.bugs.txt”,      n.iter  =  1600,  n.burnin  =  100,  n.thin  =3  }    

file  =  “model.bugs.txt”:  BUGSコードを書いたファイル名の指定  n.iter  =  1600:  MCMCサンプリング1600回  n.burnin  =  100:  バーンイン,  最初100回分のデータは使わない    

n.thin  =3:  101-­‐1600までの1500ステップを2個とばしで記録する →間引きのため(サンプリング回数検討の負担減らし)  

Page 19: みどりぼん9章前半

 9.4.3:  どれだけ長くMCMCサンプリングすればいいのか

サンプリング数が足りないと 事後分布を正確に推定できない。

多いと時間がかかる… 収束診断で確認 サンプリングを繰り返してサンブル列間の乖離を確認 chain関数を指定(デフォルトは3)

-> Rhat < 1.1(経験的な指標: 収束した、しない)

Rhat! = ! !"#!/!

!"#! = !! − 1! ! + !1!!

W: サンプル列内の分散 B: サンプル列間の分散

var+: 周辺事後分布の分散

図8.8  p179より引用

Page 20: みどりぼん9章前半

 9.4.3:  Rhat  >  1.1の時どうする?

n.iterを増やす →サンプリング回数増やす

n.burninを増やす →定常分布になるまでの  待ち時間を増やす

それでも改善しない時は?

不適切な統計モデリング コード・データの間違い パラメータの初期値が不適切

図9.4  p205より引用

Page 21: みどりぼん9章前半

 まとめ  

まずGLMをベイズモデル化することで感覚をつかむ    

未知の値には無情報事前分布を事前分布に使ってみる    

WinBUGSなどにコードを渡してMCMCサンプリング!    

サンプル列間の乖離を調べて収束したか確かめる→  Rhat  <  1.1    

収束しない時は…  サンプリング回数、Burn-­‐in期間を確認  それでもダメならモデルの中身をチェック    事後分布の推定については後半に!  

Page 22: みどりぼん9章前半

 おまけ:  glmer2stanでもうちょっとお手軽に  

library(rstan)  #  rstan読み出し  library(glmer2stan)  #  glmer2stan読み出し  res  <-­‐  glmer2stan(y  ~  x,  family  =  “poisson”,  data  =  d,  chain  =3)  #lme4のformula形式で記述  (res)  #結果の表示  res@stanmodel    #stanでどう表すか表示    >(res)    

mean se_mean sd 2.50% 25% 50% 75% 97.50% n_eff Rhat Intercept 1.55 0.01 0.36 0.81 1.31 1.56 1.8 2.23 1996 1 beta_x 0.09 0 0.07 -­‐0.04 0.04 0.08 0.13 0.22 1987 1 dev 92.02 0.04 2.04 90.08 90.6 91.39 92.75 97.51 2553 1 lp__ 143.98 0.02 1.02 141.24 143.62 144.3 144.69 144.95 2553 1

3 chains, each with iter=10000; warmup=5000; thin=1;

post-warmup draws per chain=5000, total post-warmup draws=15000.

iter,  warmup  (burn-­‐in),  chain,  thin回数については  XX  (内容)  =  X  (回数)  で指定可能  デフォルトは iter  =  10000,  warmup  =  5000,  chain  =  1,  thin  =  1

Page 23: みどりぼん9章前半

 おまけ:  glmer2stanでもうちょっとお手軽に  res@stanmodel    #stanでどう表すか表示    >  res@stanmodel  S4  class  stanmodel  'y  ~  x  [poisson]'  coded  as  follows:  data{          int  N;          int  y[N];          real  x[N];  }    parameters{          real  Intercept;          real  beta_x;  }    #右へ続く  

model{          real  vary[N];          real  glm[N];          //  Priors          Intercept  ~  normal(  0  ,  100  );          beta_x  ~  normal(  0  ,  100  );          //  Fixed  effects          for  (  i  in  1:N  )  {                  glm[i]  <-­‐  Intercept                                  +  beta_x  *  x[i];                  glm[i]  <-­‐  exp(  glm[i]  );          }          y  ~  poisson(  glm  );  }    generated  quanwwes{          real  dev;          real  vary[N];          real  glm[N];          dev  <-­‐  0;          for  (  i  in  1:N  )  {                  glm[i]  <-­‐  Intercept                                  +  beta_x  *  x[i];                  dev  <-­‐  dev  +  (-­‐2)  *  poisson_log(  y[i]  ,  exp(glm[i])  );          }  }  

今まで使っていたモデルをstanで書き換えるとどうやって書くのかわかるので、stan事始めに向いているかも?