バナナでもわかる話

計量経済学・統計学が専門の大学院生です。統計学・経済学・投資理論・マーケティング等々に関する勉強・解説ブログ。ときどき趣味も。極力数式は使わずイメージで説明出来るよう心掛けていますが、時々暴走します。

Stan入門

前回はRstanの導入と実例に関する記事を書きました。
bananarian.hatenablog.com


しかし、まあ実例なのでコードはなんとなくで見てくださいとは言ったものの、よくわからんなあといった感じで記事を眺めていた人も多かったのではないでしょうか。



今回はStanのコードの構成と文法について焦点をあてて、入門編をやっていきます。



Stanの基本構造

まず、Stanの基本構造は次のようになっています。

data{  
使うデータに関する情報の宣言 
} 
 
parameters{  
サンプリングしたいパラメータ θ の宣言 
} 
 
model{  
尤度や事前分布の設定によるモデルの構築 
} 

ちなみに前回の例だとこんな感じでした。

data {
int N;
real X[N];
real Y[N];
}
parameters {
real a;      
real<lower=0> sigma;
}
model {
for(i in 1:N) {
Y[i] ~ normal(a*X[i], sqrt(sigma));
}
}

ちなみにこのdata{}やparameters{}などといった大きな枠組みをブロックと呼びます。
stanを実行するには最低限dataブロックとparametersブロックとmodelブロックがきちんと記述されている必要があります。
ほかにもtransformed parametersブロックなどもありますが、とりあえず入門なので省略しておきます。


データブロック

今回使うデータに関する宣言を行う場所です。変数の型(整数(int)なのか、実数(real)なのか等々)を指定する必要があります。
また、このブロックに限らず、stanでは行が変わる際はセミコロン(;)をつけてやる必要があります。


ちなみに今回のコードを詳しく説明すると、

int N:integer(整数)のこと。N には整数値しか入らないという意味です。

real Y[N]:real は実数値が入ることを示します。

Y[N]の[ ]は列のことで、Y[1],Y[2],…,Y[N]の N 個の変数があることを表します。




パラメータブロック

今回サンプリングして、事後分布を知りたいパラメータを指定するブロックです。

real sigma : sigmaは0以上の実数であるという宣言です。


モデルブロック

ここで、パラメータブロックとデータブロックで宣言した変数達を使って、モデルを作っていきます。
モデルを作るといっても、何か計算したりする必要はなくて、各データが従う尤度とパラメータが従う事前分布を設定してやれば、後は勝手にやってくれます。

とは言ってもデータの変数が1からNまであって、一個ずつ書いていくと大変なので、for関数を利用します。


for(i in 1:N) {
Y[i] ~ normal(a*X[i], sqrt(sigma));
}


RやらPythonやら何かしらをいじったことのある人にとってはおなじみの繰り返し処理してくれるやつです。「~」を使うことで、以下の分布に従っていますよとコンピュータに知らせることが出来ます。

ちなみに、今回の例は事前分布を明示していませんが、パラメータの事前分布を明示しなかった場合は自動的に、そのパラメータの範囲に合った無情報事前分布(一様分布)が選択されます。
無情報事前分布についてよく知らない人はまた別の記事で説明するのでお待ちください。今は一様分布だと思っておいてください。



とりあえず以上ですね。これで何となくStanのコードの意味合いが分かったかと思うので、次からはまたベイズに戻ろうと思いますね。

後は必要になった時に追加でコードやブロックの説明をしてこうと思います。