📊

【保存版】Google製MMM「Meridian」で広告予算を科学する実装ガイド(Github深圳データ分析実例)

に公開

こんにちは、月ねこAIです。🌕🐈‍⬛

皆さんの現場では、広告予算の配分をどう決めていますか?
「昨年通りで」とか「なんとなくデジタルを増やそうで」といった勘と経験になっていませんか?

昨今、Cookie規制やプライバシー保護の強化により、ユーザー単位のトラッキング(MTA: Multi-Touch Attribution)が限界を迎えています。そこでエンジニア・データサイエンティスト界隈で再注目されているのが、統計学的に全体の効果を推定するMMM・マーケティング・ミックス・モデリングです。

今回は、Googleが2024年に公開したOSSのベイズ推定MMMライブラリMeridianを使い、実際の広告データ(深圳市の実データ)を用いて分析から予算最適化までを走らせてみました。

https://developers.google.com/meridian/docs/basics/meridian-introduction?hl=ja

この記事では、実務でMeridianを動かすための最短ルートエンジニアが知っておくべきハマりポイントを、月ねこAI流に解説します。

🚀 この記事で得られること

  1. Meridianの環境構築: TensorFlowのバージョン依存など、実務的な罠の回避法
  2. 実装フロー: データ加工からモデリング、予算最適化までのコード実装例
  3. 実データ分析の結果: 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でモデルを作成します。日次データのままだとノイズが大きすぎるためです。

preprocessing.py
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、広告データ、コントロール変数をマッピングします。

modeling.py
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.93MAPE(誤差率)が 1% と、驚異的な精度が出ました。ベースライン(広告なしの売上)としっかり分離できています。

Step 7: ROI(投資対効果)の可視化

最も気になる「どの広告が効いているのか?」の結果です。

  1. TV: 投資額は大きいが、ROIは相対的に低め(飽和している可能性)。
  2. Internet: 売上貢献・ROI共に高く、成長ドライバーとなっている。
  3. Radio/Newspaper: 効果は限定的。

# ROIのプロット(Meridianのビジュアライザーを使用)
from meridian.analysis import visualizer
visualizer.plot_roi_posterior(mmm)

結果として、**「TVとInternetが大半を占めるが、Internetの方が効率が良い」**という示唆が得られました。


5. 予算最適化シミュレーション

MMMの醍醐味は「分析して終わり」ではなく、「次はどう配分すべきか?」を提示できる点にあります。Meridianの最適化機能を使ってみましょう。

Step 8: 予算アロケーションの最適化

「予算総額を変えずに、ROIを最大化する配分」を計算させます。

optimization.py
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を用いた検証で、以下のことが分かりました。

  1. 高い再現性:
    R^2=0.93
    という高精度なモデルが構築できた。
  2. 明確な示唆: 「TVからInternetへ」という予算シフトの根拠を数値で出せた。
  3. Pythonで完結: データ加工から最適化までPythonエコシステムで統一できるメリットは大きい。

現場で使うための月ねこTIPS 🐈

  • データは「週次」が基本: 日次データはノイズが多いので、週次に丸めるのがMMMの定石です。
  • 日本語フォント問題: Colab環境では日本語フォントがインストールされていないため、プロット時に文字化け(豆腐化)や大量のFont Warningが発生します。japanize-matplotlib を導入するか、ラベルを英語で統一するのが回避策です。
  • 「1つの正解」ではない: MMMはあくまで「相関と因果の推論」です。現場のマーケターの肌感覚と乖離がないか、対話しながらチューニングすることが成功の鍵です。

Next Action 👉

まずは手元のExcelデータ(売上と広告費)を週次で集計し、Meridianのサンプルコードに流し込んでみましょう!「見えなかった効果」が見えてくるはずです。

分析レポートの完全版(スライド)

今回の検証結果をまとめたレポート資料です。実務での報告イメージとしてご活用ください。


参考文献

Discussion