【保存版】Google製MMM「Meridian」で広告予算を科学する実装ガイド(Github深圳データ分析実例)
こんにちは、月ねこAIです。🌕🐈⬛
皆さんの現場では、広告予算の配分をどう決めていますか?
「昨年通りで」とか「なんとなくデジタルを増やそうで」といった勘と経験になっていませんか?
昨今、Cookie規制やプライバシー保護の強化により、ユーザー単位のトラッキング(MTA: Multi-Touch Attribution)が限界を迎えています。そこでエンジニア・データサイエンティスト界隈で再注目されているのが、統計学的に全体の効果を推定するMMM・マーケティング・ミックス・モデリングです。
今回は、Googleが2024年に公開したOSSのベイズ推定MMMライブラリMeridianを使い、実際の広告データ(深圳市の実データ)を用いて分析から予算最適化までを走らせてみました。
この記事では、実務でMeridianを動かすための最短ルートとエンジニアが知っておくべきハマりポイントを、月ねこAI流に解説します。
🚀 この記事で得られること
- Meridianの環境構築: TensorFlowのバージョン依存など、実務的な罠の回避法
- 実装フロー: データ加工からモデリング、予算最適化までのコード実装例
- 実データ分析の結果: TV vs インターネットのROI比較と、最適化シミュレーションの実例
対象読者
- Pythonでデータ分析ができるエンジニア・データサイエンティスト
- 広告効果測定の「脱・ラストクリック」を模索しているマーケター
- ベイズ推定を用いた因果推論に興味がある方
1. 前提・環境・アーキテクチャ
今回は以下の環境で検証を行いました。Meridianは現在も活発に開発が進んでいるため、バージョン固定が再現性の鍵になります。
- Python: 3.10+
-
Library:
google-meridian==1.1.6 -
Dependencies:
tensorflow==2.18.0(※ここ重要) - Data: 深圳市の家電メーカー(TV事業)の実広告データ(2010-2017)
なぜ今、Meridianなのか?
Meta製の「Robyn」も有名ですが、Meridianには以下の特徴があります。
- 「モデル選択」からの解放: Robynは何千ものモデル候補から「選ぶ」必要がありますが、Meridianは階層ベイズモデルで「1つの最適なモデル」を推定する思想です。
- 因果推論の重視: 広告の飽和効果(S字カーブ)や残存効果(アドストック)を厳密に分離しやすい設計になっています。
- Googleエコシステム: BigQueryやVertex AIとのシームレスな連携がすでに確立されており、データ抽出からモデル学習までのパイプラインをGoogle Cloud上で完結できる点が最大の強みです。
全体アーキテクチャ
今回の分析フローは以下の通りです。
2. データ準備と前処理(Data Prep)
MMMで最も重要なのはデータです。今回は、需要(販売台数)、広告費(TV, Radio, Internet等)、外部要因(CPI, PPI)を含むデータセットを使用しました。
Step 1: データの読み込みと週次集計
MMMは一般的に週次・Weeklyでモデルを作成します。日次データのままだとノイズが大きすぎるためです。
import pandas as pd
# データの読み込み
df = pd.read_excel("MMM_data.xlsx")
# 週次への集計(ここがポイント)
# 日次データを 'W' (Weekly) でリサンプリングし、sum()で合計をとる
weekly = df.copy()
weekly['time'] = pd.to_datetime(weekly['DATE'])
weekly = weekly.set_index('time').resample('W').sum().reset_index()
# 必要なカラムの整形(prefixをつけると管理しやすい)
# control_cols: 外部要因(物価指数など)
# media_cols: 広告インプレッション/支出
Step 2: マルチコ(多重共線性)の確認
広告媒体ごとの出稿量は相関しがちです(例:キャンペーン時にTVもWebも一気に増やすなど)。VIF(分散膨張係数)を確認しておきましょう。
ソースコードを見る(VIF計算)
from statsmodels.stats.outliers_influence import variance_inflation_factor
# VIF計算の実装例
X = weekly[control_cols].fillna(method='ffill')
vif_data = pd.DataFrame()
vif_data["feature"] = X.columns
vif_data["VIF"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
print(vif_data)
今回のデータでは全ての変数が VIF < 5 に収まっており、多重共線性の懸念は低いことが確認できました。
3. Meridianの実装とモデリング
ここからが本番です。Google Colabなどで実行する場合、ライブラリのバージョン整合性が最大の沼ポイントです。
Step 3: インストール(バージョン固定)
Meridian 1.1.6 は TensorFlow 2.19系をまだサポートしていない場合があるため、2.18.0 を明示的に入れます。
!pip install tensorflow==2.18.0
!pip install google-meridian==1.1.6
Step 4: モデルスペックの定義と実行
Meridianでは InputData オブジェクトを作成し、そこにKPI、広告データ、コントロール変数をマッピングします。
import meridian
from meridian.model import spec
# データマッピング
input_data = meridian.data.InputData(
time=weekly['time'],
kpi=weekly['kpi'],
media=weekly[media_impression_cols],
media_spend=weekly[media_spend_cols],
controls=weekly[control_cols],
population=None # 地域階層がない場合はNoneでも可
)
# モデルスペックの定義
model_spec = spec.ModelSpec(
media_channel_names=media_names,
# ROIなどの事前分布をここで設定可能
)
# モデルの学習(MCMC)
mmm = meridian.model.Meridian(input_data=input_data, model_spec=model_spec)
mmm.sample_posterior(n_chains=4, n_adapt=1000, n_burnin=1000, n_draws=1000)
4. モデル診断と結果の解釈
モデルができたら、「本当に信頼できるのか?」を診断します。
Step 5: 収束診断(R-hat)
ベイズ推定が正しく収束しているかを確認します。R-hat値が 1.1未満(理想は1.0に近い)であればOKです。
今回の分析では、全てのパラメータ(alpha_m, beta_m, roi_m など)で R-hat ≈ 1.0 となり、非常に安定した収束が見られました。
Step 6: 予測精度 (Model Fit)
実測値(Actual)と予測値(Expected)の適合度を見ます。
今回のモデルでは R-squared(決定係数)が 0.93、MAPE(誤差率)が 1% と、驚異的な精度が出ました。ベースライン(広告なしの売上)としっかり分離できています。

Step 7: ROI(投資対効果)の可視化
最も気になる「どの広告が効いているのか?」の結果です。
- TV: 投資額は大きいが、ROIは相対的に低め(飽和している可能性)。
- Internet: 売上貢献・ROI共に高く、成長ドライバーとなっている。
- Radio/Newspaper: 効果は限定的。
# ROIのプロット(Meridianのビジュアライザーを使用)
from meridian.analysis import visualizer
visualizer.plot_roi_posterior(mmm)

結果として、**「TVとInternetが大半を占めるが、Internetの方が効率が良い」**という示唆が得られました。
5. 予算最適化シミュレーション
MMMの醍醐味は「分析して終わり」ではなく、「次はどう配分すべきか?」を提示できる点にあります。Meridianの最適化機能を使ってみましょう。
Step 8: 予算アロケーションの最適化
「予算総額を変えずに、ROIを最大化する配分」を計算させます。
from meridian.analysis import optimizer
# 予算固定での最大化シミュレーション
opt_results = optimizer.optimize_budget(
mmm,
budget=total_budget, # 現状の予算総額
media_identifier='media_channel'
)
# 結果の表示
print(opt_results.optimized_media_spend)
シミュレーション結果:
- Internet: 予算配分を 67% → 68% に微増
- TV: 予算配分を 29% → 28% に微減

インパクト:
この微調整だけで、インクリメンタル収益(広告による上積み売上)が +2,000ドル 改善する試算が出ました。
「たった1%?」と思うかもしれませんが、大規模な予算において「根拠を持って1%動かせる」ことは、エンジニアリングとして非常に価値があります。
6. まとめ・実務への応用
今回のMeridianを用いた検証で、以下のことが分かりました。
-
高い再現性:
という高精度なモデルが構築できた。R^2=0.93 - 明確な示唆: 「TVからInternetへ」という予算シフトの根拠を数値で出せた。
- Pythonで完結: データ加工から最適化までPythonエコシステムで統一できるメリットは大きい。
現場で使うための月ねこTIPS 🐈
- データは「週次」が基本: 日次データはノイズが多いので、週次に丸めるのがMMMの定石です。
- 日本語フォント問題: Colab環境では日本語フォントがインストールされていないため、プロット時に文字化け(豆腐化)や大量のFont Warningが発生します。japanize-matplotlib を導入するか、ラベルを英語で統一するのが回避策です。
- 「1つの正解」ではない: MMMはあくまで「相関と因果の推論」です。現場のマーケターの肌感覚と乖離がないか、対話しながらチューニングすることが成功の鍵です。
Next Action 👉
まずは手元のExcelデータ(売上と広告費)を週次で集計し、Meridianのサンプルコードに流し込んでみましょう!「見えなかった効果」が見えてくるはずです。
分析レポートの完全版(スライド)
今回の検証結果をまとめたレポート資料です。実務での報告イメージとしてご活用ください。
参考文献

Discussion