Claudeで広告クリエイティブの疲労を検知する — Meta広告のCSVから差し替え時期を出す
Meta広告の日次CSVから、フリークエンシーの上昇とCTRの低下が重なった広告を拾う手順です。判定スクリプトと、Claudeに渡すときの注意点をまとめました。
広告クリエイティブの疲労は、フリークエンシーの上昇とCTRの低下が同じ広告で同時に起きたときに疑う、という見方が実務では使いやすい指標です。広告単位の日次CSVがあれば、Claudeに集計させて「どの広告が、どの日から崩れたか」を一覧にできます。
ここでは、Metaの広告マネージャから書き出した日次CSVを例に、判定ルールの決め方、Claudeへの渡し方、手元で動くスクリプト、誤検知の切り分けまでを順に書きます。判定のしきい値は筆者が置いた例で、Metaが定めた基準ではありません。
疲労の判定は「フリークエンシー上昇」と「CTR低下」の同時成立で組む
結論から言うと、フリークエンシーだけ、あるいはCTRだけで差し替えを決めないほうが安全です。理由は単純で、片方だけが動く場面が多いからです。
- フリークエンシーだけが上がる: 配信対象が狭いだけで、反応は落ちていない広告がある
- CTRだけが下がる: 曜日、季節、入札や予算の変更といった別要因でも動く
2つを同時に見るルールにすると、誤検知がかなり減ります。次の形で書けるようにしておくと、Claudeに依頼するときも曖昧さが残りません。
単独指標と同時成立の違い
どちらか一方で判定
フリークエンシーが高いだけの広告まで差し替え候補に入ります。判定対象が多すぎて、優先順位が付きません。
両方が基準を超えたら判定
基準期間と直近期間を比べ、CTRの低下率とフリークエンシーの上昇率が両方しきい値を超えた広告だけを残します。
Meta広告の日次CSVを書き出すときに決めておくこと
広告マネージャの書き出しは、表示する列と内訳の設定がそのままCSVになります。疲労検知に必要なのは、次の5列です。列名は言語設定や書き出しの設定で変わるので、手元のCSVの見出しに合わせて読み替えてください。
| 必要な情報 | 役割 |
|---|---|
| 広告名(または広告ID) | 役割広告単位に分けるキー |
| 日 | 役割日次の並びを作る |
| リーチ | 役割フリークエンシーの分母 |
| インプレッション | 役割フリークエンシーとCTRの分母 |
| クリック数 | 役割CTRの分子 |
書き出す前に、内訳を「日」にしておきます。期間全体で1行にまとまったCSVでは、推移が見えません。
フリークエンシーは足し算できない
ここに落とし穴があります。リーチは「何人に届いたか」という重複を除いた人数なので、日次の行を単純に足しても期間全体のリーチにはなりません。
日次CSVから期間をまとめるときは、次のように扱います。
- CTR: クリック数の合計 ÷ インプレッションの合計(日ごとのCTRを平均しない)
- フリークエンシー: 期間内のインプレッション合計 ÷ 期間内のリーチ合計で近似する。厳密な値ではなく、期間同士を同じ方法で比べるための指標と割り切る
日ごとのCTRを平均すると、インプレッションの少ない日が過大に効きます。依頼文には「合計から再計算する」と明記しておくと、Claudeが平均で済ませる事態を防げます。
Claudeへの渡し方は3通り
CSVの扱いは、使う面によって条件が変わります。
| 渡し方 | 向く場面 | 押さえる条件 |
|---|---|---|
| Claudeのチャットにアップロード | 向く場面広告が数十本、単発で見たい | 押さえる条件コード実行が有効だとPythonで集計できる |
| Claude for Excel | 向く場面Excel上で条件付き書式やピボットまで作りたい | 押さえる条件対象のExcelとプランに制限がある |
| Claude Code | 向く場面毎週同じ判定を回したい | 押さえる条件スクリプトとして残せる |
チャットにCSVをアップロードする
CSVはサポート対象のファイル形式に入っています。チャットでは1ファイル500MBまで、1回のチャットに20ファイルまで添付できます。Excel形式(XLSX)を渡したいときは、アカウントでコード実行とファイル作成を有効にしておく必要があります。
コード実行が有効なら、Claudeはデータ分析用のPythonスクリプトを作り、CSVを処理できます。グラフはPNGの画像として出力されます。
プロジェクトのファイル欄に置く場合は1ファイル30MBまでで、内容はテキスト抽出として扱われる点が、チャット添付との違いです。日次の広告データを毎回貼り替えるなら、チャット添付のほうが運用は軽くなります。
Claude for Excelで条件付き書式まで作る
Claude for Excelは、Excelのアドインです。Pro、Max、Team、Enterpriseのプランが対象で、並べ替え、フィルタ、ピボットテーブルの編集、条件付き書式の適用をそのまま依頼できます。疲労の疑いがある行を色付けしたいときは相性が良い選び方です。
使えない環境も決まっています。
- 2016・2019の永続ライセンス版とボリュームライセンス版のExcel
- iPadとAndroidのExcel
- マクロとVBA、データテーブルの操作
そして、見落としやすいのが外部ファイルの扱いです。Meta広告から書き出したCSVは、自分で作ったブックではなく外部から持ち込んだデータにあたります。ヘルプには、外部由来のファイルに仕込まれた指示でアドインが操作を誘導される危険が書かれており、信頼できるスプレッドシートだけで使うよう案内されています。実務では、広告マネージャから自分で書き出したCSVを、別の作業用ブックに貼り付けてから使うのが無難です。
また、既存データを上書きする前には確認が出ますが、広く編集させる前には元のブックのコピーを取っておくのが、ヘルプのベストプラクティスにも沿います。
手元で動く判定スクリプト
毎週同じ判定を回すなら、スクリプトにしてしまうほうが早く確実です。Claude Codeに「次の仕様でPythonスクリプトを書いて」と依頼すれば、次の形に近いものが得られます。標準ライブラリだけで動くので、追加のインストールは要りません。
# ads_daily.csv を置いたフォルダで実行
python3 fatigue.pyimport csv
from collections import defaultdict
BASE, RECENT = 7, 7 # 比べる日数
CTR_DROP, FREQ_RISE = 0.20, 0.30 # 目安(自社データに合わせて調整)
ads = defaultdict(list)
with open("ads_daily.csv", encoding="utf-8-sig") as f:
for r in csv.DictReader(f):
if int(r["impressions"]) >= 500: # 小さすぎる日は除外
ads[r["ad_name"]].append(r)
def total(rows, key):
return sum(int(r[key]) for r in rows)
for name, rows in ads.items():
rows.sort(key=lambda r: r["day"])
if len(rows) < BASE + RECENT:
print(name, "データ不足"); continue
b, c = rows[:BASE], rows[-RECENT:]
ctr = lambda x: total(x, "clicks") / total(x, "impressions")
freq = lambda x: total(x, "impressions") / total(x, "reach")
drop = 1 - ctr(c) / ctr(b)
rise = freq(c) / freq(b) - 1
flag = "疲労の疑い" if drop >= CTR_DROP and rise >= FREQ_RISE else "継続"
print(f"{name}: CTR {ctr(b)*100:.2f}%→{ctr(c)*100:.2f}% ({-drop*100:+.1f}%) "
f"freq {rise*100:+.1f}% → {flag}")列名の ad_name day reach impressions clicks は、手元のCSVの見出しに合わせて書き換えます。日本語見出しのままなら、その文字列を指定するだけです。
動作を確かめた結果(合成データ)
仕組みを確かめるため、3本の架空の広告を21日分つくって流しました。実在の広告データではなく、挙動の確認用です。
ad_A: CTR 1.41%→0.74% (-47.8%) freq +86.2% → 疲労の疑い
ad_B: CTR 1.37%→1.38% (+0.6%) freq +11.4% → 継続
ad_C: CTR 1.46%→1.49% (+1.8%) freq +71.7% → 継続注目は ad_C です。フリークエンシーは7割以上伸びていますが、CTRは落ちていません。フリークエンシー単独で見れば差し替え候補に見える広告が、同時成立のルールでは外れました。この区別が、わざわざ2指標を組み合わせる理由です。
差し替え時期の目安を出す
「疲労の疑い」に入った広告について、いつ差し替えるかも決める必要があります。判定が付いた時点で入れ替えるだけでなく、崩れ始めの日を特定すると、次のクリエイティブの制作リードタイムが見えます。
Claudeには次のように頼むと、日付付きの結果が返ります。
添付のCSVは広告単位の日次データです。次の手順で集計してください。
1. CTRは クリック数合計 ÷ インプレッション合計 で再計算する(日次CTRの平均は使わない)
2. 広告ごとに、配信開始から7日間を基準期間とする
3. 直近7日とのCTR低下率、フリークエンシー上昇率を出す
4. CTR低下20%以上かつフリークエンシー上昇30%以上を「疲労の疑い」とする
5. 疲労の疑いの広告だけ、7日移動平均のCTRが基準期間より10%下回った最初の日を示す
6. インプレッション500未満の日は除外し、除外した日数も報告する手順5の「最初に下回った日」を、差し替え準備に入る合図として使います。たとえば崩れ始めから判定成立まで何日かかったかを広告ごとに記録しておくと、次回は判定が付く前に動けます。しきい値の20%・30%・10%はいずれも例です。数回回して、自社の広告が実際に落ちるときの水準へ寄せてください。
疲労ではない低下を見分ける
CTRの低下が、必ずしもクリエイティブの劣化とは限りません。判定に引っかかった広告は、差し替える前に次の点を確かめます。
差し替える前の切り分け
- Q同じ期間に予算、入札、配信対象を変更しましたか?答えがいいえのとき答えがはい
変更日を境に数字が動いていれば、クリエイティブではなく設定が原因の可能性が高くなります。変更前後で分けて比べ直します。
- Q同じ広告セットの他の広告も、同じ日に同じ向きで落ちていますか?答えがいいえのとき答えがはい
全体が落ちているなら、季節や曜日、ターゲットの飽和が疑われます。広告単体の疲労とは別の対処になります。
疲労と判断して差し替え候補へ
自分の広告だけが落ちており、設定の変更もないなら、クリエイティブの疲労として扱います。
曜日の影響を避けるには、基準期間と直近期間を同じ日数かつ7の倍数にします。7日で揃えているのは、そのためです。
外部から書き出したCSVの扱い
Claude for ExcelやClaudeのチャットにCSVを渡すとき、列の中身が「ただのデータ」であることを前提にしています。広告名やコメント欄のようなテキスト列に第三者が入力できる経路があると、その文字列が指示として読まれるリスクがあります。分析に要らない自由記述の列は、渡す前に削除しておくと安全側に倒せます。
広告データを継続的に取り込むなら
CSVの書き出しを手で繰り返すのが負担なら、コネクタで広告データを直接聞く方法もあります。Google広告とMeta広告を横断して聞く方法はClaudeとWindsor.aiを連携する方法に、媒体横断のCPAやROASを揃える方法はClaudeとFunnelを連携する方法にまとめています。
疲労の判定とは逆向きに、他社の広告がどんな訴求で出ているかを調べたいときはClaudeで競合の広告クリエイティブを分析する手順が参考になります。大きなCSVをチャットに貼らず、Files APIとコード実行で集計する比較はFiles APIとcode executionでCSVを集計するで扱っています。
運用に乗せるときの要点
判定ルールは、基準期間と直近期間の比較、2指標の同時成立、少数インプレッションの除外、の3つで足ります。手元のCSVで一度回し、疲労の疑いに入った広告が実際に成果を落としていたかを見てから、しきい値を調整してください。
Claudeは集計とスクリプト作成を速くしますが、差し替えの判断そのものは広告の成果と予算を知る担当者のものです。出力された数字は、合計値の再計算で検算してから使います。