RStan:MCMC収束の確認方法 を調査します。
Rstanでベイズモデリングを行う際、MCMC(マルコフ連鎖モンテカルロ法)サンプリングが正しく「収束」しているかを確認することは、得られた結果の信頼性を保証するために非常に重要です。収束していない場合、得られたサンプルは真の事後分布を反映しておらず、誤った結論を導く可能性があります。
ここでは、簡単なサンプルデータを用いて、MCMCの収束を確認する方法を調べます。
準備
1. 必要なパッケージの読み込み
rstan
と、結果の可視化のためにbayesplot
パッケージを使用します。
library(rstan)
library(bayesplot)
sapply(X = c("rstan", "bayesplot"), packageVersion)
<- "D:/stan_output" stan_output
$rstan
[1] 2 32 7
$bayesplot
[1] 1 13 0
2. サンプルデータの準備
平均10
、標準偏差2
の正規分布から100個のデータを生成します。このmu=10
とsigma=2
を、Rstanで推定するターゲットとします。
<- 20250626
seed set.seed(seed)
<- 100
N <- 10
mu_true <- 2
sigma_true <- rnorm(N, mean = mu_true, sd = sigma_true) y
RstanでのモデリングとMCMC実行
1. Stanモデルの記述
観測データy
が正規分布に従うと仮定し、その平均mu
と標準偏差sigma
を推定するモデルを記述します。
# Stanモデル
<- "
stan_model data {
int<lower=0> N; // データ数
vector[N] y; // 観測データ
}
parameters {
real mu; // 推定する平均
real<lower=0> sigma; // 推定する標準偏差(正の値のみ)
}
model {
// 事前分布(弱い無情報事前分布)
mu ~ normal(0, 100);
sigma ~ cauchy(0, 5);
// 尤度
y ~ normal(mu, sigma);
}
"
2. MCMCサンプリングの実行
作成したモデルとデータを使って、MCMCサンプリングを実行します。ここでは4つのチェーンを走らせます。
rstan_options(auto_write = TRUE)
options(mc.cores = parallel::detectCores())
# Stanに渡すためのデータリストを作成
<- list(N = N, y = y)
dat
# MCMCの実行
<- stan(
fit model_code = stan_model, # Stanモデル
data = dat, # データ
iter = 2000, # サンプリング回数(ウォームアップ含む)
warmup = 1000, # ウォームアップ(捨てる)期間
chains = 4, # チェーンの数
seed = seed # MCMCの再現性のための乱数シード
)
# stanfit オブジェクトの保存
setwd(stan_output)
saveRDS(object = fit, file = "stan_fit.rds")
-
iter
: 1チェーンあたりのサンプリング総数 -
warmup
: パラメータの初期値の影響をなくすための準備期間。この期間のサンプルは捨てられます。 -
chains
: 独立したMCMCをいくつ実行するか。複数(通常は3〜4以上)実行し、それらが同じ結果に収束するかを確認します。
MCMC収束の確認方法
①視覚的な確認と②数値的な確認による収束診断を以下に示します。
① 視覚的な確認:トレースプロット
トレースプロットは、各MCMCステップにおけるパラメータのサンプル値を時系列でプロットしたものです。これにより、サンプリングが安定しているかを視覚的に確認できます。
チェックポイント
- よく混ざっているか (Well-mixed): 複数のチェーン(色違いの線)が、区別できないほどよく混ざり合っているのが理想です。
- 定常性: プロット全体に特定のトレンド(上昇/下降傾向)がなく、ある一定の範囲を安定して動き回っているか。
# トレースプロットの描画
setwd(stan_output)
<- readRDS("stan_fit.rds")
fit mcmc_trace(fit, pars = c("mu", "sigma"))
このプロットの解釈:
-
mu
とsigma
のどちらのプロットも、4つのチェーン(4色の線)が重なり合って区別がつかず、全体として安定した帯状になっています。 - 特定のトレンドは見られず、定常状態に達していると考えられます。
- これは収束が良好であることを強く示唆しています。
② 数値的な確認:R-hat (\(\\hat{R}\)) と n_eff
Rstanのsummary()
(あるいはprint()
)関数で、重要な診断指標を確認できます。
# 結果の要約を表示
print(fit, pars = c("mu", "sigma", "lp__"))
Inference for Stan model: anon_model.
4 chains, each with iter=2000; warmup=1000; thin=1;
post-warmup draws per chain=1000, total post-warmup draws=4000.
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
mu 9.76 0.00 0.20 9.36 9.62 9.76 9.90 10.16 3150 1
sigma 2.04 0.00 0.15 1.78 1.94 2.04 2.14 2.36 3407 1
lp__ -120.45 0.02 1.00 -123.20 -120.87 -120.15 -119.73 -119.46 1882 1
Samples were drawn using NUTS(diag_e) at Thu Jun 26 06:58:03 2025.
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).
1. R-hat (\(\\hat{R}\))
R-hatは、チェーン内分散とチェーン間分散を比較することで、チェーンが同じ分布に収束したかを評価する指標です。
- 判断基準:
Rhat
< 1.1(より厳しく 1.05 や 1.01 を基準にすることもあります) - 理想:
Rhat
が1.0に近いほど良い。
今回の結果の解釈: 上の結果を見ると、mu
とsigma
のRhat
は両方とも1
です。これは、4つのチェーンが同じ分布にうまく収束したことを示しており、収束は良好と判断できます。
2. 有効サンプルサイズ (n_eff)
n_eff
(Effective Sample Size)は、MCMCサンプル間の自己相関を考慮した、実質的に独立なサンプルの数を示します。
- 判断基準:
n_eff
が小さすぎると(例えば100未満)、事後分布の推定が不安定になる可能性があります。多ければ多いほど良いです。 - 自己相関との関係: MCMCサンプルは通常、自己相関を持ちます(1つ前のサンプルと似ている)。自己相関が高いと
n_eff
は小さくなります。
今回の結果の解釈: n_eff
はmu
で3150 、sigma
で3407です。総サンプル数4000に対して十分に大きな値であり、事後分布を要約するのに十分なサンプルが得られていると言えます。
③ その他の視覚的確認
bayesplot
には他にも便利な関数があります。
事後分布のプロット
各チェーンから得られた事後分布を重ねて描画し、形状が一致しているかを確認します。
# ヒストグラムで事後分布を確認
mcmc_hist(fit, pars = c("mu", "sigma"))
# 密度プロットで事後分布を確認
mcmc_dens_overlay(fit, pars = c("mu", "sigma"))
解釈: 4つのチェーンから得られた分布がほぼ重なっており、Rhat
が1であったことを視覚的にも裏付けています。
自己相関プロット
サンプルの自己相関がどのくらいの速さで減衰するかを確認します。減衰が速い(すぐに0に近づく)ほど、効率的なサンプリングができており、n_eff
が大きくなります。
mcmc_acf(fit, pars = c("mu", "sigma")) + ggplot2::scale_x_continuous(breaks = scales::pretty_breaks(10))
解釈: ラグ1以降の自己相関が急速に0に近づいています。これはサンプルの自己相関が低く、効率的なサンプリングが行われたことを示します。
まとめ
以下にMCMCの収束確認方法をまとめます。
- トレースプロット(視覚的確認): チェーンがよく混ざり、定常的で、“毛虫”のようになっているかを確認する。
- R-hat(数値的確認):
Rhat
が1.1未満(理想は1.0に近い)ことを確認する。 - n_eff(数値的確認):
n_eff
が十分に大きいことを確認する。 - その他のプロット(補助的確認): 事後分布のオーバーレイプロットや自己相関プロットで、収束を多角的に確認する。
これらの診断をすべてクリアして初めて、print(fit)
で表示されるmean
(事後平均値)や95%
区間(95%ベイズ信用区間)などを信頼して解釈することができます。もし収束に問題がある場合は、iter
やwarmup
の回数を増やしたり、モデルの書き方(再パラメータ化)を見直すなどの対策が必要になります。
以上です。