Mímisbrunnr知恵の泉

← マーケティングサイエンス 一覧

🎓 レベル:標準 | 重要度:B(標準)

📎 関連:第6章 セグメンテーション 目次 | 前提:RFM分析(リセンシー・フリークエンシー・マネタリー)クラスタリングによるセグメンテーション(k-means)

要点(BLUF)

1. 分けた後の二つの問い:ターゲティング(どれを)とペルソナ(どんな人を)

セグメンテーションはゴールではなく出発点です。RFM分析(リセンシー・フリークエンシー・マネタリー)クラスタリングによるセグメンテーション(k-means) で顧客を kk 個の層に分けたら、次に必ず二つの問いが来ます。

まずターゲティングです。素朴には「大きいセグメントを狙えばいい」「反応率が高い層を狙えばいい」と考えがちですが、どちらも単独では誤りです。人数が多くても1人あたりの儲けが薄ければ赤字になり得ますし、反応率が高くても1件の価値が小さく接触コストに負ければやはり損です。規模・反応率・価値・コストは別々に見ると判断を誤る——これらを1本に束ねた物差しが期待利益で、§2でその式を立てます。狙うべきは「期待利益が大きいセグメント」、より正確には「期待利益が正のセグメント」です。

次にペルソナです。ターゲティングが「どのセグメントか」を決めるのに対し、ペルソナは「そのセグメントは何者か」を肉付けします。555555 や「クラスタ0」という記号のままでは、現場のコピーライターやデザイナーは動けません。そこで、そのセグメントの平均的な特徴(平均RFM・典型的な買い方・推定されるニーズ)を持ち寄り、「最近も月1〜2回買う、新作に敏感な常連客」のような具体的な1人の人物像に翻訳します。これがペルソナで、その役割はチーム内の共通言語になることです。「このペルソナならどう感じるか」を全員が共有できれば、施策のトーンやチャネルの判断がぶれません。肝心なのは、ペルソナをデータに根ざして作ること——平均特徴という土台があるからこそ、空想ではなく「狙う層の代表」になります(§⚠️)。

flowchart LR
  SEG["セグメント(06-01 RFM / 06-02 クラスタリング)"] --> T["ターゲティング:どのセグメントを狙うか"]
  SEG --> P["ペルソナ:狙う層を1人の人物像へ翻訳"]
  T --> PI["期待利益 N×(r×v−c) が正のセグメントだけ"]
  P --> ACT["施策(打ち手):誰に・何を・どう伝えるか"]
  PI --> ACT

2. 期待利益で狙うセグメントを選ぶ(数式)

セグメント ss に施策(クーポン送付・DM・広告など)を打つ場面を考えます。そのセグメントには NsN_s 人いて、施策に反応する確率(反応率)が rsr_s、反応1件が生む価値が vsv_s、1人に接触するコストが csc_s とします。このとき期待利益 πs\pi_s は次式です。

πs=Ns(rsvscs)\pi_s = N_s\,\big(r_s\,v_s - c_s\big)

中身を読み解きます。1人に接触すると確率 rsr_s で価値 vsv_s を得る——期待値は rsvsr_s v_s。そこから接触コスト csc_s を引いた rsvscsr_s v_s - c_s1人あたりの期待利益です。これに人数 NsN_s を掛ければセグメント全体の期待利益になります。規模 NsN_s・反応率 rsr_s・価値 vsv_s・コスト csc_s の4つが、ここで初めて1本に束ねられるのがポイントです。どれか一つだけ大きくても πs\pi_s が大きいとは限りません。

狙うかどうかの判断は単純です。1人あたりの期待利益が正なら狙い、負なら狙わない

rsvs>cs    狙う,rsvscs    狙わないr_s\,v_s > c_s \;\Longrightarrow\; \text{狙う}, \qquad r_s\,v_s \le c_s \;\Longrightarrow\; \text{狙わない}

負のセグメントは、接触すればするほど損が積み上がるので、手を出さないことが最善です。ここから二つの戦略を比べます。全セグメントに一律で打つブランケットと、期待利益が正のセグメントだけ打つターゲティングです。

Πall=sNs(rsvscs),Πtarget=s:rsvs>csNs(rsvscs)\Pi_{\text{all}} = \sum_{s} N_s\,(r_s v_s - c_s), \qquad \Pi_{\text{target}} = \sum_{s:\, r_s v_s > c_s} N_s\,(r_s v_s - c_s)

両者の差を取ると、ターゲティングが除外した(負の)セグメントの利益だけが残ります。

ΠtargetΠall= ⁣ ⁣s:rsvscs ⁣ ⁣Ns(rsvscs)    0\Pi_{\text{target}} - \Pi_{\text{all}} = -\!\!\sum_{s:\, r_s v_s \le c_s}\!\! N_s\,(r_s v_s - c_s) \;\ge\; 0

右辺は負のセグメントの赤字を符号反転した正の量なので、つねに 00 以上。つまりターゲティングはブランケットを弱支配する(負のセグメントが一つでもあれば厳密に勝ち、無ければ引き分け)。「全員に配る」が最適になるのは、すべてのセグメントが黒字のときだけです。1つでも赤字セグメントがあれば、そこを外すだけで総利益は必ず増えます。

採算の物差しとしては、接触コストあたりの利益率=ROI も併用します。

ROIs=Ns(rsvscs)Nscs=rsvscscs=rsvscs1\text{ROI}_s = \frac{N_s(r_s v_s - c_s)}{N_s\,c_s} = \frac{r_s v_s - c_s}{c_s} = \frac{r_s v_s}{c_s} - 1

ROI は人数 NsN_s に依存しない1人あたりの効率で、ROIs>0\text{ROI}_s>0rsvs>csr_s v_s > c_s と同値——狙う/狙わないの境界と一致します。総額(期待利益 πs\pi_s)で全体インパクトを、率(ROI)で効率を見るのが定石です。

3. ターゲティングとペルソナをコードで(コード)

pandas で4セグメントの表を作り、期待利益・1人あたり期待利益・ROI を計算して期待利益で降順ランキングします。次に**「期待利益が正のセグメントだけ狙う」ターゲティング全員一律(ブランケット)の総利益を比べ、最後に上位セグメント(優良客)のペルソナ・サマリー**を表で示します。数式との対応:seg["期待利益"]πs=Ns(rsvscs)\pi_s=N_s(r_s v_s-c_s)seg["1人利益"]rsvscsr_s v_s-c_sseg["ROI"]ROIs\text{ROI}_s です。

import numpy as np
import pandas as pd

# === セグメント表:人数N・反応率r・1件あたり価値v(v は LTV で見積もる)===
# 接触コスト c は全セグメント共通(1件あたり 200円)。
c = 200
seg = pd.DataFrame({
    "セグメント": ["優良客", "離反予兆", "新規", "休眠"],
    "N":        [167, 110, 126, 203],     # 人数(06-01 のセグメント規模)
    "反応率r":  [0.30, 0.15, 0.20, 0.03],  # 施策に反応する確率
    "価値v":    [5000, 5000, 2000, 2000],  # 1件の反応が生む価値(円)
})

# === 期待利益=N×(r×v − c)。1人あたり期待利益・ROI も計算 ===
seg["1人利益"] = seg["反応率r"] * seg["価値v"] - c        # r×v − c
seg["期待利益"] = seg["N"] * seg["1人利益"]               # N×(r×v − c)
seg["ROI"]    = seg["1人利益"] / c                       # 接触コストあたりの利益率

# === 期待利益で降順ランキング ===
ranked = seg.sort_values("期待利益", ascending=False).reset_index(drop=True)
print("=== セグメント別の期待利益ランキング(接触コスト c=200円/件)===")
print(ranked.to_string(index=False, formatters={
    "N": "{:.0f}".format, "反応率r": "{:.2f}".format, "価値v": "{:,.0f}".format,
    "1人利益": "{:,.0f}".format, "期待利益": "{:,.0f}".format, "ROI": "{:.0%}".format}))

# === 全員一律(ブランケット)vs 期待利益が正のセグメントだけ狙うターゲティング ===
blanket = seg["期待利益"].sum()                       # 4セグメント全員に接触
mask    = seg["期待利益"] > 0
targeted = seg.loc[mask, "期待利益"].sum()             # 期待利益>0 のセグメントだけ接触
excluded = seg.loc[~mask, "セグメント"].tolist()       # 狙わない(負利益)セグメント
improve  = targeted - blanket

print("\n=== 全員一律 vs ターゲティング(期待利益が正のみ)===")
print(f"全員一律(4セグメント全員に接触)   :総期待利益 {blanket:,.0f}円")
print(f"ターゲティング(期待利益>0 のみ)    :総期待利益 {targeted:,.0f}円"
      f"(除外={'・'.join(excluded)})")
print(f"改善                                 :{improve:+,.0f}円"
      f"({'・'.join(excluded)}の赤字 {seg.loc[~mask,'期待利益'].sum():+,.0f}円 を回避)")

# === 上位セグメント(優良客)のペルソナ・サマリー:平均RFM像・ニーズ・打ち手 ===
# 平均RFMは 06-01 の優良客の値(R=107日・F=21回・M=124,680円)を起点にする。
top = ranked.iloc[0]["セグメント"]
persona = pd.Series({
    "セグメント":     top,
    "平均RFM像":      "R=107日・F=21回・M=124,680円(最近も高頻度・高額)",
    "反応率":         f"{seg.loc[seg['セグメント']==top,'反応率r'].iat[0]:.0%}(4セグメント中で最高)",
    "1人あたり期待利益": f"{seg.loc[seg['セグメント']==top,'1人利益'].iat[0]:,.0f}円",
    "ふるまい":       "月に1〜2回ペースで購入する常連(F=21回/年)",
    "ニーズ":         "特別扱い・新作の先行アクセス・上位グレード",
    "打ち手":         "ロイヤルティ特典・限定先行案内・アップセル",
})
print(f"\n=== ペルソナ・サマリー:{top}(最優先ターゲット)===")
print(persona.to_string())

出力:

=== セグメント別の期待利益ランキング(接触コスト c=200円/件)===
セグメント   N 反応率r   価値v  1人利益    期待利益  ROI
  優良客 167 0.30 5,000 1,300 217,100 650%
 離反予兆 110 0.15 5,000   550  60,500 275%
   新規 126 0.20 2,000   200  25,200 100%
   休眠 203 0.03 2,000  -140 -28,420 -70%

=== 全員一律 vs ターゲティング(期待利益が正のみ)===
全員一律(4セグメント全員に接触)   :総期待利益 274,380円
ターゲティング(期待利益>0 のみ)    :総期待利益 302,800円(除外=休眠)
改善                                 :+28,420円(休眠の赤字 -28,420円 を回避)

=== ペルソナ・サマリー:優良客(最優先ターゲット)===
セグメント                                       優良客
平均RFM像       R=107日・F=21回・M=124,680円(最近も高頻度・高額)
反応率                             30%(4セグメント中で最高)
1人あたり期待利益                                1,300円
ふるまい                  月に1〜2回ペースで購入する常連(F=21回/年)
ニーズ                       特別扱い・新作の先行アクセス・上位グレード
打ち手                       ロイヤルティ特典・限定先行案内・アップセル

出力の意味

ランキングの読み方。期待利益で降順に並ぶと、優良客 217,100217{,}100 円 → 離反予兆 60,50060{,}500 円 → 新規 25,20025{,}200 円 → 休眠 28,420-28{,}420。注目は、人数では休眠が 203203 人で最多なのに、期待利益では最下位(しかも赤字)という逆転です。休眠は反応率 r=0.03r{=}0.03・価値 v=2000v{=}2000 円と低く、1人あたり期待利益は 0.03×2000200=1400.03\times2000-200=-140 円。200200 円かけて接触しても期待で 6060 円しか戻らず、11 人ごとに 140140 円の損が出る——人数が多いぶん赤字も 203×(140)=28,420203\times(-140)=-28{,}420 円と大きく膨らみます。「規模が大きい=狙うべき」がいかに危ういかが、この1行に出ています。逆に離反予兆は人数こそ 110110 人と少なめでも、v=5000v{=}5000 円と価値が高く、期待利益 60,50060{,}500 円・ROI 275%275\%新規より上位規模ではなく期待利益で並べ替えると、狙う順番が変わるのです。

ターゲティングがブランケットに勝つ。全員一律に打つと総期待利益は 274,380274{,}380 円。ところが期待利益が正の3セグメント(優良客・離反予兆・新規)だけに絞ると 302,800302{,}800 円で、+28,420+28{,}420 円の改善です。この改善幅は休眠の赤字 28,420-28{,}420 円を回避した分にちょうど等しい——§2で導いた「差=除外した負セグメントの赤字の符号反転」が、数字でそのまま確認できます。やったことは「赤字の休眠に打たない」だけ。何も新しい施策を足さず、狙わない判断だけで総利益が増えるのが、ターゲティングの本質です。もし全セグメントが黒字なら差は 00 で、そのときは全員に打つのが正解になります。

ペルソナ・サマリーの役割。最後の表は、ランキング1位の優良客を1人の人物像へ翻訳したものです。土台は数字——平均RFM像(R=107R{=}107 日・F=21F{=}21 回・M=124,680M{=}124{,}680 円、RFM分析(リセンシー・フリークエンシー・マネタリー) の優良客の値)と反応率 30%30\%、1人あたり期待利益 1,3001{,}300 円。そこに「月に1〜2回買う常連」というふるまいF=21F{=}21 回/年から逆算)、推定されるニーズ、対応する打ち手を添えると、「最近も高頻度に買う、新作に敏感な常連客」という顔の見える1人になります。これがペルソナです。注意したいのは、ニーズや打ち手は平均特徴からの解釈であり、実務では定性調査(インタビュー等)で裏取りして肉付けすること。それでも出発点は必ずデータ——空想で年齢や趣味を盛るのではなく、観測された平均像に根を張らせるのが、使えるペルソナの条件です。

セグメント別の期待利益を1枚にまとめ、**正のセグメント(狙う)と負のセグメント(外す)**を色で分けます(このブロックはセグメント表を内部で再構築し、上のランキングと同じ値を描きます)。

import matplotlib.pyplot as plt
import japanize_matplotlib
import pandas as pd

# セグメント表を再構築し、セグメント別の期待利益を正負で色分けした棒グラフにする。
c = 200
seg = pd.DataFrame({
    "セグメント": ["優良客", "離反予兆", "新規", "休眠"],
    "N":        [167, 110, 126, 203],
    "反応率r":  [0.30, 0.15, 0.20, 0.03],
    "価値v":    [5000, 5000, 2000, 2000],
})
seg["期待利益"] = seg["N"] * (seg["反応率r"] * seg["価値v"] - c)
seg = seg.sort_values("期待利益", ascending=False).reset_index(drop=True)

fig, ax = plt.subplots(figsize=(8.2, 4.6))
colors = ["C2" if p > 0 else "C3" for p in seg["期待利益"]]   # 正=緑(狙う), 負=赤(外す)
bars = ax.bar(seg["セグメント"], seg["期待利益"], color=colors)
for b, p in zip(bars, seg["期待利益"]):
    off = 6000 if p > 0 else -6000
    ax.text(b.get_x() + b.get_width() / 2, p + off, f"{p:,.0f}",
            ha="center", va="bottom" if p > 0 else "top", fontsize=10)
ax.axhline(0, color="black", lw=1)
ax.set_ylabel("施策の期待利益(円)")
ax.set_title("セグメント別の期待利益:正のセグメントだけ狙う(休眠は負=外す)")
ax.grid(alpha=0.3, axis="y")
fig.tight_layout()
plt.show()

棒グラフは期待利益の降順で、緑が黒字セグメント(優良客・離反予兆・新規=狙う)、赤が赤字セグメント(休眠=外す)。ゼロ線が「狙う/外す」の境界です。優良客の棒が突出して高く、休眠だけがゼロ線の下に沈んでいるのが一目で分かります。ターゲティングとは要するに、この赤い棒を施策対象から取り除く操作——図の上で言えば「ゼロ線より上の棒だけ残す」ことに他なりません。人数の多さ(休眠 203203 人)に引きずられず、棒の高さ(期待利益)で判断するのが要点です。

⚠️ よくある誤解

関連ノート