用意するもの。
統計パッケージRと,Rを使いやすくしてくれる統合環境RStudioを用意しよう。
Rのサイトはこちらから。
Rstudioはこちらから。
三つ全てインストールが終わったら,RStudioを起動してみよう。
Rはパッケージを取り込むことで機能が増えていきます。 今後のことを考えて心理学関係のパッケージとベイズ関係のパッケージを一気に取り込んじゃおう!
install.packages("ctv") #install.packagesはパッケージをインストールする関数。
require(ctv) #requireあるいはlibraryはパッケージを装備する関数。
install.views("Psychometrics") #ctvパッケージにある,関係パッケージをまとめて入れる関数
install.views("Bayes") #Bayes関係のパッケージをじゃんじゃん入れてしまう!
実は準備が整っていたら,ここで何の苦労もない。(バージョン2.7からの恩恵!)
install.packages("rstan")
とっても簡単だね。
今更ながら,Stanプロジェクトのサイトを紹介しておきます。ここのInterfacesにRstan(stanのRインターフェイス)があります。
もうひとつ。stanの結果を見やすくするためのアプリ,shinyStanというのも入れておきます。 入れるためのコードは次の通り。
install.packages("shinystan",repos='http://cran.rstudio.com')
インストールが終わったら,Rstanの「事始め」ページにある,次のコードを実行してみよう。
require(rstan)
## Loading required package: rstan
## Loading required package: Rcpp
## Loading required package: inline
##
## Attaching package: 'inline'
##
## 以下のオブジェクトは 'package:Rcpp' からマスクされています:
##
## registerPlugin
##
## rstan (Version 2.7.0-1, packaged: 2015-07-17 18:12:01 UTC, GitRev: 05c3d0058b6a)
## For execution on a local, multicore CPU with excess RAM we recommend calling
## rstan_options(auto_write = TRUE)
## options(mc.cores = parallel::detectCores())
rstan_options(auto_write = TRUE)
options(mc.cores = parallel::detectCores())
これは何も起こらないと思いますが,「できるだけ早くしてね」という意味です。 実際に動かすのは次のコード。
stancode <- '
data {
int<lower=0> J; // number of schools
real y[J]; // estimated treatment effects
real<lower=0> sigma[J]; // s.e. of effect estimates
}
parameters {
real mu;
real<lower=0> tau;
real eta[J];
}
transformed parameters {
real theta[J];
for (j in 1:J)
theta[j] <- mu + tau * eta[j];
}
model {
eta ~ normal(0, 1);
y ~ normal(theta, sigma);
}
'
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(model_code = stancode, data = schools_dat,
iter = 1000, chains = 4)
## COMPILING THE C++ CODE FOR MODEL '19c33eca0c63b510805d5af1962613a7' NOW.
print(fit)
## Inference for Stan model: 19c33eca0c63b510805d5af1962613a7.
## 4 chains, each with iter=1000; warmup=500; thin=1;
## post-warmup draws per chain=500, total post-warmup draws=2000.
##
## mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
## mu 7.96 0.28 5.78 -4.48 4.75 7.86 11.18 20.22 434 1.00
## tau 7.14 0.42 6.31 0.20 2.54 5.56 10.07 22.53 222 1.01
## eta[1] 0.42 0.03 0.91 -1.38 -0.20 0.43 1.04 2.20 1087 1.00
## eta[2] -0.02 0.03 0.86 -1.80 -0.58 0.01 0.56 1.70 1162 1.00
## eta[3] -0.20 0.03 0.96 -2.09 -0.84 -0.19 0.43 1.70 1173 1.00
## eta[4] -0.04 0.03 0.90 -1.86 -0.62 0.00 0.55 1.70 1164 1.00
## eta[5] -0.34 0.03 0.87 -2.00 -0.89 -0.35 0.21 1.46 1157 1.00
## eta[6] -0.21 0.03 0.86 -1.91 -0.74 -0.20 0.35 1.54 1176 1.00
## eta[7] 0.29 0.03 0.87 -1.36 -0.33 0.32 0.88 1.93 1060 1.00
## eta[8] 0.06 0.02 0.90 -1.71 -0.55 0.07 0.67 1.76 1378 1.00
## theta[1] 11.92 0.32 8.52 -0.77 6.22 10.17 16.37 32.86 718 1.00
## theta[2] 8.08 0.16 6.21 -4.49 4.27 8.04 11.85 20.36 1523 1.00
## theta[3] 5.93 0.32 8.53 -14.03 1.73 6.65 10.79 22.24 721 1.00
## theta[4] 7.72 0.16 6.48 -5.25 4.13 7.61 11.65 20.86 1673 1.00
## theta[5] 5.17 0.17 6.39 -9.63 1.53 5.91 9.32 16.69 1395 1.00
## theta[6] 6.15 0.18 6.59 -8.71 2.45 6.53 10.06 18.76 1326 1.00
## theta[7] 10.65 0.20 6.84 -1.38 6.18 9.84 14.55 26.31 1189 1.00
## theta[8] 8.73 0.34 8.71 -7.98 4.05 8.32 13.01 27.84 655 1.00
## lp__ -4.77 0.14 2.81 -10.99 -6.49 -4.53 -2.79 0.19 375 1.01
##
## Samples were drawn using NUTS(diag_e) at Mon Sep 7 16:35:59 2015.
## For each parameter, n_eff is a crude measure of effective sample size,
## and Rhat is the potential scale reduction factor on split chains (at
## convergence, Rhat=1).
plot(fit)
これらの結果が何を表すか,はおいおい説明するとして,動くかどうかの確認をこれで済ませてください。
うまくいったら,Shinystanでの結果の確認の仕方も確認しておきましょう。
require(shinystan)
launch_shinystan(fit)
RStudioはプロジェクト単位でソースコードを管理することができる。 今回の分析用に,新しくプロジェクトを作り,そこに様々なソースコードをいれておくようにしよう。
データを正規分布に基づいて発生させ,そのデータがどんな正規分布から出てきたか推定させる,というコードです。 答えがわかっている問題を解かせるわけだから,実質的な意味はないんだけど,stanのコードがどういうものなのかを知るために。
require(rstan)
n <- 100
mu <- 50
sig <- 10
y <- rnorm(n,mu,sig)
hist(y)
stancode <- '
data{
int<lower=0> T;
real N[T]; // data
}
parameters {
real mu;
real<lower=0> s2;
}
model{
N~normal(mu,sqrt(s2));
s2~cauchy(0,5);
}
'
datastan <- list(N=y,T=n)
fit <- stan(model_code = stancode,data=datastan,iter=5000,chain=4)
## COMPILING THE C++ CODE FOR MODEL '2252c37f415db79c9e3f3198c1fa1980' NOW.
traceplot(fit,ask=T)
print(fit,digit=3)
## Inference for Stan model: 2252c37f415db79c9e3f3198c1fa1980.
## 4 chains, each with iter=5000; warmup=2500; thin=1;
## post-warmup draws per chain=2500, total post-warmup draws=10000.
##
## mean se_mean sd 2.5% 25% 50% 75% 97.5%
## mu 48.990 0.012 0.911 47.207 48.368 48.997 49.598 50.798
## s2 85.285 0.160 12.078 65.066 76.709 84.161 92.679 112.005
## lp__ -274.039 0.018 0.983 -276.712 -274.425 -273.735 -273.345 -273.084
## n_eff Rhat
## mu 6146 1.000
## s2 5724 1.000
## lp__ 2918 1.001
##
## Samples were drawn using NUTS(diag_e) at Mon Sep 7 16:36:27 2015.
## For each parameter, n_eff is a crude measure of effective sample size,
## and Rhat is the potential scale reduction factor on split chains (at
## convergence, Rhat=1).
今度はもう少し複雑なコード。 二番目に簡単なrstanコードからの丸パクリです。
今回は回帰分析モデルにもとづいてデータを発生させ,それをstanに解かせるというもの。 これもコードの練習でしかないんだけど,「データ生成モデルから統計モデルを見る」という感覚に開眼してください。つまり,現実的には生成モデルはわからないデータだけがあるわけで,データの奥を見通す目を持つというか,そういうことをしているだという理解の仕方を。
N <- 1000
x <- rnorm(N, mean = 50, sd = 10)
y <- 10 + 0.8 * x + rnorm(N, mean =0, sd = 7)
plot(x,y)
abline(lm(y~x),col=2)
stancode <- '
data{
int<lower=0> N;
real x[N];
real y[N];
}
parameters {
real alpha;
real beta;
real<lower=0> s;
}
model{
for(i in 1:N)
y[i] ~ normal(alpha + beta * x[i], s);
alpha ~ normal(0, 100);
beta ~ normal(0, 100);
s ~ cauchy(0,5);
}
'
datastan <- list(N=N, x=x, y=y)
fit <- stan(model_code=stancode, data=datastan, iter=1000, chain=4)
## COMPILING THE C++ CODE FOR MODEL '68cb52b4d2351820fa0138861c46e315' NOW.
traceplot(fit, ask=T)
print(fit, digit=2)
## Inference for Stan model: 68cb52b4d2351820fa0138861c46e315.
## 4 chains, each with iter=1000; warmup=500; thin=1;
## post-warmup draws per chain=500, total post-warmup draws=2000.
##
## mean se_mean sd 2.5% 25% 50% 75% 97.5%
## alpha 10.59 0.05 1.12 8.42 9.80 10.58 11.36 12.80
## beta 0.79 0.00 0.02 0.74 0.77 0.79 0.80 0.83
## s 7.36 0.01 0.17 7.03 7.24 7.36 7.46 7.69
## lp__ -2495.45 0.06 1.22 -2498.70 -2495.96 -2495.14 -2494.58 -2494.09
## n_eff Rhat
## alpha 582 1.00
## beta 582 1.00
## s 578 1.01
## lp__ 483 1.00
##
## Samples were drawn using NUTS(diag_e) at Mon Sep 7 16:36:56 2015.
## For each parameter, n_eff is a crude measure of effective sample size,
## and Rhat is the potential scale reduction factor on split chains (at
## convergence, Rhat=1).
基本はこういうスタイル。モデルとデータ生成分布を考えてstanに推定させてやる,という考え方です。 どういうモデルがいいのか(あるのか),どういう分布がいいのか(あるのか)というのはおいおいわかっていくと思います。
Enjoy!
追伸;RStanの導入と基本的な使い方についてのスライドも見ておいてね。