Meta広告の重複をPythonで検知して分かった3つ
Meta広告のCPAが下がらない。予算を足しても配信が伸びない。その原因が、実は自分の広告セット同士の「オーディエンス重複」にある場合は多い。同じユーザー層を複数の広告セットで狙うと、Metaのオークションで自社の広告が競合し、CPMが上がる。この記事では、広告マネージャの手動確認ではなく、Marketing APIとPythonで重複を検知する手順をまとめた。実運用で詰まった点も添える。
なぜ広告セットの重複がCPAを押し上げるのか
オーディエンス重複とは、複数の広告セットが同一ユーザーを配信対象に含む状態を指す。重複率が高いと、Metaのオークションで自社の広告セット同士が入札を奪い合う。結果、CPMが上がりCPAも連動して悪化する。特にカスタムオーディエンスと類似オーディエンスを併用する構成で起きやすい。
広告マネージャにも「オーディエンスの重複を表示」機能はある。ただし手動で2つずつ選ぶ方式で、広告セットが10個を超えると現実的に回らない。運用規模が大きいほど、APIで一括取得して機械的に判定する価値が出る。手動確認の限界はMeta広告レポートをPythonで自動化する実装手順でも触れたとおりだ。
Marketing APIで広告セットのtargetingを取得する
重複判定の入口は、各広告セットの配信条件(targeting)をAPIで取ることだ。エンドポイントは広告アカウント配下の adsets で、fields に name と targeting を指定する。1行で書くと GET https://graph.facebook.com/v20.0/act_アカウントID/adsets?fields=name,targeting,effective_status&access_token=トークン を叩けば、各広告セットのJSONが返る。
targetingの中で重複判定に効くキーは4つある。(1)geo_locations(地域)(2)age_min と age_max(年齢帯)(3)genders(性別)(4)custom_audiences と flexible_spec 内の interests(カスタム客層・興味関心)。特にcustom_audiencesのIDが複数の広告セットで一致していれば、それは明確な重複シグナルだ。公式の項目名はMetaのMarketing APIドキュメント(developers.facebook.com/docs/marketing-api)で確認できる。
Pythonで重複を判定する実装骨格
ブックマークして、自分のアカウントIDに書き換えて使ってほしい。処理の流れはシンプルだ。(1)adsetsを全件取得しリスト化(2)各広告セットからcustom_audiencesのID集合を取り出す(3)広告セットを総当たりで比較し共通IDの数を数える(4)共通IDが1つ以上あるペアを重複候補として出力する。
コアの判定は集合演算で書ける。1行なら overlap = set(a["ca"]) & set(b["ca"]) とし、len(overlap) > 0 なら重複ありと判定する。地域と年齢も同様に、geo_locationsのkey集合や年齢範囲の重なりを見れば精度が上がる。requestsでAPIを叩き、itertools.combinationsで全ペアを回すのが定石だ。
チェックリストとして最低限おさえる項目は次の5つ。(1)ページング(paging.next)を辿り全件取得したか(2)custom_audiencesが空の広告セットを除外したか(3)同一キャンペーン内だけでなくアカウント横断で比較したか(4)停止中の広告セットを除外したか(5)判定結果をCSVかSlackに出力したか。この5点を満たせば実運用に乗る。この判定の完全版はnoteの実践ガイドにコード込みでまとめている。
実際に検知して分かった3つの落とし穴
月数千万規模の運用アカウントで実装したところ、手動確認では見えなかった重複が複数見つかった。特に効いた学びは3つある。
1つ目。custom_audiencesのIDだけを見ると重複を見逃す。地域や興味関心だけが重なるケースが検知全体の約4割を占めた。IDの完全一致に加え、geo_locationsとinterestsの部分一致も判定に入れるべきだ。
2つ目。停止中の広告セットを含めると誤検知が増える。effective_statusがACTIVEのものだけを対象にしたら、重複候補が約3分の1に絞れた。配信していない広告セットは競合しない。当たり前だが、最初は見落とした。
3つ目。重複を見つけても即統合すると学習がリセットされる。CPAが安定した広告セットは残し、消化の少ない側を停止する順で進めたら、CPMが約1割下がった。学習リセットの扱いはtCPA学習リセットの条件と防ぐ運用ルール6つと同じ考え方で進めると安全だ。
この判定を毎朝バッチで回し、結果をクライアント報告用のスライドにまとめる運用にしている。検知結果を図解に落とすなら、AIスライド作成ツールを使うと作図の時間を圧縮できる。
本記事で紹介した検知フローの結果を、そのまま報告資料へ落とし込むなら以下のツールが使える:
まとめ
Meta広告の重複は、広告マネージャの手動確認では規模が大きいほど追いきれない。Marketing APIでtargetingを一括取得し、集合演算で機械的に判定すれば、CPMを押し上げる無駄な競合を短時間で洗い出せる。まずは全件取得と停止中除外の2点から着手するとよい。次の一手は、この判定を毎朝のバッチへ組み込むことだ。
実務でそのまま使いたい人へ
本記事の手法の完全版(実際のコード・テンプレート・つまずき対処つき)は、運営者のnote(note.com/ryo_ai_hack)で公開している。実データに基づく実践ガイドをまとめて読める。

コメント
コメントを投稿