「研究ソフト/MCMCサンプラー」の編集履歴(バックアップ)一覧はこちら

研究ソフト/MCMCサンプラー」(2017/06/22 (木) 20:55:24) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

* MCMCサンプラー このページでは、ベイズモデルのパラメータ推定に不可欠な(自分でプログラムを書ける人は別ですが)、MCMCサンプラーの「使い方」について説明します。 | 名称 | WinBUGS | OpenBUGS | JAGS | Stan | | 利用可能OS | Windows(頑張ればMacも)| Windows(頑張ればMacも)| マルチプラットフォーム | マルチプラットフォーム | | 長所 | car.normal()が使える。 | WinBUGSとほぼ同じ操作。 | 多項モデルの計算が速い。エラー個所の特定が容易。 | 収束が速い。エラー個所の特定が容易。空間自己相関を考慮可能。 | | 短所 | 開発は止まっている。エラーメッセージが理解不能。プログラムは非公開。 | WinBUGSと同じ。 | 推定の実行が複数段階にわたり面倒くさい。結果のオブジェクトがそのままでは使いにくい。| 離散パラメータを推定できない。1stepあたりの計算速度が遅い。 | | 公式サイト | [[The BUGS project>http://www.mrc-bsu.cam.ac.uk/software/bugs/the-bugs-project-winbugs/]] | [[OpenBUGS>http://www.openbugs.net/w/FrontPage]] | [[JAGS>http://mcmc-jags.sourceforge.net/]] | [[Stan>http://mc-stan.org/]] | | インストール方法 | [[北大の久保先生のページ>http://hosho.ees.hokudai.ac.jp/~kubo/ce/HowtoInstallWinBUGS.html]] | | | [[2012年度統計数理研究所共同研究集会「データ解析環境Rの整備と利用」>http://prcs.ism.ac.jp/useRjp/hiki.cgi?2012%C7%AF%C5%D9+%A5%C7%A1%BC%A5%BF%B2%F2%C0%CF%B4%C4%B6%ADR%A4%CE%C0%B0%C8%F7%A4%C8%CD%F8%CD%D1]]の石倉さんのスライド、[[BUGSstan勉強会>http://atnd.org/events/43260]]、[[R stan導入公開版>http://www.slideshare.net/KojiKosugi/r-stan]] | #contents ** 使うデータ #データの生成 set.seed(1) N <- 100 Nplot <- 4 Nsigma <- 2 y <- rnorm(N, 0, 5) x1 <- y + rnorm(N, 0, 5) x2 <- rnorm(N, 0, 1) x3 <- as.numeric(cut(y + rnorm(N, 0, 5), Nplot, labels=1:Nplot)) ** WinBUGS *** データの定義 データは、データ名のベクトルを与えます。 data <- c("N", "Nplot", "Nsigma", "y", "x1", "x2", "x3") *** 初期値の設定 WinBUGSにまつわるエラーの大半はここが原因です。間違いのないように指定しましょう。 inits <- list(list(alpha = 0, bx1 = 0, bx2 = 0, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)), list(alpha = -5, bx1 = -5, bx2 = -5, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)), list(alpha = 5, bx1 = 5, bx2 = 5, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)) ) *** 結果として得たいパラメータの定義 para <- c("alpha", "bx1", "bx2", "bx3", "sigma") *** モデルの記述 #モデルのファイルを別に用意する場合は、model { }の部分だけ書いてファイルに保存して下さい。 modelFilename = "testmod.txt" cat(" model { for (i in 1:N) { y[i] ~ dnorm(mu[i], tau[1]) mu[i] <- alpha + bx1*x1[i] + bx2*x2[i] + bx3[x3[i]] } alpha ~ dnorm(0.0, 1.0E-6) bx1 ~ dnorm(0.0, 1.0E-6) bx2 ~ dnorm(0.0, 1.0E-6) for (i in 1:Nplot) { bx3[i] ~ dnorm(0.0, tau[2]) } for (i in 1:Nsigma) { tau[i] <- pow(sigma[i], -2) sigma[i] ~ dunif(0, 100) } } ", fill=TRUE, file=modelFilename) *** 計算の実行 library(R2WinBUGS) res <- bugs(data, inits, para, model=modelFilename, n.burnin = 500, n.iter=6500, n.chains=3, n.thin=6, bugs.directory="C:/WinBUGS14/", #デフォルトのフォルダから変更している場合のみ指定 working.directory=getwd(), debug=TRUE ) *** 結果の確認 print(res$summary, digits=3) plot(res) - 昔の[[R2WinBUGSに関するページ>研究ソフト/R2WinBUGS]] ** R2OpenBUGS 基本的に、WinBUGSの場合とほとんど一緒です。データの定義、初期値の定義、パラメータの指定は完全に一緒。 *** データの定義 データは、データ名のベクトルを与えます。 data <- c("N", "Nplot", "Nsigma", "y", "x1", "x2", "x3") *** 初期値の設定 inits <- list(list(alpha = 0, bx1 = 0, bx2 = 0, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)), list(alpha = -5, bx1 = -5, bx2 = -5, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)), list(alpha = 5, bx1 = 5, bx2 = 5, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)) ) *** 結果として得たいパラメータの定義 para <- c("alpha", "bx1", "bx2", "bx3", "sigma") *** モデルの記述 #モデルのファイルを別に用意する場合は、model { }の部分だけ書いてファイルに保存して下さい。 modelFilename = "testmod.txt" cat(" model { for (i in 1:N) { y[i] ~ dnorm(mu[i], tau[1]) mu[i] <- alpha + bx1*x1[i] + bx2*x2[i] + bx3[x3[i]] } alpha ~ dnorm(0.0, 1.0E-6) bx1 ~ dnorm(0.0, 1.0E-6) bx2 ~ dnorm(0.0, 1.0E-6) for (i in 1:Nplot) { bx3[i] ~ dnorm(0.0, tau[2]) } for (i in 1:Nsigma) { tau[i] <- pow(sigma[i], -2) sigma[i] ~ dunif(0, 100) } } ", fill=TRUE, file=modelFilename) *** 計算の実行 library(R2OpenBUGS) res2 <- bugs(data, inits, para, model=modelFilename, n.burnin = 500, n.iter=6500, n.chains=3, n.thin=6, OpenBUGS.pgm="C:/OpenBUGS322/OpenBUGS.exe", #プログラムまでフルパスを指定 working.directory=getwd(), debug=TRUE ) ** JAGS 前者2つと比べると、多少データの指定方法などが異なります。 *** データの定義 データは、リスト形式で準備して下さい。 list.data <- list(N=N, Nplot=Nplot, Nsigma=Nsigma, y=y, x1=x1, x2=x2, x3=x3) *** 初期値 ここはWinBUGSなどと一緒です。 inits <- list(list(alpha = 0, bx1 = 0, bx2 = 0, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)), list(alpha = -5, bx1 = -5, bx2 = -5, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)), list(alpha = 5, bx1 = 5, bx2 = 5, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)) ) *** 結果として得たいパラメータの指定 ここもWinBUGSなどと一緒です。 para <- c("alpha", "bx1", "bx2", "bx3", "sigma") *** モデルの記述 #モデルのファイルを別に用意する場合は、model { }の部分だけ書いてファイルに保存して下さい。 modelFilename = "testmod.txt" cat(" model { for (i in 1:N) { y[i] ~ dnorm(mu[i], tau[1]) mu[i] <- alpha + bx1*x1[i] + bx2*x2[i] + bx3[x3[i]] } alpha ~ dnorm(0.0, 1.0E-6) bx1 ~ dnorm(0.0, 1.0E-6) bx2 ~ dnorm(0.0, 1.0E-6) for (i in 1:Nplot) { bx3[i] ~ dnorm(0.0, tau[2]) } for (i in 1:Nsigma) { tau[i] <- pow(sigma[i], -2) sigma[i] ~ dunif(0, 100) } } ", fill=TRUE, file=modelFilename) *** 計算の実行 #パッケージの読み込み library(rjags) #計算開始時間を記録 start.time <- Sys.time() #初期化 m <- jags.model(file = modelFilename, data = list.data, # inits = inits, #JAGSは初期値を与えなくても上手く計算してくれます。こける場合は指定してください。 n.chain = 3 ) update(m, 500) x <- coda.samples(m, para, thin = 6, n.iter = 6000 ) #終了時間を記録、表示 end.time <- Sys.time() elapsed.time <- difftime(end.time, start.time, units='hours') cat(paste(paste('Posterior computed in ', elapsed.time, sep=''), ' hours\n', sep='')) *** 結果の確認 res <- data.frame(summary(x)$statistics) ci <- data.frame(summary(x)$quantiles) res$sig <- abs(sign(ci[, 1]) + sign(ci[, 5])) == 2 # Calculation of "R-hat" for convergence checking rhat <- gelman.diag(x)[["psrf"]][, 1] res$Rhat <- rhat ** Stan StanはBUGS系と比べると、色々な点で違いがあります。 *** データの定義 list.data <- list(N=N, Nplot=Nplot, Nsigma=Nsigma, y=y, x1=x1, x2=x2, x3=x3) *** 初期値の設定 inits <- list(list(alpha = 0, bx1 = 0, bx2 = 0, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)), list(alpha = -5, bx1 = -5, bx2 = -5, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)), list(alpha = 5, bx1 = 5, bx2 = 5, bx3 = rnorm(Nplot, 0, 1), sigma = rnorm(Nsigma, 50, 1)) ) *** 結果として得たいパラメータの定義 para <- c("alpha", "bx1", "bx2", "bx3", "sigma") *** モデルの記述 modelfile <- ' data { int<lower=0> N; //整数はint int<lower=0> Nplot; int<lower=0> Nsigma; real y[N]; //実数はreal real x1[N]; real x2[N]; int<lower=0> x3[N]; } parameters { real alpha; real bx1; real bx2; real bx3[Nplot]; real<lower=0> sigma[Nsigma]; //分散パラメータなので、負にならないように範囲を指定 } model { for (i in 1:Nplot) bx3[i] ~ normal(0.0, sigma[2]); for (i in 1:N) y[i] ~ normal(alpha + bx1*x1[i] + bx2*x2[i] + bx3[x3[i]], sigma[1]); //事前分布を指定しない場合、自動的に一様分布が事前分布として与えられます } ' *** 計算の実行 library(rstan) #BUGS系と引数の名称が微妙に異なります fit <- stan(model_code = modelfile, data = list.data, par = para, inits=inits, iter = 1000, chains = 3, thin=1, init=inits) [[Hirokiさん>http://ito-hi.blog.so-net.ne.jp/2015-07-26]]によると、Stanのバージョン2.7.0から並列化が簡単にできるようになったとのことです。便利! #並列化する場合 rstan_options(auto_write = TRUE) options(mc.cores = parallel::detectCores()) fit <- stan(model_code = modelfile, data = list.data, par = para, inits=inits, iter = 1000, chains = 3, thin=1, init=inits) *** 結果の確認 print(fit, digits=3) plot(fit) #パラメータが多くて部分表示したい場合は一度データフレーム型に変換すると便利 res <- as.data.frame(summary(fit))[1:10] colnames(res) <- c("mean", "se", "sd", "ci2.5", "ci25", "ci50", "ci75", "ci97.5", "neff", "Rhat") head(res) #同じように、パラメータが多くて一部のトレースだけを確認したい場合は以下のようにする traceplot(fit, pars=c("alpha", "bx1"))
このページは、[[こちら>https://hayatoiijima.jimdo.com/%E7%B5%B1%E8%A8%88%E8%A7%A3%E6%9E%90/mcmc%E3%82%B5%E3%83%B3%E3%83%97%E3%83%A9%E3%83%BC/]]に移転しました。

表示オプション

横に並べて表示:
変化行の前後のみ表示: