Uncategorized

因果推論学習:Phase2






Phase 2: ベイズ統計の基礎固め - 詳細カリキュラム


Phase 2: ベイズ統計の基礎固め
期間: 4週間 | 目標: PyMCでベイズモデリングを実装できるようになる

Phase 2で達成すること

  • ベイズ統計の基本概念(事前分布、事後分布、ベイズ更新)を理解する
  • PyMC最新版で基本的な統計モデルを構築できる
  • MCMC収束診断ができる
  • 階層ベイズモデルを不動産データに適用できる
  • Bayesian A/Bテストを設計・実装できる

使用教材

主教材

  • 導入書: 「史上最強図解 これならわかる!ベイズ統計学」(図書館)
    • 数式を最小限に、直感的にベイズを理解
    • Week 1で集中的に読破(1週間で完読可能)
  • 実装教材: Udemy「PyMCで学ぶ実践ベイズ統計モデリング」(購入済み)
    • PyMC最新版対応(2025年6月更新)
    • 動画で手を動かしながら学習
    • Week 1から並行して視聴開始
  • 補助教材: PyMC公式ドキュメント(無料)
    • https://www.pymc.io/
    • 最新機能の確認、トラブルシューティング用
Phase 2開始前の確認事項

  • Phase 1で因果推論の基礎を習得済みであること
  • Python環境(Google Colab or ローカル)が動作すること
  • Pandas/NumPyの基本操作ができること
  • Udemy講座を購入済みであること
  • 図書館で「史上最強図解 ベイズ統計学」を借用済み、または借用予約済み

Week 1: ベイズ統計の直感的理解

Week 1 の学習目標
  • ベイズの定理を直感的に理解し、自分の言葉で説明できる
  • 事前分布、事後分布、尤度の関係を図解できる
  • PyMC環境を構築し、最初のベイズモデルを動かす
  • 頻度論とベイズ統計の違いを理解する
Day 1-2: ベイズの定理の直感的理解

月曜日(3時間)

  • 午前(1.5時間): 史上最強図解 第1章「ベイズ統計とは」
    • 頻度論 vs ベイズ統計の違い
    • 確率を「信念の度合い」として捉える
    • 具体例: 病気診断での応用
  • 午後(1.5時間): 第2章「ベイズの定理」
    • 条件付き確率の復習
    • ベイズの定理の導出
    • 数値例で計算練習
理解を深めるコツ

ベイズの定理は「事前の信念 + 新しいデータ = 更新された信念」という構造。不動産の例で考えると:

  • 事前: 「駅近物件は人気だろう」(経験則)
  • データ: 実際の問い合わせデータ
  • 事後: 「やはり駅近は問い合わせが1.5倍多い」(データで確信度UP)

火曜日(3時間)

  • 午前(1.5時間): 史上最強図解 第3章「事前分布と事後分布」
    • 事前分布の選び方
    • 共役事前分布とは
    • 無情報事前分布 vs 情報事前分布
  • 午後(1.5時間): Udemy講座 Section 1「ベイズ統計の基礎」
    • 動画で理論を復習
    • 具体例で理解を深める
    • ノートにまとめ直す

Day 3-4: PyMC環境構築と初めてのベイズモデル

水曜日(3時間)

  • 午前(1.5時間): 史上最強図解 第4-5章
    • ベイズ更新の仕組み
    • 逐次学習の概念
  • 午後(1.5時間): PyMC環境構築
    • PyMCインストール
    • ArviZインストール(可視化用)
    • 動作確認

PyMC環境構築コード

# Google Colabの場合
!pip install pymc arviz

# ローカル環境の場合(conda推奨)
# conda install -c conda-forge pymc arviz

# 動作確認
import pymc as pm
import arviz as az
import numpy as np
import matplotlib.pyplot as plt

print(f"PyMC version: {pm.__version__}")
print(f"ArviZ version: {az.__version__}")

# 簡単なモデルで動作確認
with pm.Model() as test_model:
mu = pm.Normal('mu', mu=0, sigma=1)
trace = pm.sample(1000, return_inferencedata=True)

az.plot_trace(trace)
plt.tight_layout()
plt.show()

print("✅ PyMC環境構築完了!")

木曜日(3時間)

  • 全日(3時間): Udemy講座 Section 2「PyMCの基礎」
    • PyMCの基本文法
    • 確率分布の指定方法
    • 最初のベイズモデル実装

初めてのベイズ推定: コイントスの例

import pymc as pm
import arviz as az
import numpy as np

# データ: 10回投げて7回表
n_trials = 10
n_heads = 7

with pm.Model() as coin_model:
# 事前分布: 表が出る確率(0から1の一様分布)
p = pm.Uniform('p', lower=0, upper=1)

# 尤度: 二項分布
obs = pm.Binomial('obs', n=n_trials, p=p, observed=n_heads)

# サンプリング
trace = pm.sample(2000, return_inferencedata=True,
random_seed=42)

# 結果の確認
az.summary(trace, var_names=['p'])

# 可視化
az.plot_posterior(trace, var_names=['p'])
plt.title('表が出る確率の事後分布')
plt.show()

print(f"推定された確率: {trace.posterior['p'].mean():.3f}")
print(f"95%信用区間: {az.hdi(trace, var_names=['p'])}")

理解のポイント

  • 事前分布(Uniform): 何も知らない状態では、どの確率も等しくありうる
  • 尤度(Binomial): 実際に観測されたデータ(7/10)
  • 事後分布: 事前 × 尤度 ∝ 事後(ベイズの定理)
  • 結果: 95%信用区間は約[0.40, 0.93]。0.5(公正なコイン)も含まれるので、まだ断定できない

Day 5-7: ベイズ線形回帰と復習

金曜日(3時間)

  • 全日(3時間): Udemy講座 Section 3「ベイズ線形回帰」
    • 通常の線形回帰との違い
    • パラメータの不確実性を考慮
    • PyMCでの実装

不動産データでのベイズ線形回帰

import pymc as pm
import arviz as az
import pandas as pd
import numpy as np

# シミュレーションデータ(不動産価格予測)
np.random.seed(42)
n = 100
area = np.random.uniform(30, 100, n) # 面積(㎡)
true_price = 50 + 2 * area + np.random.normal(0, 10, n) # 真の関係

data = pd.DataFrame({
'area': area,
'price': true_price
})

# ベイズ線形回帰
with pm.Model() as bayesian_regression:
# 事前分布
alpha = pm.Normal('alpha', mu=0, sigma=50) # 切片
beta = pm.Normal('beta', mu=0, sigma=10) # 傾き
sigma = pm.HalfNormal('sigma', sigma=20) # 誤差の標準偏差

# 線形予測子
mu = alpha + beta * data['area']

# 尤度
price_obs = pm.Normal('price_obs', mu=mu, sigma=sigma,
observed=data['price'])

# サンプリング
trace = pm.sample(2000, return_inferencedata=True,
target_accept=0.95, random_seed=42)

# 結果サマリー
print(az.summary(trace, var_names=['alpha', 'beta', 'sigma']))

# 可視化
az.plot_trace(trace, var_names=['alpha', 'beta', 'sigma'])
plt.tight_layout()
plt.show()

# 事後予測分布
with bayesian_regression:
ppc = pm.sample_posterior_predictive(trace, random_seed=42)

# 予測の可視化
plt.figure(figsize=(10, 6))
plt.scatter(data['area'], data['price'], alpha=0.5, label='観測値')

# 事後平均での予測線
area_range = np.linspace(30, 100, 100)
alpha_mean = trace.posterior['alpha'].mean()
beta_mean = trace.posterior['beta'].mean()
plt.plot(area_range, alpha_mean + beta_mean * area_range,
'r-', linewidth=2, label='予測(事後平均)')

# 95%予測区間
pred_samples = ppc.posterior_predictive['price_obs'].values.reshape(-1, n)
pred_lower = np.percentile(pred_samples, 2.5, axis=0)
pred_upper = np.percentile(pred_samples, 97.5, axis=0)
plt.fill_between(data['area'], pred_lower, pred_upper,
alpha=0.2, color='red', label='95%予測区間')

plt.xlabel('面積(㎡)')
plt.ylabel('価格(万円)')
plt.legend()
plt.title('ベイズ線形回帰による不動産価格予測')
plt.show()

頻度論の回帰 vs ベイズ回帰

項目 頻度論 ベイズ
パラメータ 固定値(点推定) 確率分布
不確実性 信頼区間(解釈が難しい) 信用区間(直感的)
事前知識 使えない 事前分布で組み込める
予測 点予測のみ 予測分布(幅を持つ)

土日(各2-3時間)

  • 土曜: Week 1の総復習
    • ベイズの定理を自分の言葉でまとめる
    • 実装したコードを読み直し
    • つまずいたポイントの再確認
  • 日曜: 実践演習
    • 自分で簡単なデータを作成
    • ベイズ回帰モデルを一から実装
    • 結果の解釈レポート作成

Week 1 完了チェックリスト

☐ ベイズの定理を自分の言葉で説明できる
☐ 事前分布、尤度、事後分布の関係を図解できる
☐ PyMC環境が正常に動作する
☐ 簡単なベイズモデル(コイントス)を実装できた
☐ ベイズ線形回帰を実装し、結果を解釈できた
☐ 頻度論とベイズの違いを理解している

Week 2: MCMCサンプリングと収束診断

Week 2 の学習目標
  • MCMCサンプリングの仕組みを理解する
  • 収束診断(Rhat, ESS)ができる
  • 事後分布の可視化と解釈ができる
  • 複数のモデルを比較できる
Day 1-2: MCMCの基礎理解

月曜日(3時間)

  • 午前(1.5時間): 史上最強図解 第6章「MCMC入門」
    • なぜMCMCが必要か
    • マルコフ連鎖の基礎
    • メトロポリス・ヘイスティングス法
  • 午後(1.5時間): Udemy講座 Section 4「MCMC サンプリング」
    • NUTSサンプラーとは
    • ウォームアップ(tune)の役割
    • チェーン数の設定
MCMCが必要な理由

ベイズ統計では事後分布を求めたいが、多くの場合、解析的に計算できない。そこで、事後分布から「サンプリング」することで近似的に分布を得る。これがMCMCの役割。

例: 不動産価格モデルで、切片、傾き、誤差の3つのパラメータの同時分布を求める場合、解析解はないが、MCMCで2000サンプル取得すれば、事後分布を近似できる。

火曜日(3時間)

  • 全日(3時間): 収束診断の実践
    • Rhat(R-hat)統計量の理解
    • Effective Sample Size (ESS)
    • トレースプロットの見方

収束診断のコード例

import pymc as pm
import arviz as az
import numpy as np

# わざと収束しにくいモデルを作る(学習用)
np.random.seed(42)
y = np.random.normal(100, 15, 50)

with pm.Model() as convergence_test:
# 事前分布を極端に設定(収束の問題を確認)
mu = pm.Normal('mu', mu=0, sigma=1000) # 広すぎる事前分布
sigma = pm.HalfNormal('sigma', sigma=1000)

obs = pm.Normal('obs', mu=mu, sigma=sigma, observed=y)

# サンプリング(意図的に少なめ)
trace_bad = pm.sample(500, tune=500, chains=2,
return_inferencedata=True)

# 収束診断
print("=== 収束診断結果 ===")
summary = az.summary(trace_bad, var_names=['mu', 'sigma'])
print(summary)

# トレースプロット
az.plot_trace(trace_bad, var_names=['mu', 'sigma'])
plt.suptitle('収束が不十分な例', fontsize=16)
plt.tight_layout()
plt.show()

# より良い設定で再サンプリング
with convergence_test:
trace_good = pm.sample(2000, tune=1000, chains=4,
target_accept=0.95,
return_inferencedata=True)

print("\n=== 改善後の収束診断 ===")
summary_good = az.summary(trace_good, var_names=['mu', 'sigma'])
print(summary_good)

az.plot_trace(trace_good, var_names=['mu', 'sigma'])
plt.suptitle('収束が良好な例', fontsize=16)
plt.tight_layout()
plt.show()

収束診断の判定基準

指標 良好な値 問題あり 対処法
Rhat (R̂) < 1.01 > 1.01 サンプル数増、チェーン数増、事前分布見直し
ESS (bulk) > 400 < 400 サンプル数増、target_accept調整
ESS (tail) > 400 < 400 同上
Divergences 0 > 0 target_accept=0.99、パラメータ変換

Day 3-4: 事後分布の可視化と解釈

水曜日(3時間)

  • 全日(3時間): Udemy講座 Section 5「事後分布の可視化」
    • ArviZの各種プロット機能
    • HDI(Highest Density Interval)の理解
    • 事後予測チェック(PPC)

ArviZによる可視化の完全ガイド

import pymc as pm
import arviz as az
import numpy as np
import matplotlib.pyplot as plt

# サンプルデータ
np.random.seed(42)
treatment = np.random.normal(105, 15, 100)
control = np.random.normal(100, 15, 100)
data = np.concatenate([treatment, control])
group = np.array([1]*100 + [0]*100)

# ベイズt検定モデル
with pm.Model() as bayesian_ttest:
# グループ別の平均
mu_control = pm.Normal('mu_control', mu=100, sigma=20)
mu_treatment = pm.Normal('mu_treatment', mu=100, sigma=20)

# 共通の標準偏差
sigma = pm.HalfNormal('sigma', sigma=20)

# 効果量(Cohen's d)
effect_size = pm.Deterministic('effect_size',
(mu_treatment - mu_control) / sigma)

# 尤度
mu = pm.math.switch(group == 1, mu_treatment, mu_control)
obs = pm.Normal('obs', mu=mu, sigma=sigma, observed=data)

# サンプリング
trace = pm.sample(2000, return_inferencedata=True,
random_seed=42)

# 1. 事後分布のプロット
az.plot_posterior(trace, var_names=['mu_control', 'mu_treatment',
'effect_size'],
hdi_prob=0.95)
plt.tight_layout()
plt.show()

# 2. トレースプロット
az.plot_trace(trace, var_names=['mu_control', 'mu_treatment'])
plt.tight_layout()
plt.show()

# 3. ペアプロット(相関確認)
az.plot_pair(trace, var_names=['mu_control', 'mu_treatment', 'sigma'],
kind='kde')
plt.tight_layout()
plt.show()

# 4. 森プロット(複数パラメータ比較)
az.plot_forest(trace, var_names=['mu_control', 'mu_treatment'])
plt.tight_layout()
plt.show()

# 5. 事後予測チェック
with bayesian_ttest:
ppc = pm.sample_posterior_predictive(trace, random_seed=42)

az.plot_ppc(ppc, data_pairs={"obs": "obs"})
plt.title('事後予測チェック')
plt.show()

# 6. エネルギープロット(収束診断の高度版)
az.plot_energy(trace)
plt.show()

# 7. 自己相関プロット
az.plot_autocorr(trace, var_names=['mu_control', 'mu_treatment'])
plt.tight_layout()
plt.show()

木曜日(3時間)

  • 午前(1.5時間): HDIと信用区間の理解
  • 午後(1.5時間): 実践演習
    • 不動産データで複数モデルの比較
    • 結果の解釈レポート作成
HDI(Highest Density Interval)とは

事後分布の中で、最も確率密度が高い領域を示す区間。95% HDIは「真の値が95%の確率でこの範囲にある」と直感的に解釈できる(頻度論の信頼区間とは異なる)。

  • 例: 駅距離の効果の95% HDIが[5, 15]万円なら、「駅から1分遠くなると、価格が5〜15万円下がる確率が95%」
  • 意思決定: HDIが0を含まない場合、効果があると判断できる

Day 5-7: モデル比較と選択

金曜日(3時間)

  • 全日(3時間): Udemy講座 Section 6「モデル選択」
    • WAIC(広く適用可能な情報量基準)
    • LOO(Leave-One-Out交差検証)
    • モデル比較の実践

モデル比較の実装例

import pymc as pm
import arviz as az
import numpy as np

# データ
np.random.seed(42)
x = np.linspace(0, 10, 100)
y = 2 + 3*x + 0.5*x**2 + np.random.normal(0, 2, 100)

# モデル1: 線形モデル
with pm.Model() as model1:
alpha = pm.Normal('alpha', 0, 10)
beta1 = pm.Normal('beta1', 0, 10)
sigma = pm.HalfNormal('sigma', 5)

mu = alpha + beta1 * x
obs = pm.Normal('obs', mu=mu, sigma=sigma, observed=y)

trace1 = pm.sample(2000, return_inferencedata=True)

# モデル2: 2次モデル
with pm.Model() as model2:
alpha = pm.Normal('alpha', 0, 10)
beta1 = pm.Normal('beta1', 0, 10)
beta2 = pm.Normal('beta2', 0, 10)
sigma = pm.HalfNormal('sigma', 5)

mu = alpha + beta1 * x + beta2 * x**2
obs = pm.Normal('obs', mu=mu, sigma=sigma, observed=y)

trace2 = pm.sample(2000, return_inferencedata=True)

# モデル3: 3次モデル(過剰適合の例)
with pm.Model() as model3:
alpha = pm.Normal('alpha', 0, 10)
beta1 = pm.Normal('beta1', 0, 10)
beta2 = pm.Normal('beta2', 0, 10)
beta3 = pm.Normal('beta3', 0, 10)
sigma = pm.HalfNormal('sigma', 5)

mu = alpha + beta1 * x + beta2 * x**2 + beta3 * x**3
obs = pm.Normal('obs', mu=mu, sigma=sigma, observed=y)

trace3 = pm.sample(2000, return_inferencedata=True)

# モデル比較
comparison = az.compare({'Linear': trace1,
'Quadratic': trace2,
'Cubic': trace3})
print(comparison)

# 可視化
az.plot_compare(comparison)
plt.tight_layout()
plt.show()

モデル選択の指針

  • WAIC/LOO値: 小さいほど良いモデル
  • dWAIC/dLOO: 最良モデルとの差。0なら最良
  • weight: モデルの重み。高いほど推奨
  • SE: 標準誤差。dがSEの2倍以上なら、有意に異なる

例: 上記の例では、Quadratic(2次)モデルが最良。Linearは単純すぎ、Cubicは過剰適合の可能性。

土日(各3時間)

  • 土曜: 総合演習
    • 不動産データで3つのモデルを構築
    • 収束診断、可視化、モデル比較を実施
    • 最良モデルを選択し、理由を説明
  • 日曜: Week 2振り返り
    • MCMC、収束診断の復習
    • つまずいたポイントの整理
    • Week 3の予習(階層ベイズ)

Week 2 完了チェックリスト

☐ MCMCサンプリングの仕組みを説明できる
☐ Rhat、ESSで収束診断ができる
☐ トレースプロットから収束の良し悪しを判断できる
☐ ArviZで事後分布を可視化できる
☐ HDIを計算し、解釈できる
☐ WAIC/LOOでモデル比較ができる

Week 3: 階層ベイズモデル

Week 3 の学習目標
  • 階層構造の概念を理解する
  • 部分プーリングの効果を体感する
  • 不動産データでエリア別・物件タイプ別の階層モデルを構築する
  • 固定効果 vs ランダム効果を使い分けられる
Day 1-2: 階層ベイズの理論

月曜日(3時間)

  • 全日(3時間): Udemy講座 Section 7「階層ベイズモデル」
    • 階層構造とは
    • 完全プーリング vs 部分プーリング vs プーリングなし
    • 収縮(shrinkage)効果
階層ベイズが威力を発揮する場面

不動産マーケティングでの具体例:

  • エリア別の効果推定: 23区すべてのエリアで広告効果を知りたいが、サンプル数がエリアごとに異なる
  • 問題: サンプルの少ないエリアでは推定が不安定
  • 解決: 階層ベイズで「全体の傾向」から情報を借りることで、少ないサンプルでも安定した推定が可能

火曜日(3時間)

  • 全日(3時間): 完全プーリング vs 部分プーリングの比較実装

3つのアプローチの比較

import pymc as pm
import arviz as az
import pandas as pd
import numpy as np

# シミュレーションデータ: 5つのエリアでの問い合わせ数
np.random.seed(42)
areas = ['渋谷区', '新宿区', '港区', '世田谷区', '目黒区']
n_samples = [50, 30, 80, 20, 40] # エリアごとにサンプル数が異なる

data = []
true_means = [100, 95, 110, 90, 105] # 真の平均

for area, n, true_mean in zip(areas, n_samples, true_means):
inquiries = np.random.poisson(true_mean, n)
data.extend([{'area': area, 'inquiries': inq} for inq in inquiries])

df = pd.DataFrame(data)

# カテゴリ変数を数値に変換
area_idx, area_names = pd.factorize(df['area'])
n_areas = len(area_names)

# アプローチ1: プーリングなし(エリアごとに独立推定)
with pm.Model() as no_pooling:
mu = pm.Normal('mu', mu=100, sigma=20, shape=n_areas)
obs = pm.Poisson('obs', mu=mu[area_idx], observed=df['inquiries'])

trace_no_pool = pm.sample(2000, return_inferencedata=True)

# アプローチ2: 完全プーリング(全エリア同じと仮定)
with pm.Model() as complete_pooling:
mu_global = pm.Normal('mu_global', mu=100, sigma=20)
obs = pm.Poisson('obs', mu=mu_global, observed=df['inquiries'])

trace_complete = pm.sample(2000, return_inferencedata=True)

# アプローチ3: 部分プーリング(階層ベイズ)
with pm.Model() as partial_pooling:
# 超パラメータ(全体の傾向)
mu_global = pm.Normal('mu_global', mu=100, sigma=20)
sigma_areas = pm.HalfNormal('sigma_areas', sigma=20)

# エリア別パラメータ(部分プーリング)
mu = pm.Normal('mu', mu=mu_global, sigma=sigma_areas, shape=n_areas)

obs = pm.Poisson('obs', mu=mu[area_idx], observed=df['inquiries'])

trace_partial = pm.sample(2000, return_inferencedata=True)

# 結果の比較
fig, axes = plt.subplots(1, 3, figsize=(15, 5))

for i, (trace, title) in enumerate([
(trace_no_pool, 'プーリングなし'),
(trace_complete, '完全プーリング'),
(trace_partial, '部分プーリング(階層ベイズ)')
]):
ax = axes[i]

if title == '完全プーリング':
mu_samples = trace.posterior['mu_global'].values.flatten()
means = [mu_samples.mean()] * n_areas
hdi = az.hdi(trace, var_names=['mu_global'], hdi_prob=0.95)
hdi_low = [hdi['mu_global'].values[0]] * n_areas
hdi_high = [hdi['mu_global'].values[1]] * n_areas
else:
means = trace.posterior['mu'].mean(dim=['chain', 'draw']).values
hdi = az.hdi(trace, var_names=['mu'], hdi_prob=0.95)
hdi_low = hdi['mu'].values[:, 0]
hdi_high = hdi['mu'].values[:, 1]

ax.plot(range(n_areas), true_means, 'ro-', label='真の値', markersize=10)
ax.plot(range(n_areas), means, 'bs-', label='推定値', markersize=8)
ax.fill_between(range(n_areas), hdi_low, hdi_high, alpha=0.3)

ax.set_xticks(range(n_areas))
ax.set_xticklabels(area_names, rotation=45)
ax.set_ylabel('問い合わせ数')
ax.set_title(title)
ax.legend()
ax.grid(alpha=0.3)

plt.tight_layout()
plt.show()

print("\n=== サンプル数の少ないエリア(世田谷区)の推定精度比較 ===")
print(f"真の値: {true_means[3]}")
print(f"プーリングなし: {trace_no_pool.posterior['mu'].mean(dim=['chain', 'draw']).values[3]:.1f}")
print(f"完全プーリング: {trace_complete.posterior['mu_global'].mean():.1f}")
print(f"部分プーリング: {trace_partial.posterior['mu'].mean(dim=['chain', 'draw']).values[3]:.1f}")

部分プーリングの効果

  • プーリングなし: サンプル少ないエリアで推定が不安定
  • 完全プーリング: エリア差を無視してしまう
  • 部分プーリング: エリア差を考慮しつつ、全体の傾向から情報を借りて安定化 ✅

Day 3-5: 実践的な階層モデル構築

水曜〜金曜(各3時間)

  • 水曜: エリア × 物件タイプの2階層モデル
  • 木曜: 時変効果を含む階層モデル
  • 金曜: 実データでの総合演習

2階層モデルの実装

# エリア × 物件タイプの階層モデル
import pymc as pm
import arviz as az
import pandas as pd
import numpy as np

# データ準備
np.random.seed(42)
areas = ['渋谷区', '新宿区', '港区']
types = ['マンション', '戸建て']

data = []
for area_i, area in enumerate(areas):
for type_i, ptype in enumerate(types):
n = np.random.randint(20, 50)
# エリアと物件タイプの効果
base = 100 + area_i * 10 + type_i * 5
price = np.random.normal(base, 10, n)
for p in price:
data.append({'area': area, 'type': ptype, 'price': p})

df = pd.DataFrame(data)

# カテゴリを数値化
area_idx, area_names = pd.factorize(df['area'])
type_idx, type_names = pd.factorize(df['type'])
n_areas = len(area_names)
n_types = len(type_names)

# 階層モデル
with pm.Model() as hierarchical_model:
# 全体の平均
mu_global = pm.Normal('mu_global', mu=100, sigma=20)

# エリア効果の階層
sigma_area = pm.HalfNormal('sigma_area', sigma=10)
mu_area = pm.Normal('mu_area', mu=0, sigma=sigma_area, shape=n_areas)

# 物件タイプ効果の階層
sigma_type = pm.HalfNormal('sigma_type', sigma=10)
mu_type = pm.Normal('mu_type', mu=0, sigma=sigma_type, shape=n_types)

# 組み合わせ効果
mu = pm.Deterministic('mu',
mu_global + mu_area[area_idx] + mu_type[type_idx])

# 誤差
sigma = pm.HalfNormal('sigma', sigma=10)

# 尤度
obs = pm.Normal('obs', mu=mu, sigma=sigma, observed=df['price'])

# サンプリング
trace = pm.sample(2000, return_inferencedata=True,
target_accept=0.95)

# 結果の可視化
az.plot_forest(trace, var_names=['mu_area', 'mu_type'])
plt.tight_layout()
plt.show()

print(az.summary(trace, var_names=['mu_global', 'mu_area', 'mu_type',
'sigma_area', 'sigma_type']))

土日(各3時間)

  • 土曜: Week 3総復習
    • 階層ベイズの概念整理
    • 実装コードの復習
  • 日曜: ケーススタディ
    • 自社データで階層モデル構築
    • 結果レポート作成

Week 3 完了チェックリスト

☐ 階層構造の概念を説明できる
☐ 部分プーリングの効果を理解している
☐ 2階層以上のモデルを実装できる
☐ 収縮効果を可視化できる
☐ 実データで階層モデルを適用できた

Week 4: Bayesian A/Bテストと一般化線形モデル

Week 4 の学習目標
  • Bayesian A/Bテストを設計・実装できる
  • 頻度論のA/Bテストとの違いを理解する
  • ロジスティック回帰、ポアソン回帰を実装できる
  • 不動産マーケティングでの実践的な応用ができる
Day 1-2: Bayesian A/Bテスト

月曜日(3時間)

  • 全日(3時間): Udemy講座 Section 8「Bayesian A/Bテスト」
    • 従来のA/Bテストの問題点
    • ベイズアプローチの利点
    • 早期終了(early stopping)の可能性
ベイズ A/Bテストの5つの利点

  1. 直感的な解釈: 「Aが優れている確率は85%」と言える
  2. 事前知識の活用: 過去のテスト結果を事前分布に反映
  3. 逐次分析: データ収集中に途中確認してもOK
  4. 損失関数: ビジネス的な損失を組み込める
  5. 不確実性の定量化: 「差が5〜10%ある」と幅を持って表現

-Uncategorized