Mais conteúdo relacionado
Semelhante a Stanの便利な事後処理関数 (18)
Stanの便利な事後処理関数
- 2. 動機
• Stan Advent Calendar 2016 という素晴らしいものがある。
http://qiita.com/advent-calendar/2016/stan
• すごいためになるモデルばかり...(お菓子力も、サンシャイン力もあがる)
• レベル高すぎない??(もちろん素晴らしいですけど)
• 初心者は記事通りモデル回してStan結果ファイルを自由に扱
えるだろうか?
• Stanには、結果処理の上質な関数が整っているけど、初心者
にはあまり知られていないのでは!?
•X’mas暇
2
- 4. おなじみのデモデータ
• まずは 8schools.stan を実行
詳しくは
(https://github.com/stan-dev/rstan/wiki/RStan-Getting-Started)
setwd(“ディレクトリ")
# rm(list=ls()) #Enviroment をきれいにします。
library(rstan) #パッケージ読み込み
rstan_options(auto_write = TRUE) #並列処理(下と合わせて)
options(mc.cores = parallel::detectCores())
# options(max.print = 99999) #Consoleに表示する個数の設定
schools_dat <- list(J = 8,
y = c(28, 8, -3, 7, -1, 1, 18, 12),
sigma = c(15, 10, 16, 11, 9, 11, 10, 18))
fit <- stan(file = '8schools.stan', data = schools_dat,
iter = 1000, chains = 4)
4
- 7. fitから簡単に数値取り出せない問題発生
• stanfit ファイル(今回でいう fit )はS4クラス形式で保存
• S4クラス形式とは?
• 普通のオブジェクトよりも複雑な形式で保存されている(っていう認識
でここでは問題ないと思う)。
• 普通のオブジェクトとは異なり、$で引き出すのではなく、@を用いて
中身を取り出す。
• ちなみに、JAGSの結果はS3クラスで保存されていて、これが同じよう
な操作ができないことの理由。最近はggmcmcなるパッケージがありま
すので便利ですけれども(わからない人は聞き流してください)
• 例えばこんな感じ(下記はモデルのパラメータを抽出している)
> fit@model_pars
[1] "mu" "tau" "eta" "theta" "lp__"
(飛ばしても良い)
7
- 9. やりたいこと①
• 魔法の言葉「 」で抽出して解決
• そして、一括判定してあげる。
※「 ,na.rm = T 」をつける意味
stanモデル上でパラメータに直接数値を代入している場合、 𝑅は当然算出されず、
𝑅=NaNとなります。そのような場合、欠損値の除去を行わないと正常に判定するこ
とが出来ません。
𝑅で収束判定
> all(summary(fit)$summary[,“Rhat”] <= 1.10, na.rm = T)
# all() ()内で論理式を全て満たしたらTRUEを返す関数
[1] TRUE
9
- 13. 他にも
• get_logposterior(fit) ⇒ 発生させた対数事後確率の乱数を取り出す
• get_inits(fit) ⇒ 推定の際の各パラメータの初期値を取り出す
• get_seeds(fit) ⇒ 推定の際の各パラメータの乱数の種を取り出す
• get_stanmodel(fit) ⇒ 推定に用いたstanモデルを取り出す
• get_elapsed_time(fit) ⇒ 推定時間(warmupとsampleが分かれてでる)
等々
13
- 17. stan_trace
• この関数はトレースプロットを出力することが出来る。
eta[7] eta[8]
eta[3] eta[4] eta[5] eta[6]
mu tau eta[1] eta[2]
500 600 700 800 900 1000 500 600 700 800 900 1000
500 600 700 800 900 1000 500 600 700 800 900 1000 500 600 700 800 900 1000 500 600 700 800 900 1000
500 600 700 800 900 1000 500 600 700 800 900 1000 500 600 700 800 900 1000 500 600 700 800 900 1000
-2
0
2
4
-4
-2
0
2
-2
0
2
-2
0
2
0
10
20
30
40
-2
0
2
-2
0
2
0
10
20
-2
0
2
-2
0
2
chain
1
2
3
4
今回はプロットするパラメータを
設定していないので10個分の
パラメータが表示、
バーンイン期間が非表示(デフォルト)
stan_trace(fit)
17
- 27. さらに...
• 各 stan_ シリーズの最後に$dataをつけることでplotに用いた
dataを抽出することが出来ます。
• たとえば...stan_plotの場合
mean = 事後平均値
ll=outer_levelで設定した点(低い方)
l = ci_levelで設定した点(低い方)
m = median
h, hh = l, llの逆。高い方。
27
- 28. これを応用して...
• 先ほど収束判定で以下を用いましたが
• 以下でも可能です。
> all(summary(fit)$summary[,“Rhat”] <= 1.10, na.rm = T)
# all() ()内で論理式を全て満たしたらTRUEを返す関数
[1] TRUE
> all(stan_rhat(fit)$data <= 1.10, na.rm = T)
# all() ()内で論理式を全て満たしたらTRUEを返す関数
[1] TRUE
28
- 30. おまけ extract()
• おれは要約統計量ではなく、発生させた乱数列全てがほしいんだ!!!と
言う方は、
• extract(fit)とすれば発生させた乱数列を抽出出来ます
• extractで抽出した乱数を用いて、median、mean等々を求めれば、もちろん、それがMAP、
EAP等になります。
この関数のオプションとして,,,
• inc_warmup=Tをつければ、バーンイン期間を含む乱数列がとれます。
• permuted=Tをつけると、同パラメータのchainが縦につながった状態で出
ます(list形式)。permuted=Fにすると同パラメータのchainが区別された状
態で出ます(3次元配列[ iter, chain, parameter ]形式)。
30