Up

PyStan3build関数とsample関数の備忘録

 

PyStan3を用いてのMCMCサンプリングはbuild関数とsample関数を用いるとできる。簡単な例をリスト1に示す。

なお、PyStan3用Stanの備忘録も用意した。

 

 

 

PyStan3のインストールは

 

pip install pystan

 

であるが、import

 

import stan

 

である。

 

Pythonスクリプトの実行は、Anaconda/ubuntu22/WSL/Windowsに設定したPython3.12仮想環境において行った。ただし、scipy1.12.0を利用している。このウェブサイトを参照されたい。

 

 

 

リスト1 簡単な例

 

import stan

import arviz as az

 

binomial_model = """

    data {

        int n;

        int k;

    }

    parameters {

        real<lower=0.0, upper=1.0> p;

    }

    model {

        k ~ binomial(n, p);

    }

"""

sm = stan.build(binomial_model, data={'n':10, 'k':7})

fit = sm.sample()

i_data = az.from_pystan(posterior=fit, posterior_model=sm)

print(az.summary(i_data))

 

 

 

文字列binomial_modelとして記述されたStanモデルと、辞書型で与えられたデータdata={'n':10, 'k':7}を引数として関数stan.buildを呼び出してビルドを行い、作成したモデルsmの関数sm.sampleを呼び出して、MCMCサンプリングを行っている。MCMCサンプリングの結果は、fitによって表されている。

fitの内容は、arvizの関数from_pystanによってInferenceData型のオブジェクトに変換した後、arvizの関数summaryによってMCMCサンプリングの統計量が算出されるが、これらを次のスクリプトで行っている。

 

i_data = az.from_pystan(posterior=fit, posterior_model=sm)

print(az.summary(i_data))

 

端末には、以下のように出力されている。

 

    mean     sd  hdi_3%  hdi_97%  mcse_mean  mcse_sd  ess_bulk  ess_tail  r_hat

p  0.669  0.132   0.426    0.904      0.004    0.003    1293.0    1444.0    1.0

 

 

関数buildsampleリスト1における例以外のパラメータも設定した例は、リスト4に示している。

 

 

 

 

Stanモデルが別のファイルに記述されている場合

 

 

リスト1では、StanモデルがPythonスクリプト内に記述されているが、これを別ファイルとして用意することもできる。

リスト2は、Stanモデルを別ファイルbinomial_pstan.stanとして用意したものである。

 

 

 

リスト2 Stanモデル(binomial_pstan.stan

 

data {

    int n;

    int k;

}

parameters {

    real<lower=0.0, upper=1.0> p;

}

model {

    k ~ binomial(n, p);

}

 

 

 

リスト2のファイルを読み込んで利用するPythonスクリプトを、リスト3に示す。

 

 

 

リスト3 リスト2のファイルbinomial_pstan.stanを読み込んで利用するPythonスクリプト

 

import stan

import arviz as az

 

with open('binomial_pstan.stan', 'r') as f_stan:

    sm = stan.build(f_stan.read(), data={'n':10, 'k':7})

fit = sm.sample()

 

print(fit)

i_data = az.from_pystan(posterior=fit, posterior_model=sm)

print(az.summary(i_data))

 

 

 

Stanモデルのファイルbinomial_pstan.stanf_stan.read()読み込んで文字列として、stan.buildの第1パラメータとしている。

 

with open('binomial_pstan.stan', 'r') as f_stan:

    sm = stan.build(f_stan.read(), data={'n':10, 'k':7})

 

Stanモデルを与える文字列が、ファイルの読み込みによって与えられていることを除いて、リスト1と同じである。

 

 

 

Buildsampleのパラメータ

 

 

関数buildsampleのよく用いる可能性のあるパラメータの使用例を、リスト4に示す。

 

 

リスト4 関数buildsampleのパラメータ例

 

import stan

import arviz as az

 

binomial_model = """

    data {

        int n;

        int k;

    }

    parameters {

        real<lower=0.0, upper=1.0> p;

    }

    model {

        k ~ binomial(n, p);

    }

"""

 

sm = stan.build(binomial_model, data={'n':10, 'k':7}, random_seed=12345)

fit = sm.sample(num_chains=4,

                init=[{'p':0.4}, {'p':0.5},{'p':0.6}, {'p':0.7}],

                num_samples = 2000,

                num_warmup = 1000)

print(fit)

i_data = az.from_pystan(posterior=fit, posterior_model=sm)

print(az.summary(i_data))

 

 

関数buildにおけるパラメータ

 

random_seed=12345

 

は、乱数の初期値(正整数)を設定するものである。スクリプトの実行を繰り返すとき、同じMCMCサンプルを得たいときに設定する。

 

関数sampleにおけるパラメータ

 

num_chains=4,

 

は、MCMCサンプリングにおけるマルコフ鎖の本数を指定するものである。

 

パラメータ

 

init=[{'p':0.4}, {'p':0.5},{'p':0.6}, {'p':0.7}]

 

は、マルコフ鎖の初期値を指定するものである。マルコフ鎖の本数だけ設定する。マルコフ鎖がwarm up時に安定しないとき、適切な初期値を設定すると安定することがある。

 

パラメータ

 

num_samples = 2000,

num_warmup = 1000

 

は、MCMCサンプル数とwarm up試行数を設定するものである。この指定は、各マルコフ鎖に対するものであり、warm up試行数のサンプリング後、num_samples数のサンプリングが行われる。MCMCサンプリングが安定しないときはnum_warmup数を増やして安定を期待することができる。事後分布の推定精度を上げるときは、num_samplesの値を大きくとることになる。

 

リスト4のスクリプトを実行すると、端末には以下の出力が表示される。

 

 

<stan.Fit>

Parameters:

    p: ()

Draws: 8000

   mean     sd  hdi_3%  hdi_97%  mcse_mean  mcse_sd  ess_bulk  ess_tail  r_hat

p  0.67  0.134   0.423    0.907      0.002    0.002    3140.0    3622.0    1.0

 

 

 

 

Home