# RFM 顧客セグメンテーション

購買行動に基づいて顧客ベースを自動的にセグメント化し、すべてのキャンペーンを適切なタイミングで適切なオーディエンスに届けます。

## 概要とユースケース

Treasure AIの機械学習プラットフォーム（AI Signal）のRFM AI Signalsは、取引履歴から各顧客を3つのディメンションでスコアリングして、顧客ベースを自動的にセグメント化します。Recency（最終購入からの日数）、Frequency（購入回数）、Monetary value（合計支出額）の3つでスコアリングし、それらのスコアをChampions、Loyal Customers、Lost Customersなど10の業界標準セグメントにマッピングします。セグメントはMaster Segmentに直接連携され、パーソナライゼーション、抑制、ウィンバックキャンペーン、ロイヤルティプログラムに活用できます。マーケティングチームやCRMチームに対して、SQLを書いたりカスタムモデルを構築したりすることなく、離反しつつある顧客や再購入の可能性が高い顧客を素早く把握できるビューを提供します。

一般的なユースケース：

* 競合に奪われる前に、トップのChampions顧客をVIPオファーで特定し、報酬を提供する
* 活動が停滞した「Cannot Lose Them」顧客に対して、自動ウィンバックキャンペーンをトリガーする
* 高コストの有料メディアから優先度の低い「Lost Customers」を除外し、無駄な支出を削減する
* メール配信頻度を調整する — Championsには毎週、Hibernatingセグメントには主要キャンペーンのみ
* RFMスコアをダウンストリームのCLTVおよびチャーン傾向モデルの入力特徴量として活用する


最も効果的な対象者：データサイエンスチームを常駐させることなく、迅速で実用的な顧客セグメントを必要とするマーケティングアナリスト、CRMマネージャー、ライフサイクルマーケティングチーム。

## モデル設定

### トレーニング入力

RFM AI Signalsは、事前集計された顧客レベルのテーブルを受け入れます。各行は1人の顧客を表し、すべての取引にわたって集計済みです。

| **フィールド**  | **型**  | **必須**  | **説明**  |
|  --- | --- | --- | --- |
| `user` | VARCHAR | はい | 一意の顧客識別子。カラム名は `user_column` パラメータでカスタマイズできます。 |
| `recency` | INTEGER | はい | 顧客の最新の取引からの日数。 |
| `frequency` | INTEGER | はい | 分析期間内の取引の総数。 |
| `monetary_value` | DOUBLE | はい | すべての取引にわたる合計支出額。 |


データ品質の要件
RFM AI Signalsは欠損値の処理を自動的に行いません。モデルを実行する前に、`recency`、`frequency`、`monetary_value` のnull値を削除または補完する前処理を行ってください。負の値やゼロの値は不正確なスコアを生成するため、上流で処理する必要があります。

### トレーニング出力

モデルは各顧客レコードに対して、以下のカラムを出力テーブルに書き込みます。

| **フィールド**  | **型**  | **説明**  |
|  --- | --- | --- |
| `user` | STRING | 入力から引き継がれた顧客識別子。 |
| `recency` | LONG | 最新の取引からの日数。 |
| `frequency` | LONG | 取引の総数。 |
| `monetary_value` | DOUBLE | 合計支出額。 |
| `r_quartile` | LONG | Recencyランク（1〜4）。4 = 最も最近の四分位。 |
| `f_quartile` | LONG | Frequencyランク（1〜4）。4 = 最も頻繁な四分位。 |
| `m_quartile` | LONG | Monetaryランク（1〜4）。4 = 最も高い支出額の四分位。 |
| `rfm_quartile` | STRING | 連結された四分位ラベル（例：`R3F1M4`）。`audience_name` が設定されている場合、Master Segmentの属性カラムとしても追加されます。 |
| `rfm_score` | DOUBLE | 3つの四分位スコアの平均：`(r + f + m) / 3`。1.0〜4.0の範囲。 |
| `rfm_segment` | STRING | 名前付きビジネスセグメント（例：`Champions`、`Hibernating`）。以下のセグメント定義を参照してください。 |


### 出力例

モデル実行後のRFM予測テーブルのサンプル：

| **user**  | **recency**  | **frequency**  | **monetary_value**  | **r_quartile**  | **f_quartile**  | **m_quartile**  | **rfm_quartile**  | **rfm_score**  | **rfm_segment**  |
|  --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `3105285968` | 10 | 8 | 4115.00 | 4 | 4 | 4 | R4F4M4 | 4.0000 | Champions |
| `1850985734` | 20 | 5 | 1456.00 | 2 | 3 | 2 | R2F3M2 | 2.3333 | Need attention |
| `274382808` | 95 | 2 | 200.12 | 2 | 1 | 1 | R2F1M1 | 1.3333 | Hibernating |
| `358273144` | 310 | 6 | 2770.00 | 1 | 2 | 3 | R1F2M3 | 2.0000 | High Value Sleeping |
| `45110` | 400 | 1 | 133.00 | 1 | 1 | 1 | R1F1M1 | 1.0000 | Lost customers |


出力の読み方：`rfm_score` は3つの四分位値の算術平均です。スコア4.0はChampion、1.0はLost customerを表します。`rfm_quartile` 文字列は各ディメンションを明示的にエンコードします — `R2F1M1` はRecencyが中程度、Frequencyが低い、支出額が低いことを意味します。`audience_name` が設定されている場合、`rfm_quartile` はMaster Segmentの属性カラムとしても書き込まれ、CDPセグメントビルダーで直接フィルタリングが可能になります。

### パラメータ

| **パラメータ**  | **型**  | **デフォルト**  | **必須**  | **説明**  |
|  --- | --- | --- | --- | --- |
| `input_table` | string | — | はい | `dbname.table_name` 形式のソーステーブル（例：`ml_dataset.td_rfm`）。事前集計されたRFMカラムを含む必要があります。 |
| `output_table` | string | — | はい | `dbname.table_name` 形式の出力先テーブル（例：`ml_output.rfm`）。スコアリング結果がここに書き込まれます。 |
| `output_mode` | string | `append` | いいえ | 出力テーブルの書き込みモード。`append` で複数回の実行にわたって行を追加、または `replace` で最新のスコアのみで上書きします。 |
| `user_column` | string | `user` | いいえ | 入力テーブルで顧客識別子を保持するカラム名。テーブルが異なる名前を使用している場合に変更してください（例：`customer_id`）。 |
| `use_sql` | boolean | `false` | いいえ | `true` の場合、RFM計算がPythonではなくTrino SQLクエリとして実行されます。大規模データセットに強く推奨 — スケールに応じて大幅に高速化されます。 |
| `use_hive` | boolean | `false` | いいえ | `true` の場合（`use_sql: true` との組み合わせで）、計算がTrinoではなくHive経由で実行されます。環境がHive互換性を必要とする場合にのみ使用してください。 |
| `mv_threshold` | float | — | いいえ | `monetary_value` がこの閾値を下回る顧客は、実際の相対ランクに関係なくmonetary四分位1（`m_quartile = 1`）に割り当てられます。低額または実質ゼロの取引をフィルタリングするのに有用です。例：`0.05`。 |


**チューニングのヒント：**

* **`use_sql: true`** — 1,000万行を超える行動データには有効にしてください。Pythonのメモリオーバーヘッドを解消し、実行時間を大幅に短縮します。ベンチマークについてはスケーラビリティセクションを参照してください。
* **`mv_threshold`** — 取引データにフリーティアのサインアップや四分位の境界を歪める可能性のある少額購入が含まれる場合に設定してください。
* **`output_mode: append`** — 各実行がスコアリングされたスナップショットを追加するため、スケジュール実行に安全です。最新の状態のテーブルのみが必要な場合は `replace` を使用してください。


## ワークフローコード例

RFM AI SignalsはML Batch API経由で実行され、Treasure Workflowから呼び出されます。以下のワークフローは完全なコピー＆ペースト可能な例です。

```yaml
# rfm_signal_workflow.dig
# Treasure Workflow: RFM AI Signals (PrecisionML)
# RFMスコアリングジョブをML Batch APIに送信し、
# ダウンストリームステップに進む前に完了をポーリングします。

# ステップ1: RFMジョブをML Batch APIに送信
+run_rfm:
  http>: https://ml-batch-api.treasuredata.com/v1/runs/
  method: POST
  headers:
    - authorization: ${secret:td.apikey}
    - X-TD-ML-SESSION-ID: ${session_id}
    - X-TD-ML-ATTEMPT-ID: ${attempt_id}
  store_content: true
  content:
    input_table: your_database.aggregated_customers
    output_table: your_database.rfm_output
    solution_name: rfm
    solution_arguments:
      user_column: user
      use_sql: true
      # mv_threshold: 0.05   # 実質ゼロのmonetary valueを抑制するにはコメントを外してください

# ステップ2: APIレスポンスをログに記録（ポーリングに使用するジョブID）
+print_response:
  echo>: "Job submitted. Response: ${http.last_content}"

# ステップ3: ジョブが完了するまでポーリング
# APIはジョブ実行中にHTTP 408を返します — Treasure Workflow
# がHTTP 200を受信するまで自動的にリトライします。
+poll_status:
  http>: https://ml-batch-api.treasuredata.com/v1/runs/${JSON.parse(http.last_content)['id']}/status
  method: GET
  headers:
    - authorization: ${secret:td.apikey}

# ステップ4: 完了の確認
+finished:
  echo>: "RFM scoring complete. Results written to your_database.rfm_output"
```

**このワークフローの動作：** ワークフローはRFM設定をML Batch APIに送信し、レスポンスでジョブIDを受け取ります。その後、ステータスエンドポイントをリトライループでポーリングします — APIはジョブ実行中にHTTP 408を返し、Treasure WorkflowはHTTP 200を受信するまで自動的にリトライします。完了すると、スコアリングされた出力テーブルはダウンストリームのアクティベーションまたはオーディエンス作成に使用できます。

セキュリティ
TD APIキーは `td.apikey` という名前のWorkflowシークレットとして保存してください。ワークフロー定義にAPIキーをハードコードしたり、バージョン管理にコミットしたりしないでください。

## セグメント定義

RFM AI Signalsは四分位の組み合わせを10の業界標準セグメントにマッピングします。四分位値が高いほど、そのディメンションでのパフォーマンスが良いことを示します。

| **セグメント**  | **説明**  | **四分位パターン**  |
|  --- | --- | --- |
| Champions | 最近購入し、頻繁に購入し、最も多く支出している。最も価値の高い顧客。 | R4F4M4 |
| Loyal Customers | 継続的にアクティブで高価値。プロモーションに反応する。 | R3–4, F3–4, M3–4（Championsを除く） |
| Potential Loyalists | 最近の購入者で、複数回購入し、相応の金額を支出している。 | R3–4, F2–4, M2–4 |
| Promising | 最近の買い物客で、Recencyは高いがFrequencyまたは支出額がまだ低い。 | R3–4, F1–4, M1–2 |
| New Customers | 最近購入したが、1回のみ。 | R3–4, F1, M1 |
| Cannot Lose Them | 大口で頻繁な購入をしていたが、かなり前のこと。高価値のリエンゲージメント対象。 | R1–2, F3–4, M3–4 |
| Need Attention | 以前のPotential Loyalistsで、エンゲージメントが低下している。 | R2, F2–4, M2 |
| Hibernating | Recencyが低く、Frequencyが低く、支出額が低い。リエンゲージメントのROIは低い。 | R2, F1–4, M1–2 |
| High Value Sleeping | 過去のPotential Loyalistsで活動が停滞している。ターゲットを絞った再活性化の価値がある。 | R1, F2–4, M2–4 |
| Lost Customers | 3つのディメンションすべてで最低スコア。リエンゲージメントの優先度が最も低い。 | R1, F1–3, M1–2 |


## スケーラビリティ

RFM AI Signalsはエンタープライズ規模のデータセットを処理できるように設計されています。以下の表は、さまざまなデータセットサイズでの実測ランタイムを示しています。1,000万行を超える行動データには `use_sql: true` を有効にしてください。

| **行動データ行数**  | **顧客行数**  | **ランタイム**  | **タスクあたりのピークメモリ**  |
|  --- | --- | --- | --- |
| 100万 | 31万3千 | 約4分 | 4.4 GiB |
| 1,000万 | 313万 | 約12分 | 5.4 GiB |
| 1億 | 3,130万 | 約89分 | 37.9 GiB |
| 5億 | 1億5,600万 | 約445分 | 182.8 GiB |
| 8億（8並列タスク） | 2億5,000万 | 約96分 | 37.3 GiB |


非常に大規模なデータセットの場合、8タスクの並列処理（アカウントあたりの最大同時実行数）により、実行時間を大幅に短縮できます — 8億行のケースでは、並列実行により約445分から約96分に短縮されました。データセットが定常的に5億行の行動データを超える場合は、インフラストラクチャオプションについてTreasure AIアカウントチームにお問い合わせください。

## 制限事項と既知の問題

* **少なくとも12か月の取引履歴で最適に機能します。** 短い期間ではRecencyシグナルが圧縮され、新規顧客とリピート顧客の区別が困難になります。
* **四分位ランキングは相対的であり、絶対的ではありません。** 低活動期間の「Champion」は、高活動期間の「Loyal Customer」よりも支出額が少ない場合があります。セグメントラベルはモデル実行時のコンテキストで解釈してください。
* **サブスクリプションやSaaS製品向けには設計されていません。** Monetary Valueが顧客間で均一な場合（例：固定価格サブスクリプション）、Mディメンションの予測力が低下します。代わりに、エンゲージメントメトリクス（ログイン、機能使用状況）を事前集計入力として使用することを検討してください。
* **将来の行動を予測しません。** RFMは過去のパターンを記述します。将来を見据えたCLTV予測には、RFMスコアをダウンストリームの特徴量として確率モデル（BG/NBD、Gamma-Gamma）と組み合わせてください。
* **データの鮮度に敏感です。** 入力テーブルが最新に保たれていない場合、Recencyスコアがドリフトし、セグメントが古くなります。キャンペーンの頻度に合わせてワークフロー実行をスケジュールしてください — 動きの速い小売業では毎週、低頻度カテゴリでは毎月。
* **事前集計入力にはクリーンなデータが必要です。** 欠損値の処理は自動的に行われません。`recency`、`frequency`、`monetary_value` のnull値や負の値は不正確なスコアを生成するため、上流で処理する必要があります。


## 用語集

| **用語**  | **定義**  |
|  --- | --- |
| Recency | 顧客の最新の取引からの日数。値が低いほど、顧客がより最近に購入したことを意味します。 |
| Frequency | 分析期間内に顧客が行った取引の総数。 |
| Monetary Value | 分析期間内のすべての取引にわたる顧客の合計支出額。 |
| 四分位（Quartile） | 単一のディメンションですべての顧客をランク付けして作成される4つの等サイズグループの1つ。四分位4の顧客はそのディメンションの上位25%に属します。 |
| RFM Score | 顧客の3つの四分位ランクの平均：`(r + f + m) / 3`。1.0（最低）から4.0（最高）の範囲。 |
| RFM Segment | 顧客の四分位パターンの組み合わせに基づいて割り当てられる名前付きビジネスラベル（例：「Champions」、「Hibernating」）。 |
| `rfm_quartile` | 3つの四分位値すべてをエンコードする文字列ラベル（例：`R3F1M4`）。オーディエンス作成が有効な場合、Master Segmentの属性としても書き込まれます。 |
| Master Segment | モデルによってスコアリングされたすべての顧客を保持するTreasure AI CDPの構成要素。Child Segmentは `rfm_segment` でフィルタリングされたサブセットです。 |
| PrecisionML | RFM AI Signalsを支える本番MLインフラストラクチャ。スケーラビリティに最適化されており、以前のAutoMLベースの実装に代わるものです。 |
| `mv_threshold` | Monetary Valueの下限値。この金額を下回る支出の顧客は、すべての顧客間の相対ランクに関係なく、最低のmonetary四分位に割り当てられます。 |
| `use_sql` | RFM計算をPythonではなくTrino SQL経由でルーティングするパラメータ。大規模データセットのより高速な処理を可能にします。 |
| ウィンバックキャンペーン | 最近購入していない顧客のリエンゲージメントを目的としたターゲットキャンペーン — 通常、「Cannot Lose Them」または「High Value Sleeping」セグメントを対象とします。 |


## よくある質問

| **質問**  | **回答**  |
|  --- | --- |
| RFMモデルはどのくらいの頻度で再実行すべきですか？ | 顧客の一般的な購入頻度によって異なります。EコマースやリテールではRecencyスコアの変化を早期に検知するため、毎週のスケジュールが適切です。低頻度カテゴリ（旅行、自動車など）では、毎月の実行で十分です。Treasure Workflowコンソールで直接ワークフローをスケジュールできます。 |
| `use_sql: true` はいつ有効にすべきですか？ | 1,000万行を超える行動データを持つデータセットに対して有効にしてください。SQL実行はRFM計算をTrinoで直接実行し、Pythonのメモリ制限を回避して実行時間を大幅に短縮します。小規模なデータセットでは、デフォルトのPython実行で問題なく、設定変更は不要です。 |
| `mv_threshold` は何をするもので、いつ使用すべきですか？ | `mv_threshold` は最小monetary valueの下限値を設定します。この閾値を下回る支出の顧客は、他の顧客に対する相対ランクに関係なくmonetary四分位1に割り当てられます。取引データにフリーティアのサインアップ、実質ゼロの購入、またはセグメント割り当てを歪める可能性のあるプロモーションクレジットが含まれる場合に使用してください。例えば、`mv_threshold: 0.05` は$0.01の取引が四分位境界に影響するのを防ぎます。 |
| 顧客が1回しか購入しない場合、RFM AI Signalsを使用できますか？ | RFMはリピート購入データで最も効果的に機能します。ほとんどの顧客のFrequencyが1の場合、Fディメンションはほぼ均一になり、シグナルがほとんど加わりません。この場合、RecencyとMonetary Valueが重みの大部分を担います。サイト訪問やメール開封などの行動エンゲージメントデータを事前集計入力として追加してモデルを強化することを検討してください。 |
| RFMセグメントをキャンペーンツールでどのように活用しますか？ | モデル実行後、出力テーブルにはすべての顧客の `rfm_segment` カラムが含まれます。ワークフローで `audience_name` を設定すると、モデルはCDP内にMaster Segmentと `rfm_segment` 値ごとに1つのChild Segmentを自動的に作成します。これらのSegmentは標準的なCDPアクティベーションワークフローを通じて、ダウンストリームのアクティベーション先にプッシュできます。 |
| 顧客の大部分が「Lost Customers」として表示されるのはなぜですか？ | 非常に大きなLostセグメントは通常、次の2つのうちいずれかを意味します：入力テーブルが最近更新されていない（Recencyにより全員が非アクティブに見える）、またはビジネスが実際に高い一度きりの購入率を持っている。データの鮮度を確認するために、入力テーブルの最大recency値をチェックしてから、獲得品質を調査してください。 |