AI×PyMC-Marketing — Claude Code・Cursor・YAMLで実現する次世代MMMワークフロー
はじめに
PyMC-Marketingのリポジトリには、あまり知られていない特徴があります。それは、Claude CodeとCursorのAI設定が公式に組み込まれていることです。
pymc-marketing/
├── .claude/ <- Claude Code用の設定
│ ├── CLAUDE.md セッション指示書
│ ├── commands/ 23種のスラッシュコマンド
│ └── agents/ エージェント定義
│
└── .cursor/ <- Cursor IDE用の設定
├── rules/basic.mdc 常時適用ルール
└── skills/ 7種のスキルモジュール
つまり、リポジトリをクローンしてClaude CodeやCursorを起動するだけで、PyMC-Marketingに特化したAIアシスタントが使えるのです。
なぜこれが重要なのか: PyMC-Marketingはベイズ統計、確率プログラミング、マーケティングサイエンスという3つの専門分野が交差する領域です。汎用的なAIアシスタントでは、このドメイン特有のパターン(事前分布の設計、MCMC診断、Adstock変換の選択等)に対して的確な回答が難しい場面があります。公式のAI設定は、これらの専門知識をAIのコンテキストに注入することで、ドメイン特化型のアシスタントを実現しています。
本記事では、YAML駆動モデリング、Streamlit可視化、Claude Code連携、Cursor IDE連携を組み合わせた次世代MMMワークフローの全貌を解説します。
1. YAML駆動モデリング
PyMC-Marketing v0.18以降で導入された MMM.from_yaml() は、コードを書かずにMMMモデルを定義できる機能です。YAMLファイルにモデル構成を記述するだけで、Pythonコード1行でモデルをインスタンス化できます。
1.1 MMM.from_yaml() の基本的な使い方
from pymc_marketing.mmm import MMM
import pandas as pd
# YAMLからモデルを構築(1行)
mmm = MMM.from_yaml("model_config.yml")
# データ読み込み & フィッティング
df = pd.read_csv("marketing_data.csv", parse_dates=["date_week"])
mmm.fit(X=df, target_column="revenue")
1.2 基本YAMLテンプレート(コメント付き)
以下は、そのまま使えるYAMLテンプレートです。コメントで各パラメータの意味と推奨値を記載しています。
# ========================================
# PyMC-Marketing MMM 基本設定テンプレート
# ========================================
model:
type: mmm # モデル種別(mmm固定)
date_column: date_week # 日付列名(週の開始日)
target_column: revenue # 目的変数(売上等)
# --- チャネル列 ---
channel_columns:
- tv_spend # TV広告費
- digital_spend # デジタル広告費
- social_spend # SNS広告費
# --- コントロール変数(オプション) ---
control_columns:
- holiday_flag # 祝日フラグ(0/1)
- temperature # 気温(外部変数)
# --- Adstock設定 ---
adstock:
type: geometric # geometric | weibull | binomial
l_max: 8 # 最大ラグ週数(TV: 8-12, Digital: 2-4)
# --- 飽和関数設定 ---
saturation:
type: logistic # logistic | hill | tanh | michaelis_menten
# --- 季節性 ---
yearly_seasonality: 2 # フーリエモード次数(2-3推奨)
# --- サンプリング設定 ---
sampling:
draws: 1000 # MCMCサンプル数(本番: 2000)
tune: 1000 # バーンイン数(本番: 2000)
chains: 4 # チェーン数(4推奨)
target_accept: 0.9 # 受容確率(発散時: 0.93-0.95)
random_seed: 42 # 再現性用シード
1.3 カスタマイズパターン
パターンA: カスタム事前分布
model:
type: mmm
date_column: date_week
target_column: revenue
channel_columns:
- tv_spend
- digital_spend
- social_spend
adstock:
type: geometric
l_max: 8
saturation:
type: logistic
# --- カスタム事前分布 ---
priors:
beta_channel:
dist: HalfNormal
kwargs:
sigma: [0.1, 0.05, 0.025] # TV > Digital > SNS
intercept:
dist: Normal
kwargs:
mu: 0
sigma: 5
alpha: # Adstock残存率
dist: Beta
kwargs:
alpha: 3
beta: 3
パターンB: Geoモデル(階層ベイズ)
model:
type: mmm
date_column: date
target_column: sales
channel_columns:
- tv_spend
- digital_spend
geo_column: region # 地域列を指定
adstock:
type: weibull # Weibullで柔軟な残存効果
l_max: 12
saturation:
type: hill # Hill関数で急激な飽和もモデル化
yearly_seasonality: 3
1.4 YAML比較実験ワークフロー
YAML駆動の最大の利点は、異なるモデル設定を簡単に比較実験できることです。以下は、異なるAdstock型を比較するワークフローです。
import yaml
import copy
import arviz as az
import pandas as pd
from pymc_marketing.mmm import MMM
from pymc_marketing.paths import data_dir
# ベース設定の読み込み
with open("base_config.yml") as f:
base_config = yaml.safe_load(f)
# 実験設定: 4つのAdstock型を比較
experiments = {
"geometric_8": {"type": "geometric", "l_max": 8},
"geometric_12": {"type": "geometric", "l_max": 12},
"weibull_8": {"type": "weibull", "l_max": 8},
"weibull_12": {"type": "weibull", "l_max": 12},
}
# データ読み込み
df = pd.read_csv(
data_dir / "mmm_example.csv",
parse_dates=["date_week"]
)
results = {}
for name, adstock_config in experiments.items():
print(f"\n=== 実験: {name} ===")
# YAMLを動的に生成
config = copy.deepcopy(base_config)
config["model"]["adstock"] = adstock_config
yaml_path = f"experiment_{name}.yml"
with open(yaml_path, "w") as f:
yaml.dump(config, f)
# モデル構築 & フィッティング
model = MMM.from_yaml(yaml_path)
model.fit(X=df, target_column="y")
# LOO-CVスコアで評価
loo = az.loo(model.fit_result)
results[name] = {
"elpd_loo": loo.elpd_loo,
"se": loo.se,
"p_loo": loo.p_loo,
}
print(f" LOO = {loo.elpd_loo:.2f} (SE: {loo.se:.2f})")
# ベストモデルの選択
best = max(results, key=lambda k: results[k]["elpd_loo"])
print(f"\n*** 推奨モデル: {best} ***")
print(f" LOO = {results[best]['elpd_loo']:.2f}")
1.5 LOO-CV(az.loo())によるモデル選択と解釈
LOO-CV(Leave-One-Out Cross-Validation)は、ベイジアンモデル比較の標準手法です。
import arviz as az
# 単一モデルのLOO-CV
loo = az.loo(model.fit_result)
print(loo)
# 出力例:
# elpd_loo: -245.3 <- 高いほど良い
# se: 12.1 <- 標準誤差
# p_loo: 8.7 <- 有効パラメータ数
# 複数モデルの比較
comparison = az.compare({
"geometric_8": model_geo8.fit_result,
"geometric_12": model_geo12.fit_result,
"weibull_8": model_weibull8.fit_result,
})
print(comparison)
# 出力: rank, elpd_loo, p_loo, weight 等の比較表
LOO-CV解釈のポイント:
| 指標 | 意味 | 判断基準 |
|---|---|---|
elpd_loo | 期待対数予測密度 | 高いほど良い(負の値で、0に近いほど良い) |
se | 標準誤差 | 2モデルのelpd_loo差がSEの2倍未満なら実質的に同等 |
p_loo | 有効パラメータ数 | 実際のパラメータ数より大幅に大きい場合は過学習の兆候 |
weight | モデル重み | ベイジアンモデル平均化に使用 |