The One with ...

思いついたことや作業メモなどを公開しています

ベイズファクタ計算用サンプルコード

授業で使ったベイズファクタ計算用のコードのメモです*1

必要なパッケージのロード

library(rstan)
library(bridgesampling)

パッケージがなければ,

install.packages("bridgesampling")

でインストールします.

stanでのコンパイルの効率化のために,以下を指定します(いつものやつ).

rstan_options(auto_write=TRUE)#コンパイルを保存する設定
options(mc.cores=parallel::detectCores())#マルチコア計算用設定

データの生成

平均0分散1の正規分布にしたがう乱数を1000個生成し、stanコードでパラメタリカバリします. データの生成

set.seed(123)
y <- rnorm(1000, mean = 0, sd = 1)

Stanコード

stanでモデルを定義します.コードは,BF比較用に事前分布も含めて全てtarget記法で書きます. stanファイルを使わずに,すべてR内で完結するように,Rコード上でstanモデルを定義します.

# Stan code for parameter recovery
m0 <- "
data {
    int<lower=0> N;
    vector[N] y;
}

parameters {
    real mu;
    real<lower=0> sigma;
}

model {
    target += normal_lpdf(mu | 0, 1); // prior for mu
    target += normal_lpdf(sigma | 0, 1); // prior for sigma
    target += normal_lpdf(y | mu, sigma); // likelihood
}

"

# 平均位置がズレている
m1 <- "
data {
    int<lower=0> N;
    vector[N] y;
}
parameters {
    real<lower=0> sigma;
}
model {
    target += normal_lpdf(sigma | 0, 1); // prior for sigma
    target += normal_lpdf(y | 0.5, sigma); // likelihood
}
"

# m0に比べて事前分布のサポートが広い場合
m2 <- "
data {
    int<lower=0> N;
    vector[N] y;
}

parameters {
    real mu;
    real<lower=0> sigma;
}

model {
    target += normal_lpdf(mu | 0, 10); // prior for mu
    target += normal_lpdf(sigma | 0, 10); // prior for sigma
    target += normal_lpdf(y | mu, sigma); // likelihood
}
"

Prepare data for Stan

stan用にデータを定義します.

data <- list(N = length(y), y =y)

Compile the Stan model

stanモデルをコンパイルします

model0 <- stan_model(model_code = m0)
model1 <- stan_model(model_code = m1)
model2 <- stan_model(model_code = m2)

Fit the model

サンプリング結果を格納します.

fit0 <- sampling(model0, data = data, iter = 5000, chains = 3)
fit1 <- sampling(model1, data = data, iter = 5000, chains = 3)
fit2 <- sampling(model2, data = data, iter = 5000, chains = 3)

Bridge sampling

ブリッジサンプリングします

bs0 <- bridge_sampler(fit0)
bs1 <- bridge_sampler(fit1)
bs2 <- bridge_sampler(fit2)

自由エネルギー

ブリッジサンプリングした結果を使って自由エネルギを計算します

-logml(bs0)
-logml(bs1)
-logml(bs2)

Compare free energies

ベイズファクタを計算します.直感的に言うと,bf(bs0, bs1)bs1(後ろ)に対してbs0(前)が,相対的にどれくらいよいのかを表します. 慣習的な目安として10より大きければ,強い支持を与えると考えられている.

bf(bs0, bs1)
bf(bs0, bs2)

*1:自分用メモ.このコードは (略)hogehoge\授業\active\RStanBook-master\chap08\bf_sample.R に保存している.いいかげん全てgithubにアップしてちゃんと管理せい,と自分に言いたい.