Claude Media
ClaudeでRFM分析する手順 — 顧客リストを施策別に切る

ClaudeでRFM分析する手順 — 顧客リストを施策別に切る

購入日・回数・金額のCSVをClaudeに渡してRFMスコアを付け、優良・休眠・離反などの区分ごとに打ち手を考える手順です。氏名や連絡先を渡さずIDだけにする下準備も扱います。

RFM分析は「いつ・何回・いくら」で顧客を分ける方法

RFM分析とは、顧客を最終購入日からの経過(Recency)、購入回数(Frequency)、購入金額の合計(Monetary)の3つで採点し、点数の組み合わせでグループに分ける手法です。ECや会員制サービスのCRMでは定番で、「全員に同じクーポンを送る」状態から抜け出すときの最初の一歩になります。

必要な材料は注文履歴のCSVだけです。顧客ID、注文日、金額の3列があれば成り立ちます。ClaudeにCSVを渡すと、Claudeがサンドボックス(隔離された実行環境)でPythonを書いて動かし、スコア付けから区分ごとの件数・平均金額の集計まで返します。計算の手間は消えるので、人が考える時間は「どの区分に何をするか」に回せます。

この記事では、CSVの下準備、Claudeへの頼み方、区分の切り方、区分ごとの打ち手、計算結果の検証までを順に書きます。CSV分析の基本操作はClaude CSV分析の使い方にあり、ここでは顧客リスト固有の論点に絞ります。

渡す前に決めておくこと — 列を絞り、氏名と連絡先を外す

RFMに要るのは行動の記録であって、誰かを特定する情報ではありません。氏名、メールアドレス、電話番号、住所は、分析のために渡す必要がありません。顧客IDに置き換えたCSVを作ってから添付します。

公式のサポート記事は、外部のファイルやWebサイトに仕込まれた指示でClaudeがだまされ、会話の文脈にある情報を外部へ送らされる恐れがあると説明しています。自社システムから書き出したCSVなら通常は心配が小さいものの、「渡す列を最小にする」は、その種のリスクを小さくする基本動作です。

下準備

CSVを渡す前の下準備

  1. 1

    注文単位のデータを書き出す

    1行が1注文になる形で、注文ID・顧客ID・注文日・金額を出します。顧客ごとに集計済みの表より、注文単位のほうが基準日の変更や返品の除外に対応しやすくなります。

  2. 2

    氏名・連絡先の列を落とす

    顧客IDだけを残します。IDと氏名の対応表は手元に置いたままにし、Claudeには渡しません。

  3. 3

    返品・キャンセルの扱いを決める

    返品やキャンセルの行が混ざっていると、回数と金額がふくらみます。除外する条件を決めて、書き出し側で落とすか、列を足しておきます。

  4. 4

    金額の定義を揃える

    税込か税抜か、送料を含むかを1つに揃えます。途中で混ざると、金額の分位が崩れます。

IDだけにしても、購入履歴は元の名簿と突き合わせれば個人に結びつきます。社内の個人情報の取り扱いルールがある場合は、CSVを外部のサービスに渡してよいかを先に確かめます。

ファイルサイズの上限は30MBを目安にする

アップロードの上限は、公式の記事によって数字が異なります。ファイルのアップロード記事はチャット添付を1ファイル500MBまで、プロジェクトのファイルを1ファイル30MBまでとしています。一方、コード実行とファイル作成の記事は、アップロードもダウンロードも1ファイル30MBまでと書いています。CSVをコード実行で分析する今回の使い方では、30MBを基準に考えるのが安全です。

顧客が数万件、注文が数十万行ほどのCSVなら、日付・ID・金額の3列に絞れば数十MBを超えることは少なくなります。超える場合は、対象期間を直近2年などに絞って分けて渡します。

動かないときは機能の設定を見る

CSVの集計は「コード実行とファイル作成」の機能の上で動きます。Free・Pro・Maxは既定でオンで、設定画面の「Capabilities」から切り替えられます。TeamとEnterpriseは、組織の管理者が機能ごと止めていることがあります。XLSXで渡す場合は、この機能をオンにしないとアップロードできません。CSVなら、その制約はありません。

Claudeへの頼み方 — 段階を分けて進める

最初から「RFM分析をして」と丸投げすると、基準日やスコアの切り方をClaudeが勝手に決めます。結果の再現ができなくなるので、定義を自分で決めて伝えます。

流れ

RFM分析を頼む流れ

  1. 1

    読み込み結果を先に報告させる

    行数、顧客数、期間、欠損の有無を答えさせます。想定と食い違えば、この時点で気づけます。

  2. 2

    基準日を指定する

    「分析日」ではなく、2026-09-30のように日付を固定します。後日同じ分析を回しても、比較の軸がずれません。

  3. 3

    スコアの付け方を指定する

    R・F・Mそれぞれを5段階に分ける方法(分位)と、Rだけは新しいほど高得点にする向きを決めます。

  4. 4

    区分の条件を渡す

    優良、休眠などの定義を表で示し、顧客を1つの区分に必ず割り当てさせます。

  5. 5

    区分ごとの件数と平均を出させる

    区分ごとの顧客数、1人あたり購入回数、平均の合計金額を表にします。

最初の依頼文は、たとえば次のように書きます。

プロンプト例(読み込みの確認とスコア付け)
添付の orders.csv は注文単位のデータです。
列は order_id, customer_id, order_date, amount です。
 
1. まず行数・顧客数・期間・欠損のある列を報告してください。
2. 基準日を 2026-09-30 とし、顧客ごとに次を計算してください。
   - Recency: 最終注文日から基準日までの日数
   - Frequency: 注文回数
   - Monetary: amount の合計
3. R・F・M を 5 分位で 1〜5 点に変換してください。
   Recency は日数が小さいほど 5 点にします。
4. 同じ値が多くて分位が割れない場合は、その旨を報告してください。

4番の指示は保険です。購入回数は「1回」の顧客が多く、同じ値が並ぶため、分位で5段階に割ると境界が偏ります。Claudeに黙って処理させず、割れたかどうかを答えさせておくと、後で点数の意味を説明できます。

区分の条件は表で渡す

スコアが付いたら、区分の条件を渡します。ここは自社の商材に合わせて変える部分で、下の条件は考え方の一例です。

区分条件(R・Fは1〜5点)当てはまる顧客の姿
優良条件(R・Fは1〜5点)Rが4以上、かつFが4以上当てはまる顧客の姿最近も買っていて、よく買う
休眠(元優良)条件(R・Fは1〜5点)Rが2以下、かつFが3以上当てはまる顧客の姿かつてよく買ったが、最近は来ていない
新規条件(R・Fは1〜5点)Rが4以上、かつFが2以下当てはまる顧客の姿最近初めて、または数回だけ買った
離反条件(R・Fは1〜5点)Rが2以下(上の休眠に当たらないもの)当てはまる顧客の姿回数が少なく、しばらく買っていない
一般条件(R・Fは1〜5点)上のどれにも当たらない当てはまる顧客の姿中間層

条件は上から順に当てはめ、最初に合ったものを採用する、と頼み方に書き添えます。順序を指定しないと、1人が複数の区分に重なって件数の合計が顧客数と合わなくなります。

プロンプト例(区分の割り当て)
スコアから、次の順で顧客を1つの区分に割り当ててください。
上から順に当てはめ、最初に合った区分を採用します。
 
1. 優良: R>=4 かつ F>=4
2. 休眠(元優良): R<=2 かつ F>=3
3. 新規: R>=4 かつ F<=2
4. 離反: R<=2
5. 一般: 上のいずれでもない
 
区分ごとに、顧客数・平均注文回数・平均合計金額を表にして、
区分の顧客数の合計が全顧客数と一致することを確認してください。

同じ処理を手元で動かした結果

Claudeが裏で何をしているかは、同じ処理を自分でも書いてみると分かります。乱数で作った架空の注文データ(200人・579注文)に、標準ライブラリだけのPythonスクリプトを当てた例です。実在の顧客データではなく、集計の流れを見せるための実行結果です。

rfm.py(標準ライブラリのみ)
import csv, datetime
from collections import defaultdict
 
asof = datetime.date(2026, 9, 30)
c = defaultdict(lambda: {"last": None, "f": 0, "m": 0})
for r in csv.DictReader(open("orders.csv")):
    d = datetime.date.fromisoformat(r["order_date"])
    x = c[r["customer_id"]]
    x["last"] = max(x["last"], d) if x["last"] else d
    x["f"] += 1
    x["m"] += int(r["amount"])
 
def score(vals, rev=False):
    s = sorted(vals)
    q = [s[int(len(s) * p)] for p in (.2, .4, .6, .8)]
    def f(v):
        n = 1 + sum(v > t for t in q)
        return 6 - n if rev else n
    return f
 
sr = score([(asof - x["last"]).days for x in c.values()], True)
sf = score([x["f"] for x in c.values()])
seg = defaultdict(int)
for x in c.values():
    r = sr((asof - x["last"]).days)
    f = sf(x["f"])
    if r >= 4 and f >= 4: g = "優良"
    elif r <= 2 and f >= 3: g = "休眠(元優良)"
    elif r >= 4 and f <= 2: g = "新規"
    elif r <= 2: g = "離反"
    else: g = "一般"
    seg[g] += 1
 
print(len(c), "customers")
for g, n in sorted(seg.items(), key=lambda t: -t[1]):
    print(g, n)
python3 rfm.py
実行結果(Python 3.12.2・架空データ)
200 customers
新規 51
離反 48
一般 40
休眠(元優良) 31
優良 30

区分の合計は51+48+40+31+30で200人となり、顧客数と一致します。Claudeに頼んだ結果でも、同じ足し算で検算できます。

このスクリプトは、簡略化のためにMをスコア化せず、区分の条件にも使っていません。金額は区分ごとの平均を出す側で使う想定です。優良の中でも金額の大きい層を分けたいときは、Mのスコアを足して条件に加えます。

区分ごとの打ち手 — Claudeに案を出させる

件数が出たら、次は区分ごとの施策です。ここはClaudeの得意な部分で、区分の定義と自社の商材を渡せば、打ち手の候補をまとめて出せます。ただし、案をそのまま採用するのではなく、費用対効果の見積もりと、配信できる人数の確認は人が行います。

区分打ち手の方向見る指標
優良打ち手の方向先行案内、会員限定の特典。値引きは控えめにする見る指標継続購入率、客単価
休眠(元優良)打ち手の方向久しぶりの再訪を促す個別メッセージ、前回購入に関連した提案見る指標再購入率、休眠からの復帰数
新規打ち手の方向2回目購入につなげる使い方の案内、初回のフォロー見る指標2回目購入率
離反打ち手の方向低コストの一斉配信にとどめる。反応がなければ対象から外す見る指標開封・反応率
一般打ち手の方向購入頻度を上げる定期的な提案見る指標購入回数の推移

ここでの打ち手は発想の出発点で、効果を保証するものではありません。どの区分に予算を寄せるかは、区分の人数と平均金額を掛け合わせて決めます。施策ごとの予算配分の考え方はキャンペーン成果と予算の再配分にあります。

プロンプト例(区分ごとの施策案)
先ほどの区分ごとの集計表をもとに、各区分への施策案を
2つずつ出してください。
 
前提:
- 商材: 月額980円の学習アプリ(定額課金)
- 配信手段: メールとアプリ内通知
- 値引きは原則使わない
 
各案について、狙い・対象人数・見る指標を1行で書いてください。

前提に商材と制約を書くほど、施策案が具体的になります。値引きを使わない、配信手段が限られるといった制約は、書かないと案に反映されません。

計算結果を検証する

数字が出ても、そのまま会議に出さないほうが安全です。Claudeが書いたコードの前提が、こちらの意図とずれている可能性は残ります。次の3点を確かめます。

  • 区分の顧客数の合計が、読み込んだ顧客数と一致するか
  • 顧客1人を選び、その人の注文を目で追って、R・F・Mが手計算と合うか
  • 基準日が指定どおりか(コードを表示させて、日付の指定箇所を見る)
プロンプト例(1人を取り出して検算)
customer_id が C0001 の顧客について、次を表示してください。
- この顧客の全注文(日付と金額)
- 計算した R・F・M の値と、各スコア
- 割り当てられた区分とその理由

1人分でも手計算と合えば、全体の処理も同じ流れで動いていると判断しやすくなります。合わなければ、基準日の取り違えや返品行の混入が疑わしい点です。

つまずきやすい点

つまずき

RFMでよくある落とし穴

  • 購入回数が1回の顧客が多い

    Fの分位が割れず、1点と2点の境が偏ります。回数を「1回・2回・3〜4回・5回以上」のように固定の区切りで点数化するほうが、説明しやすくなります。

  • サブスクと単発購入が混在する

    定期課金は毎月の請求が回数に積み上がります。商品の種類ごとにRFMを分けるか、回数を契約単位で数えます。

  • 法人と個人が同じ表にある

    法人の大口注文が金額の分位を押し上げます。顧客の種別を列に持たせて、別々に分析します。

  • 基準日を毎回変える

    月ごとに結果を比べるつもりなら、基準日を月末に固定する運用にします。同じ顧客が区分を移動した推移が追えます。

コード実行とファイル作成は、通常のチャットより使用量を多く消費します。大きなCSVで何度も作り直すと、プランの上限に早く近づくので、定義を固めてから回します。

定義を残して、毎月同じ分析を回す

区分の条件、基準日の決め方、金額の定義を一度決めたら、文書にして残します。プロジェクトにファイルとして置くと、会話ごとに貼り直さずにClaudeが参照できます。プロジェクトのファイルはコード実行の環境からも参照されます。

毎月の更新では、新しい注文データだけを差し替え、定義のファイルは固定します。区分の人数の推移が、施策の効果を見る目安になります。

配信まで同じ流れで進めたい場合は、メール配信ツールとの連携が選択肢です。Brevoとの連携ではキャンペーン分析とセグメントの扱いを、Mixpanelとの連携では行動データの横断分析を、Chargebeeとの連携では課金データの引き方を扱っています。RFMで切った区分の一覧を、これらのツールの配信リストに反映する運用の入口になります。

まとめ

RFM分析で手間がかかるのは計算ではなく、下準備と定義の決定です。氏名・連絡先を外したIDだけのCSVを用意し、基準日・スコアの切り方・区分の条件をこちらで固定して伝えれば、Claudeは再現できる形で集計を返します。数字は顧客数の合計と1人分の手計算で検算してから、施策の議論に使います。

この記事を共有:XはてブLinkedIn