最尤推定: 推定値が真の値に近づいていく
ベイズ推定: 確率分布がどんどん尖り、確信が強まる
移項するだけでベイズの定理:
宴会場にビールが運ばれてきた。これはどこのブルワリーの?
$\text{Prob}(M \mid P)$ 真陽性率(検査陽性の人が実際に感染者である確率)は?
感染者を隔離するスクリーニング目的では使いものにならない性能。
🔰 同様に $\text{Prob}(\overline{M} \mid N)$ 真陰性率を計算してみよう
🔰 計算結果が検査性能だけでなく有病率にも依存することを確認しよう
モデル$M$に対する確信度合いをデータ$D$に基づいて更新する。
モデル$M$を仮説$H$やパラメータ$\theta$に置き換えてもいい。
周辺尤度は「確率分布の積分は1」を満たすための正規化定数とみなせる。
比例関係だけ抜き出してこう書くことが多い:
コイントスを繰り返して、表が出る確率pをベイズ推定したい。
事前分布にはベータ分布を採用(理由は後で分かる):
分布の形は $a,~b$ によって決まる。
ガンマ関数の部分は厳つく見えるけどただの正規化定数。
投げる前なのでとりあえず真っ平らを仮定 $\text{Beta}(p \mid a = 1, b = 1)$:
4回投げて表が1回だった、というデータで尤度を計算(二項分布):
これに事前分布を掛けて正規化したら事後分布になるはず。
なんと、事後分布もベータ分布になる。
ベータ分布の形パラメータ$a$が表、$b$が裏の回数分だけ増加。
さっきの事後分布を事前分布として、さらにデータを集める。
コイントス4回のうち表1回、に基づく事前分布: $\text{Beta}(p \mid 2,~4)$
さらに16回投げたら表が7回、の尤度: $\text{Binomial}(7 \mid 16,~p)$
事後分布はまた事前分布と同じ形になる:
データを加えるたびに更新していける:
事後分布が事前分布と同じ形なので計算しやすい、という組み合わせ。
尤度関数 | 共役事前分布 |
---|---|
二項分布 | ベータ分布 |
ポアソン分布 | ガンマ分布 |
正規分布 | ガンマ分布 |
正規分布 (分散既知) | 正規分布 |
共役事前分布を使うことが常に正しいとも限らない。
計算コストがかかっても無情報事前分布を使う風潮。
コイン投げモデルのベータ分布は美しい例。
→ 解析的(数学的)に解ける。
実践的なモデル・事後分布はもっと複雑。
→ コンピュータに頼って数値計算: MCMC
e.g., 半径1の円の面積
面積4の正方形に400個の一様乱数を打ち込んだら318個乗った:
$4 \times \frac {318} {400} = 3.18$
数学を知っていれば $\pi r ^ 2 \approx 3.14$
e.g., 確率密度分布に従って変数Xを集める(棄却サンプリング)。
でも、ハズレの値もけっこう引いてしまう。
(N次元球の体積 / N次元の立方体) はゼロに近づいていく。
パラメータが増えると計算量(≈乱数の無駄撃ち)が急増。
密度の高い「当たり」付近を効率よく探索したい。
「当たり」は「当たり」の近くにありがちだろう。
→ マルコフ連鎖が使えそう
尤度が高い方にただ向かうだけでなく、結構うろつく。
通ったパラメータ値を集めるといい感じの分布が得られる。
全体にばら撒く棄却サンプリングよりも効率よく集められる。
が、パラメータ1つの1次元ではご利益はわかりにくい。
パラメータが複数ある場合は?
パラメータが複数の場合「ほかを固定してひとつ更新」を繰り返す。
e.g., 二次元正規分布。(-2, 2) からスタート。
ここから、実行するにあたっての注意点を見ていく。
乱数や初期値によって偶々、じゃないことを確認したい。
e.g., chains = 3, iter = 600
。ほぼ同じところをうろうろ:
収束(convergence)の判定については後ほど。
定常分布の山に到達してからが本番。
e.g., iter = 600, warmup = 200
で灰色の部分を捨てる:
どれくらい長く捨てるべきかは場合による。
直前の値と似すぎていたら独立サンプルとして扱えないので。
e.g., thin = 5
で5回に1回だけサンプルする:
間引かなくても大丈夫な場合も、間引いても解決しない場合もある。
Warning: The largest R-hat is ***, indicating chains have not mixed.
Warning: Bulk Effective Samples Size (ESS) is too low, indicating posterior means and medians may be unreliable.
Warning: Tail Effective Samples Size (ESS) is too low, indicating posterior variances and tail quantiles may be unreliable.
Running the chains for more iterations may help. See
http://mc-stan.org/misc/warnings.html
採択率を高め、早く収束するように改良されてきている。
大部分はRで説明し、部分的にPythonでの練習を挟みます。
聞きながら手元でtokiomarine2021-stan.ipynbを実行してもいいです。
# install.packages("rstan")
library(rstan)
rstan_options(auto_write = TRUE)
# データ準備
mydata
# Stan言語で書いたモデルをコンパイル
model = rstan::stan_model(file = "model.stan")
# MCMCサンプリング
fit = rstan::sampling(model, data = mydata)
# 結果を眺める
print(fit)
rstan::stan_trace(fit)
rstan::stan_hist(fit)
rstan::stan_ac(fit)
表が出る確率 $p=0.7$ のイカサマコインをN回投げたデータを作る。
この $p$ をStanで推定してみよう。
true_p = 0.7
N = 40L
data = list(N = N, x = rbinom(N, 1, true_p))
print(data)
$N
[1] 40
$x
[1] 0 0 1 0 1 1 0 1 1 0 1 0 0 1 1 0 0 1 1 1 0 1 0 0 1 1 1 0 1 0 0 0 1 1 1 0 1 1 0 1
Rならlist型、Pythonならdict型にまとめてStanに渡す。
文字列として保持するか、別ファイルに書いておく:
data {
int<lower=0> N;
int x[N];
}
parameters {
real<lower=0,upper=1> p;
}
model {
x ~ binomial(1, p);
}
data
, 推定する parameter
, 本体の model
.int
, 実数型 real
, それらの配列がある。lower
, 上限 upper
を設定できる。順番厳守。よく使うのは太字のやつ。
functions {...}
data {...}
transformed data {...}
parameters {...}
transformed parameters {...}
model {...}
generated quantities {...}
https://mc-stan.org/docs/reference-manual/overview-of-stans-program-blocks.html
予め実行速度の速い機械語に翻訳(コンパイル):
model = rstan::stan_model("binom.stan")
これに結構時間がかかるので、変更が無ければ再利用するため先ほど
rstan_options(auto_write = TRUE)
しておいた。
モデルとデータを使ってMCMCサンプリング:
fit = rstan::sampling(model, data = data)
いろいろオプションはあるけどとりあえずデフォルトで:
chains = 4
, iter = 2000
, warmup = floor(iter/2)
, thin = 1
, …
問題があったら実行終了時に警告してくれるのでちゃんと読む。
$\hat R$ もほぼ1で $N_\text{eff}$ も大きいのでよさそう。
念のため trace plot も確認しておこう。
print(fit)
Inference for Stan model: binom.
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
p 0.55 0.00 0.08 0.39 0.50 0.55 0.60 0.69 1651 1
lp__ -29.45 0.02 0.76 -31.61 -29.61 -29.16 -28.97 -28.92 1262 1
Samples were drawn using NUTS(diag_e) at Tue Jul 6 17:58:10 2021.
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).
乱数を使った計算なので(乱数シードを固定しない限り)毎回変わる。
どのchainも似た範囲を動いていて、しっかり毛虫っぽい:
rstan::stan_trace(fit)
2–3ステップくらいで自己相関がほぼ消えるので問題なし:
rstan::stan_ac(fit, pars = c("p"))
サンプルサイズNが小さいせいか裾野の広い推定結果。
真の$p$の値も含まれている:
rstan::stan_hist(fit, bins = 30)
次はもう少しだけ複雑な例を見てみよう。
Stan does not support NA
と怒られるので欠損値を取り除いておく:
List of 3
$ body_mass_g : int [1:342] 3750 3800 3250 3450 3650 3625 4675 3475 4250 3300 ...
$ flipper_length_mm: int [1:342] 181 186 195 193 190 181 195 193 190 186 ...
$ N : int 342
切片、傾き、ばらつきを推定する:
data {
int<lower=0> N;
vector<lower=0>[N] body_mass_g;
vector<lower=0>[N] flipper_length_mm;
}
parameters {
real intercept;
real slope;
real<lower=0> sigma;
}
model {
flipper_length_mm ~ normal(intercept + slope * body_mass_g, sigma);
}
予め実行速度の速い機械語に翻訳(コンパイル):
model = rstan::stan_model("penguins.stan")
モデルとデータを使ってMCMCサンプリング:
fit = rstan::sampling(model, data = data)
いろいろオプションはあるけどとりあえずデフォルトで:
chains = 4
, iter = 2000
, warmup = floor(iter/2)
, thin = 1
, …
問題があったら実行終了時に警告してくれるのでちゃんと読む。
$\hat R$ もほぼ1で $N_\text{eff}$ も大きいのでよさそう。
念のため trace plot も確認しておこう。
print(fit)
Inference for Stan model: penguins.
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
intercept 136.76 0.05 1.97 132.89 135.40 136.75 138.04 140.67 1506 1
slope 0.02 0.00 0.00 0.01 0.01 0.02 0.02 0.02 1526 1
sigma 6.94 0.01 0.27 6.41 6.76 6.94 7.13 7.47 1198 1
lp__ -830.83 0.04 1.24 -834.08 -831.39 -830.51 -829.93 -829.43 1120 1
Samples were drawn using NUTS(diag_e) at Tue Jul 6 17:58:14 2021.
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).
どのchainも似た範囲を動いていて、しっかり毛虫っぽい:
rstan::stan_trace(fit)
どれもまあまあすぐ消えるので問題なし:
rstan::stan_ac(fit, pars = c("intercept", "slope", "sigma"))
正規分布っぽいきれいな形:
rstan::stan_hist(fit, bins = 30)
これらの値を使って点推定・区間推定も可能。
無事に最尤推定と似たような線が引けた。
coef = rstan::get_posterior_mean(fit)[, "mean-all chains"]
p_penweight +
geom_abline(intercept = coef["intercept"], slope = coef["slope"], size = 1, color = "#3366ff")
library(rstanarm)
library(tidybayes)
fit = rstanarm::stan_glm(flipper_length_mm ~ body_mass_g, family = gaussian(), data = penguins)
pred = penguins %>% tidyr::drop_na() %>% tidybayes::add_fitted_draws(fit)
p_penweight +
ggdist::stat_lineribbon(aes(y = .value), data = pred, color = "#3366ff", size = 0.4) +
scale_fill_brewer(palette = "Greys")
GLMのような書き味で書ける。
fit = rstanarm::stan_glm(flipper_length_mm ~ body_mass_g + species, family = gaussian(), data = penguins)
pred = penguins %>% tidyr::drop_na() %>% tidybayes::add_fitted_draws(fit)
p_penweight + aes(color = species, group = species) +
ggdist::stat_lineribbon(aes(y = .value), data = pred, size = 0.4) +
scale_color_manual(values = penguins_colors) +
scale_fill_brewer(palette = "Greys")
植物100個体から8個ずつ種子を取って植えたら全体で半分ちょい発芽。
親1個体あたりの生存数はn=8の二項分布になるはずだけど、
極端な値(全部死亡、全部生存)が多かった。個体差?
事前分布のパラメータに、さらに事前分布を設定するので階層ベイズ
お絵描きモデルとStanモデルを見比べてみよう。
data {
int<lower=0> N;
int y[N];
}
parameters {
real a; // mean ability
vector[N] r; // individual difference
real<lower=0> s; // sd of r
}
model {
y ~ binomial(8, inv_logit(a + r));
a ~ normal(0, 10);
r ~ normal(0, s);
s ~ exponential(0.01);
}
inv_logit(a + r)
が p に相当。
10
とか 0.01
とか、エイヤっと決めてるやつが超パラメータ。
Inference for Stan model: glmm.
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
a 0.58 0.01 0.37 -0.15 0.32 0.58 0.83 1.32 642 1
r[1] 3.77 0.04 2.06 0.57 2.28 3.49 4.96 8.51 3036 1
r[2] 0.00 0.02 0.82 -1.56 -0.54 -0.03 0.54 1.65 2294 1
r[3] -1.09 0.02 0.85 -2.81 -1.64 -1.08 -0.50 0.50 2307 1
r[4] -4.62 0.04 1.97 -9.20 -5.65 -4.33 -3.19 -1.65 2330 1
r[5] 3.79 0.03 2.04 0.66 2.33 3.50 4.95 8.54 3802 1
r[6] -1.74 0.02 0.92 -3.71 -2.30 -1.71 -1.12 -0.05 2370 1
r[7] 3.80 0.03 2.09 0.65 2.28 3.52 5.01 8.59 3951 1
r[8] 1.61 0.02 1.17 -0.44 0.81 1.51 2.30 4.27 2662 1
r[9] 3.79 0.04 2.04 0.74 2.34 3.46 4.94 8.62 2784 1
r[10] -1.73 0.02 0.90 -3.57 -2.28 -1.72 -1.12 -0.07 2820 1
r[11] 1.58 0.02 1.14 -0.37 0.79 1.47 2.23 4.19 3166 1
r[12] -4.63 0.04 1.96 -9.20 -5.78 -4.37 -3.21 -1.59 2631 1
r[13] -1.73 0.02 0.92 -3.76 -2.31 -1.67 -1.12 -0.06 2287 1
r[14] -4.63 0.04 2.00 -9.48 -5.74 -4.33 -3.23 -1.59 2403 1
r[15] -4.62 0.04 1.98 -9.33 -5.69 -4.30 -3.21 -1.62 3037 1
r[16] -1.11 0.02 0.83 -2.87 -1.65 -1.07 -0.55 0.46 2323 1
r[17] 0.64 0.02 0.94 -1.09 0.01 0.61 1.21 2.60 2699 1
r[18] -2.64 0.02 1.14 -5.19 -3.29 -2.54 -1.86 -0.68 2666 1
r[19] 1.58 0.02 1.14 -0.39 0.78 1.47 2.28 4.08 3418 1
r[20] -4.56 0.04 1.87 -8.90 -5.61 -4.30 -3.20 -1.64 2715 1
r[21] -2.61 0.02 1.12 -5.18 -3.26 -2.51 -1.84 -0.70 2764 1
r[22] 0.63 0.02 0.94 -1.05 0.00 0.60 1.23 2.53 2767 1
r[23] -4.62 0.04 1.95 -9.14 -5.75 -4.34 -3.19 -1.66 3031 1
r[24] 3.83 0.04 2.06 0.64 2.32 3.56 5.04 8.58 3251 1
r[25] -1.75 0.02 0.92 -3.74 -2.31 -1.71 -1.12 -0.06 2157 1
r[26] 3.83 0.03 2.09 0.58 2.33 3.52 5.03 8.79 3723 1
r[27] 0.00 0.02 0.83 -1.56 -0.57 -0.03 0.53 1.67 2271 1
r[28] -2.62 0.02 1.13 -5.14 -3.30 -2.52 -1.85 -0.68 2707 1
r[29] 3.85 0.04 2.05 0.72 2.36 3.58 5.02 8.57 2945 1
r[30] 3.86 0.04 2.12 0.64 2.31 3.57 5.08 8.87 3007 1
r[31] 0.65 0.02 0.92 -1.05 0.00 0.61 1.24 2.56 2431 1
r[32] 1.58 0.02 1.16 -0.46 0.77 1.51 2.27 4.07 3351 1
r[33] 3.78 0.04 2.06 0.65 2.30 3.46 4.96 8.72 3404 1
r[34] 1.58 0.02 1.11 -0.34 0.80 1.48 2.25 4.04 2612 1
r[35] -4.62 0.04 1.97 -9.23 -5.73 -4.34 -3.23 -1.55 3063 1
r[36] -0.56 0.02 0.81 -2.14 -1.10 -0.56 -0.05 1.06 2100 1
r[37] -1.72 0.02 0.94 -3.68 -2.31 -1.68 -1.07 0.00 2740 1
r[38] 1.59 0.02 1.19 -0.44 0.79 1.48 2.28 4.22 3245 1
r[39] 1.60 0.02 1.19 -0.39 0.79 1.48 2.30 4.26 2393 1
r[40] 3.81 0.04 2.02 0.63 2.33 3.54 4.99 8.46 3188 1
r[41] -2.63 0.02 1.13 -5.20 -3.31 -2.52 -1.85 -0.69 2397 1
r[42] 3.87 0.04 2.12 0.63 2.36 3.57 5.12 8.78 3403 1
r[43] -0.01 0.02 0.82 -1.63 -0.54 -0.02 0.55 1.59 2244 1
r[44] 3.84 0.04 2.08 0.68 2.33 3.54 4.98 8.69 2920 1
r[45] 3.85 0.04 2.13 0.53 2.32 3.55 5.07 8.98 3391 1
r[46] 3.80 0.04 2.12 0.60 2.28 3.48 5.00 8.77 2880 1
r[47] -4.65 0.04 2.06 -9.51 -5.81 -4.33 -3.17 -1.61 2865 1
r[48] 0.63 0.02 0.93 -1.03 0.00 0.57 1.19 2.63 2526 1
r[49] 1.59 0.02 1.20 -0.49 0.78 1.48 2.29 4.25 3496 1
r[50] -2.62 0.02 1.15 -5.29 -3.29 -2.52 -1.84 -0.64 2749 1
r[51] -2.63 0.02 1.10 -5.10 -3.28 -2.53 -1.87 -0.77 2875 1
r[52] 3.85 0.03 2.12 0.50 2.31 3.60 5.12 8.79 3797 1
r[53] 3.76 0.04 2.05 0.64 2.32 3.46 4.89 8.56 2911 1
r[54] 1.57 0.02 1.16 -0.33 0.75 1.44 2.26 4.20 3088 1
r[55] -4.62 0.04 1.95 -9.18 -5.74 -4.36 -3.21 -1.61 3075 1
r[56] -4.62 0.04 1.95 -9.16 -5.73 -4.36 -3.20 -1.66 2247 1
r[57] 3.75 0.04 2.04 0.65 2.30 3.45 4.86 8.57 3404 1
r[58] -0.55 0.02 0.81 -2.15 -1.09 -0.55 -0.01 1.03 2614 1
r[59] 0.63 0.02 0.90 -1.00 0.02 0.58 1.22 2.56 2475 1
r[60] 0.63 0.02 0.96 -1.10 -0.03 0.57 1.25 2.68 2577 1
r[61] -4.60 0.03 1.92 -9.13 -5.69 -4.34 -3.23 -1.61 3126 1
r[62] 3.78 0.04 2.06 0.64 2.27 3.49 4.97 8.52 3245 1
r[63] -1.74 0.02 0.93 -3.69 -2.31 -1.72 -1.13 -0.01 2426 1
r[64] 1.58 0.02 1.16 -0.40 0.77 1.49 2.28 4.20 3601 1
r[65] 3.82 0.04 2.04 0.73 2.33 3.49 5.03 8.47 2853 1
r[66] 3.77 0.04 2.00 0.68 2.27 3.53 4.99 8.35 3006 1
r[67] 3.82 0.04 2.08 0.58 2.32 3.54 5.06 8.58 3101 1
r[68] -0.56 0.02 0.78 -2.14 -1.08 -0.54 -0.05 0.96 2038 1
r[69] 3.86 0.04 2.11 0.63 2.34 3.54 5.06 8.79 3173 1
r[70] 3.81 0.04 2.09 0.63 2.33 3.47 4.98 8.79 3132 1
r[71] -2.65 0.02 1.18 -5.18 -3.33 -2.55 -1.86 -0.59 2951 1
r[72] -1.11 0.02 0.85 -2.86 -1.64 -1.09 -0.52 0.47 2296 1
r[73] -4.62 0.04 1.95 -9.18 -5.71 -4.36 -3.22 -1.65 2643 1
r[74] -4.59 0.04 1.93 -9.14 -5.63 -4.32 -3.24 -1.62 2921 1
r[75] 1.56 0.02 1.13 -0.45 0.80 1.48 2.24 4.10 3230 1
r[76] 3.81 0.03 2.05 0.66 2.31 3.53 4.99 8.68 3758 1
r[77] 3.82 0.03 2.09 0.55 2.30 3.51 5.02 8.61 3834 1
r[78] 1.62 0.02 1.19 -0.44 0.81 1.52 2.36 4.22 3063 1
r[79] -4.57 0.03 1.89 -9.01 -5.66 -4.30 -3.23 -1.61 3237 1
r[80] 3.78 0.04 2.04 0.61 2.32 3.51 4.90 8.69 3316 1
r[81] -1.73 0.02 0.91 -3.67 -2.31 -1.69 -1.10 -0.09 2390 1
r[82] -0.01 0.02 0.81 -1.58 -0.58 -0.03 0.52 1.61 2257 1
r[83] -0.55 0.02 0.82 -2.17 -1.09 -0.55 -0.01 1.04 2282 1
r[84] 3.81 0.04 2.05 0.66 2.36 3.51 4.96 8.64 2613 1
r[85] 1.59 0.02 1.18 -0.38 0.77 1.46 2.28 4.25 2865 1
r[86] 0.65 0.02 0.91 -1.04 0.03 0.59 1.24 2.52 2543 1
r[87] -0.55 0.02 0.80 -2.10 -1.09 -0.56 -0.01 1.05 2109 1
r[88] 0.64 0.02 0.93 -1.08 0.00 0.58 1.24 2.57 2944 1
r[89] -1.74 0.02 0.91 -3.63 -2.30 -1.70 -1.11 -0.05 2721 1
r[90] -2.64 0.02 1.12 -5.16 -3.29 -2.52 -1.88 -0.72 3005 1
r[91] -4.63 0.04 1.99 -9.37 -5.66 -4.34 -3.24 -1.68 2237 1
r[92] -1.73 0.02 0.89 -3.62 -2.30 -1.69 -1.11 -0.11 2556 1
r[93] -1.71 0.02 0.90 -3.60 -2.27 -1.66 -1.09 -0.07 2328 1
r[94] 3.77 0.04 2.06 0.59 2.31 3.50 4.87 8.60 3412 1
r[95] -4.61 0.03 1.89 -9.01 -5.69 -4.34 -3.28 -1.69 3014 1
r[96] 0.64 0.02 0.98 -1.17 -0.03 0.60 1.23 2.78 3067 1
r[97] -4.61 0.04 1.89 -8.92 -5.77 -4.35 -3.21 -1.69 2705 1
r[98] -4.63 0.04 1.97 -9.34 -5.70 -4.31 -3.24 -1.57 2638 1
r[99] -1.11 0.02 0.86 -2.81 -1.67 -1.09 -0.52 0.52 2276 1
r[100] -4.61 0.04 1.89 -8.96 -5.67 -4.35 -3.26 -1.60 2757 1
s 3.46 0.01 0.44 2.71 3.15 3.43 3.74 4.45 945 1
lp__ -433.99 0.35 9.69 -454.15 -440.31 -433.69 -427.41 -416.15 783 1
Samples were drawn using NUTS(diag_e) at Tue Jul 6 17:58:26 2021.
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).
データ生成の真のパラメータ値は $a = 0.5,~s = 3.0$ だった。
とりあえず無情報事前分布 $[-\infty, \infty]$。Stanのデフォルト。
収束が悪かったら弱情報事前分布を試す。
事後分布を更新していったとき事前分布っぽさが残らないのが良い。
おすすめ: Student’s t分布、正規分布、指数分布など。
https://github.com/stan-dev/stan/wiki/Prior-Choice-Recommendations
Student’s $t(\nu=\nu_0, \mu = 0, \sigma = \sigma_0)$
正の値しか取らない場合は <lower=0>
として右半分だけ使うとか。
刺激強度xに対する応答強度yを20個体調査。
非対称なひと山。応答変数も説明変数も正の値。
data {
int<lower=1> N;
vector[N] x;
vector[N] y;
int id[N];
int<lower=1> Ninds;
}
parameters {
real a;
real d;
real<upper=a> c;
real<upper=d> b;
real shape;
vector[Ninds] intercept;
}
model {
vector[N] mu = a * exp(-b * x) - (a - c) * exp(-d * x) + intercept[id];
y ~ gamma(shape, shape ./ mu);
a ~ exponential(1);
b ~ exponential(1);
c ~ exponential(1);
d ~ exponential(1);
shape ~ exponential(0.001);
intercept ~ normal(0, 0.005);
}
🔰 penguins
データでStanを動かしてみよう。
より柔軟にモデルを記述できるようになった。計算方法も変化。