階層ベイズモデル(HBM)って何?
階層ベイズモデル(HBM)って何?
はじめに
階層ベイズモデルという言葉を聞いたことがありますか?
AIの記事を読んでいると、ときどき出現するのですが今まで無視していたので調べてみました。
📘 用語一覧
用語 | 説明 |
---|---|
観測データ(y) | 実際に得られたデータ。ここでは生徒のテストの点数 |
実力(θ) | 各生徒が本来持っている能力。直接は見えない隠れた変数 |
全体平均(μ) | 学校全体としての平均的な実力 |
ばらつき(τ) | 各生徒の実力がどのくらい多様か(標準偏差) |
誤差(σ) | テスト結果に含まれる偶然のゆらぎやノイズ |
事前分布 | モデル内の未知の値について、データを見る前にどのくらいの値をとると考えるか |
🎓 ストーリーで学ぶ:階層ベイズモデル(Hierarchical Bayesian Model, HBM)
登場人物
- 先生:ある学校で数学を教えている。
- 10人の生徒:数学のテストを受けた。
🎬 ストーリーの始まり
ある日、先生は10人の生徒に数学のテストを受けさせました。
テストの結果を見て、先生は思いました:
「テストの点数だけで、本当の実力を測るのは難しいな。もっと賢いやり方がないかな?」
🧩 Step 1:観測データ(テスト点数)
まず先生が持っているのは、生徒のテストの点数だけです。
でも、点数というのは「実力そのもの」ではありません。
点数 = 実力(θ) + ちょっとしたブレ(σ)
体調や運も影響するので、1回のテストで全てを判断するのは難しいのです。
🧩 Step 2:実力の仮定(θ)
先生はこう考えます:
「それぞれの生徒には“本当の実力(θ)”があるはず。でも、それは見えない。だから、点数から推定しよう。」
でもここでさらに思い付きます:
「この学校の生徒たちは、だいたい似たレベルなんだから、
みんなの実力は、ある平均からバラついたものと考えよう。」
つまり、生徒の実力(θ)は次のような分布から来ているとします:
θ ~ N(μ, τ)
- μ:学校全体の平均的な実力
- τ:実力のばらつき(多様性)
🧩 Step 3:もっと上の階層(μ と τ)
最後に、先生はこう考えます:
「μ や τ も、最初から決めてしまうのではなく、データから学ばせたい。」
そこで μ や τ にも分布を持たせます。
- μ ~ N(0, 10):全体平均の事前分布
- τ ~ HalfCauchy(5):ばらつきの事前分布
これにより、推定がより柔軟で現実的になります。
🧠 3層構造のまとめ
先生の推論モデルは次の3層になりました:
- 観測層:生徒の点数(y)← 実力(θ)+誤差(σ)
- 個人層:各生徒の実力(θ)← 全体平均(μ)+ばらつき(τ)
- 全体層:μ, τ にも事前分布を設定
これが、階層ベイズモデル(HBM) です。
✅ どうして良いのか?
- データが少なくても安定する:1人の点数しかなくても、全体の情報から実力を推定できる。
- 個別性と全体傾向の両立:それぞれの違いを尊重しつつ、全体から学ぶ。
💬 ストーリーのおわりに
こうして先生は、1回のテスト結果から、より正確に生徒たちの実力を知ることができるようになりました。
それを可能にしたのが、階層ベイズモデルだったのです。
💻 Pythonでのサンプルコード
以下は、このストーリーをPythonで実際にモデリングする例です(PyMC使用):
import numpy as np
import pymc as pm
import arviz as az
# データの作成
np.random.seed(42) # 再現性のための乱数シード
n_students = 10 # 生徒数
mu_real = 70 # 全体平均
tau_real = 8 # 実力のばらつき
sigma_real = 5 # 観測ノイズ
true_ability = np.random.normal(mu_real, tau_real, size=n_students) # 各生徒の実力
test_scores = np.random.normal(true_ability, sigma_real) # テスト点数
# モデル定義
with pm.Model() as model:
mu = pm.Normal("mu", mu=50, sigma=20)
tau = pm.HalfNormal("tau", sigma=10)
theta = pm.Normal("theta", mu=mu, sigma=tau, shape=n_students)
sigma = pm.HalfNormal("sigma", sigma=10)
y_obs = pm.Normal("y_obs", mu=theta, sigma=sigma, observed=test_scores)
trace = pm.sample(1000, tune=500, chains=1, cores=1, return_inferencedata=True, target_accept=0.9)
# 結果の可視化
az.plot_trace(trace, var_names=["mu", "tau", "sigma"])
az.summary(trace, var_names=["mu", "tau", "sigma", "theta"])
このコードは、ストーリーに出てくる「実力」「テスト点数」「ばらつき」をモデル化し、PyMC[1]で階層ベイズ推論を行います。
📊 出力結果
mean | sd | hdi_3% | hdi_97% | mcse_mean | mcse_sd | ess_bulk | ess_tail | r_hat | |
---|---|---|---|---|---|---|---|---|---|
mu | 69.214 | 2.506 | 64.798 | 73.689 | 0.131 | 0.166 | 409.0 | 329.0 | NaN |
tau | 5.117 | 2.639 | 0.914 | 9.499 | 0.374 | 0.075 | 46.0 | 145.0 | NaN |
sigma | 5.220 | 2.517 | 0.735 | 9.423 | 0.698 | 0.099 | 13.0 | 81.0 | NaN |
theta[0] | 70.448 | 3.355 | 64.375 | 76.863 | 0.181 | 0.150 | 344.0 | 517.0 | NaN |
theta[1] | 67.951 | 3.612 | 61.639 | 75.354 | 0.187 | 0.174 | 371.0 | 546.0 | NaN |
theta[2] | 72.703 | 4.084 | 65.241 | 79.520 | 0.542 | 0.189 | 59.0 | 467.0 | NaN |
theta[3] | 70.911 | 3.505 | 64.115 | 77.240 | 0.249 | 0.191 | 186.0 | 329.0 | NaN |
theta[4] | 64.417 | 4.701 | 56.624 | 72.979 | 0.641 | 0.140 | 54.0 | 404.0 | NaN |
theta[5] | 67.312 | 3.884 | 59.632 | 74.373 | 0.236 | 0.181 | 260.0 | 416.0 | NaN |
theta[6] | 73.324 | 4.414 | 65.041 | 80.706 | 0.902 | 0.198 | 24.0 | 387.0 | NaN |
theta[7] | 73.335 | 4.347 | 65.486 | 80.378 | 0.777 | 0.198 | 31.0 | 201.0 | NaN |
theta[8] | 65.554 | 4.096 | 58.308 | 73.184 | 0.419 | 0.103 | 93.0 | 728.0 | NaN |
theta[9] | 68.433 | 3.652 | 62.205 | 75.429 | 0.156 | 0.242 | 478.0 | 454.0 | NaN |
※ mu
は全体の平均、tau
は実力のばらつき、sigma
は観測ノイズを示しています。
※ theta[x]
は生徒の実力を示しています。
📊 各列の意味
列名 | 意味 |
---|---|
mean |
推定されたパラメーターの平均(ベイズ的な最良推定値) |
sd |
標準偏差。推定値の不確かさ(ばらつき) |
hdi_3% , hdi_97%
|
94%の信頼区間(High Density Interval)で、この範囲に真の値がある可能性が高い |
mcse_mean |
推定平均のモンテカルロ誤差[2](小さいほど信頼性が高い) |
mcse_sd |
標準偏差のモンテカルロ誤差 |
ess_bulk |
有効サンプルサイズ(推定の信頼性指標、200以上が理想) |
ess_tail |
尾部(極端な値)の有効サンプルサイズ |
r_hat |
収束診断指標(複数チェーンの一致度)。通常は1.0に近ければOK。ここで NaN はチェーン数1のため出力されないだけで問題ありません。 |
🧠 各パラメーターの読み解き方
-
mu
(全体の平均能力):69.2点くらいで、±2.5点の不確かさがあります。信頼区間は約65〜74点。 -
tau
(能力のばらつき):5.1点で、ばらつきの程度もやや不確実(SD 2.6)ですが有効です。 -
sigma
(観測ノイズ):5.2点。これはテストのブレ(運やミスなど)を意味します。
🎯 θ(各生徒の実力)について
たとえば:
-
theta[0]
の推定値は 70.4点 ±3.4点。
信頼区間は 64〜77点。これは「この生徒の本当の実力はこの範囲にある」と判断できます。 -
theta[4]
は 64.4点 ±4.7点 と推定されており、他の生徒より不確かさが少し大きい(=観測が弱い、または平均から離れている)。
このように、全体平均μと個々の観測データをうまく統合することで、「部分プーリング[3]」による安定した推定ができているのがわかります。
結びに
階層ベイズモデルは、データが少ない場合でも全体の傾向を活かして個別の情報を補強する強力な手法のようです。
これで、少し賢くなりました。
🌍 階層ベイズモデルの応用例と実用シーン
階層ベイズモデルは教育データに限らず、以下のような多様な分野で活用されています:
- 医療:病院ごとの治療効果のばらつきや、個々の患者の応答性をモデル化
- マーケティング:地域や店舗ごとの売上予測や、顧客ごとの購買傾向の推定
- 心理学・行動科学:被験者ごとの反応や意思決定パターンの個人差を考慮した分析
- スポーツ分析:選手ごとのパフォーマンス傾向を全体のチームやリーグ傾向に統合
- 自然言語処理:文書分類などで、トピックごと・著者ごとの傾向を学習
このように、HBMは「個別データが少ないが、全体の傾向を活かして補強したい」ときに非常に力を発揮します。
-
PyMC:Pythonのベイズモデリングライブラリ。階層ベイズモデルを簡単に実装できる。URL: https://www.pymc.io/welcome.html ↩︎
-
モンテカルロ誤差:サンプリングによる推定の不確かさ。小さいほど良い。 ↩︎
-
部分プーリング:個別のデータを全体の情報で補強すること。HBMの特徴。 ↩︎
Discussion