
はじめに
はじめまして。マーケティング本部データ戦略部事業アナリシスグループ所属の大浦と申します。データアナリストとして、データに基づいた施策提案や効果検証などサービス/プロダクトのグロースに日々取り組んでいます。
この記事では、最近よく話題に上がっているMMM(Marketing Mix Modeling)について書いています。
従来であれば、クッキーを利用したユーザ個々人単位での細かな分析が可能でしたが、個人情報保護に伴うクッキーレスへの移行により、広告効果やその他施策の効果を全体的に評価するための分析・技術への期待が高まってきています。
広告投資は事業の成長に欠かせないものであり、経営層は合理的な投資判断を迫られます。その需要に伴い、MMM活用による投資判断・戦略策定が流布されるようになってきていると感じています。ビッグテックによりMMMのOSSの公開(GoogleのLightweightMMMやMetaのRobynなど)もなされ、手軽にMMMを実行できる機会が今後も増えてくるのではないかと考えています。
MMMプロジェクトは基本的には機密情報を含んだものであるため、実際の事例の紹介記事などはほとんど出回っておらず、OSSにおいてもまだ発表されてから間もないため、デモデータで試したブログ記事などしかありません(それらの記事も参考になるので、ぜひ読んでいただければ幸いです)。
今回、弊社の某サービスにおける広告効果の評価に関して、LightweightMMM(以下、LMMM)を試してみる機会がありましたので、実践データに適用した感想を書いてみたいと思います。ただし上述の通り、機密情報を含んだ詳細は公開できないため、あくまで使ってみた感想という範囲に留めさせていただきます。
私自身がはじめてMMMプロジェクトに取り組んでみたのですが、今回はその観点からの感想であるため、MMMにはじめて取り組む、あるいははじめてLMMMを使ってみる、というような方に向けた記事になっていることをあらかじめご了承ください。
なお、MMMの技術的な話については、博報堂さんが出しているこちらの資料に非常に詳しくまとまっているので、参考にしてもらえればと思います。
モデリング概要
サービスの特徴
DMMには60を超えるサービスが存在しており、それぞれの事業で広告出稿やキャンペーン実施などの投資判断を行っています。今回はそのうちの一つの事業データに対してLMMMを適用しました。サービスの特徴は以下のようなものでした。
- 広告出稿の媒体が多岐に渡る
- アフィリエイト・リターゲティング・ディスプレイ・SNSなど
- 定期的なキャンペーンが実施されている
- 自サービス内でのキャペーン
- A%還元やB円分のポイントプレゼントなど
- C円以上買うとD%OFFクーポン適用など
- DMMプラットフォーム全体のキャンペーン
- 他サービスと両方利用するとE円キャッシュバックなど
- 自サービス内でのキャペーン
- その他の訴求
- メルマガなど
データセット
ー 目的変数
各広告の貢献度を測定するKPI(目的変数)としては、売上と新規CV数を設定しました。
ー 説明変数
LMMMには説明変数の入れ方として、広告の出稿量(インプレッション数、コストなど)に関する広告変数と、キャンペーンの有無などを表す外部変数の2つが存在します。今回は、「サービスの特徴」の章で掲載したさまざまな変数をモデリングに組み込みましたが、その中でも一筋縄ではいかなかった変数の一部について少し触れたいと思います。
目的変数に対して広告の影響もありそうですが、自サービス内で大規模なポイント還元キャンペーンが複数回実施されており(かつ、それぞれで還元率が異なる)、その影響がかなり大きいと事前に予想されていました。
ここで、キャンペーンを表す外部変数の入れ方としてはいくつかの案がありました。例えば、シンプルな0,1フラグにより、キャンペーン期間中は1でそれ以外は0とするような案がありました(実際はこれに還元率を掛ける)。一見良さそうに思えましたが、これは同一キャンペーン期間内での効果を全日程で同等に扱うという仮定になっています。しかし、実データを確認すると、初日だけ盛り上がってあとは減衰していくパターンや終了間際に駆け込み需要が発生して盛り上がるパターンなどキャンペーンごとの特性があり、先述の仮定が満たされない状況になっていました。

他には、ポイント発行された金額を用いるという案もありましたが、発行額は同日の売上に対して還元したものであるため、そのまま用いると因果関係が合致していなそうです。

実際には、キャンペーンごとに盛り上がり方の傾向と規模感(還元率や対象商品数など)の2つを加味した変数を作成し、モデリングを行いました。その際にもいくつかの仮定を置いていたため、それらの仮定が許容できそうかを意識していました。予測精度を極限まで上げること自体が目的ではないので、あまり複雑にし過ぎず解釈しやすいものになるように気を付けました。事前に別の因果推論手法でキャンペーン自体のKPIのリフトを見積もる分析をしていたこともあり、その結果と検算を行うことで妥当性を確認しました。
新規CV数についても、自サービス内のキャンペーンの影響が大きくなります。こちらも上記と同様の変数を使おうとしていましたが、KPIの推移を確認していたところ、キャンペーンごとの盛り上がり方の傾向が売上とは異なることが判明したため、それに合わせた対応を行いました。
デモデータなどでは説明変数をそのまま入れているだけなのであまり実感しにくいですが、実データを使うときはそのデータの背後にある仮定や因果関係を考え、実態に即した変数を考えないといけないということを実感しました。
使ってみた感想
良かった点
使い方が非常にシンプルで手軽に試しやすい点が良いと感じました。LMMMのデモnotebookの通りにデータを整形して動かすだけで、とりあえず何らかの結果がクイックに出せます(その結果が妥当かは別の話ですが)。MCMCの収束具合、各パラメータの事後分布、予測精度なども数行で出せるため、試行錯誤しやすかったです。また、モデリングだけでなくROIの計算やそれを踏まえた予算の最適化など、MMMプロジェクトの一連の流れも簡単にできるのも良かったです。変数間での多重共線性や各変数の分散のチェックなど、MMM入門時に陥りやすい間違いも検出できるようになっていたのも親切だと思いました。
総じて、スクラッチで組む時間がない人やとりあえず触ってみたい人には良いものになっており、今後MMMの間口が広がっていきそうだなと感じました。
気を付けるべき点
ここでは実際に使用してみて感じたLMMMの気を付けるべき点と、MMM自体の気を付けるべき点を述べていきます。
ー LMMM
ライブラリをインストールしてから最後の結果を出すまでの一連の流れにおいて感じた気を付けるべき点をいくつか書きます。
バージョン管理をする
LMMMを動かすために必要な諸々のライブラリのバージョンが突如アップデートされることがあり、以前動いていたものが急にエラーを吐いて動かなくなることがありました。納期直前にこのような事態に陥らないように安定して動く環境を用意することをオススメします。
事前分布の設定は気を付ける
MMMは基本的には回帰をしているだけなので、何も考えずにそのままデータを入れると、一見モデルの当てはまりは良いものの各変数の貢献値が実態とは乖離しているということが起こり得ます。ビジネス観点を踏まえて、それぞれをどのように事前分布させるかを適切に設定することが重要だと感じました。KPIに対してネガティブな影響を与えることがないと考えられる広告の係数については、非負となる事前分布を設定するというような対応が必要です。
一階層のモデルを仮定している
LMMMはシンプルな一階層(今回はオンライン型クリックルートを指す)の回帰モデルを採用しています。モデル構造が誤っていると貢献値の推定において大きな誤差が生じる可能性があるため、一階層のモデル構造で問題ないかは慎重に検討する必要があります(詳細はこちら)。 一方で、過去の事例などから二階層以上(例えば、オンライン型クリックルート+サーチルートを指す)が適切なのではと考えても、該当するデータが取得できない可能性もあります。そのため、取得可能なデータの確認とそれらを最大限に活かしたデータ構造の検討もかなり重要だなと感じました。場合によってはMMM以外の方法で試す方が良いこともあるのかもしれません。この辺りの知見がある方は教えていただけると幸いです。
結果の可視化が少し物足りない
今回のモデリングではキャンペーン(外部変数)の貢献値も見積もる必要がありましたが、現状の結果を可視化するコードでは広告変数しか貢献値を見れませんでした。そのため、元のソースコードをいじることで全ての変数の貢献値を出すという対応を行いました。以下のように、model.pyとplot.pyを少し変えればできます。
[model.pyのmedia_mix_model]
if extra_features is not None: plate_prefixes = ("extra_feature",) extra_features_einsum = "tf, f -> t" # t = time, f = feature ...(省略)... # ここを追加 extra = numpyro.deterministic( name="extra_features", value=extra_features)
[plot.pyの_calculate_media_contribution]
...(省略)... if media_mix_model.trace["media_transformed"].ndim > 3: # s for samples, t for time, c for media channels, g for geo einsum_media = "stcg, scg->stcg" # ここを追加 einsum_extra = "stfg, sf -> stfg" elif media_mix_model.trace["media_transformed"].ndim == 3: # s for samples, t for time, c for media channels einsum_media = "stc, sc->stc" # ここを追加 einsum_extra = "stf, sf -> stf" media_contribution = jnp.einsum(einsum_media, media_mix_model.trace["media_transformed"], media_mix_model.trace["coef_media"]) # ここを追加 extra_contribution = jnp.einsum(einsum_extra, media_mix_model.trace["extra_features"], media_mix_model.trace["coef_extra_features"]) if media_mix_model.trace["media_transformed"].ndim > 3: # Aggregate media channel contribution across geos. media_contribution = media_contribution.sum(axis=-1) # ここを追加 extra_contribution = extra_contribution.sum(axis=-1) return media_contribution, extra_contribution
あとは、plot.pyのcreate_media_baseline_contribution_dfの中で、mediaと同様の処理をextra_featuresに対して実行して、貢献度のデータフレームを作ればできます(長くなるので省略します)。
ー MMM
次に、はじめてMMMに取り組んで実感したMMM自体の気を付けるべき点を書きます。
データが必ずしもキレイではない
データサイエンスの現場全般に言われていることですが、データの汚さに対して特にMMMは脆弱だと感じました。各広告の効果を精度良く出すにはキレイなデータがないと難しいと思いますが、そのような状況はなかなか存在しなさそうです。これは、最初からMMMプロジェクトを実施する想定で広告出稿をしているわけではなく、KPIを向上させるために場当たり的に広告出稿しているので、出稿パターンのキレイさなどは気にしていないからです。例えば、2つの広告間で出稿パターンが酷似している、キャンペーン時だけ出稿している広告がある、出稿エリアが時期によって異なる、といったデータの洗礼を浴びることは覚悟しておいた方が良さそうです。実際、これらのようなケースに対して、強い仮定を置きまくって精度の悪さには目をつむることしかできないのでしょうか?正当なデータを今後取得するように説得・計画するためには、この辺りの分析者やPMとしての立ち回りのうまさも必要であるとともに、MMMプロジェクトを推進する肝であるなと思いました。
結果の妥当性の判断が難しい
モデリングの良し悪しはMCMCの収束具合やMAPEなどの評価指標で判断できますが、必ずしもそれだけで結果を判断しない方が良さそうです。今回、効果が小さかったことが事前にわかっていた広告が一部あったのですが、その事前情報よりも大きい貢献値が算出されてしまうということが起こりました。そのため、ビジネス側の感覚と乖離していないか、乖離しているとしたら設計・モデリングなどのプロセスで強い仮定を置きすぎていないかなどを確認してから最終的な結果を判断した方が良さそうだと感じました。MMMの使い方としては、ゼロから新たな発見を目指すというよりは、ビジネス側の感覚を数理的な観点で補強するというスタンスの方が安全であるというのが現時点での思いです。ただし、感覚に合わせすぎるあまり恣意的にならないように注意が必要です。
予算最適化の期待感を上げ過ぎない
個人的には予算の最適化がMMMプロジェクトの花形かなと思っています。LMMMでは任意の期間のデータを入れるだけで手軽に予算の最適化を行え、それっぽい結果も返ってきます。しかし、その最適化が本当に妥当かはしっかりと考えなければなりません。例えば、今年のデータを用いて来年の予算を最適化する場合、来年の状況が今年と全く同じという仮定のもとであればそれが最適解かもしれないですが、実際にはそのようなことはあり得ないです。競合他社の動きや世間のトレンド変化などさまざまな要因が絡んでくるため、真に最適化するのは困難だと思われます。そのため、現状は明らかにROIが悪そうな広告からROIが良さそうな広告へと投資額を多少移動させるという程度に留めておき、臨機応変に対応・検証していくべきなのかなと思っています。このあたりの期待感を高めすぎると、後々つらい状況になってしまいそうです。
まとめ
LMMM自体は手軽で便利であるという印象でした。とりあえず初手で試してみて、検討モデルの一つとして採用することへの違和感はありません。ただし、それぞれの会社で広告出稿データの種類が異なり、独自のサービス形態になっているはずなので、最終的には自社にフィットしたモデル構造をスクラッチで組む方が安定しそうだなと思いました。また、結果の解釈やチューニングも注意が必要であり、絶対にビジネス側の人と協議しながら進めるべきだと思います。
MMMの事例が多くは出回っていないため、まだあまり想像できていないのですが、MMMプロジェクトは「モデリング1回してハイ終わり」という類のものではなく、ABテストなどのトライアンドエラーを繰り返しながら徐々にKPIを向上させていくような、長期間にわたって粘り強く取り組んでいくものなのだろうなと感じました。
個人的には、MMMに関する知識・経験がまだまだ薄いと痛感したので、引き続き精進していきます。
終わりに
現在、事業アナリシスグループではアナリストを募集しています。
DMMには多様なデータが存在しており、統計や機械学習を用いた分析により事業貢献を目指しています。ご興味のある方は下記よりご応募ください。
DMMではカジュアル面談も行っています。気軽に話したい方はぜひお申し込みください。
カジュアル面談はこちら
参考文献
https://github.com/google/lightweight_mmm/
https://www.hakuhodody-media.co.jp/aaas/news/mmmguidebook.html