STEP 23:コホート分析

📊 STEP 23: コホート分析

顧客の行動パターンを時系列で追跡しよう

📋 このステップで学ぶこと

  • コホート分析とは何か
  • リテンション率の計算方法
  • コホート表の作成とヒートマップ可視化
  • コホート分析の解釈と活用
  • PythonとExcelでの実装

学習時間の目安:3時間

🔍 1. コホート分析とは

基本概念

📌 コホート(Cohort)とは

同じ時期に同じ体験をしたユーザーのグループ

例:
・2024年1月に登録したユーザー → 1月コホート
・2024年2月に登録したユーザー → 2月コホート
・2024年3月に登録したユーザー → 3月コホート

コホート分析の目的:
・各コホートの行動パターンを追跡
・時間経過による変化を観察
・コホート間の違いを比較
・施策の効果を測定

なぜコホート分析が重要か

💡 全体平均では見えないもの

問題:全体平均の罠

・全体のアクティブ率:40%
・「まあまあの数字だ」と思うかもしれないが…

コホート分析で見えること:

・古いユーザー(1年前登録):アクティブ率 60%
・新しいユーザー(先月登録):アクティブ率 20%
→ 新規ユーザーの離脱が深刻!全体平均では見えなかった

コホート分析の価値:
時間軸での変化を追跡
施策の効果を正確に測定
問題の発見が早くなる

リテンション率とは

📌 リテンション率(Retention Rate)

一定期間後も、サービスを継続利用している割合

計算式:
リテンション率 = (期間後の利用者数 / 初期の利用者数) × 100%

例:
・1月に100人が登録
・2月(1ヶ月後)に40人が利用 → リテンション率 40%
・3月(2ヶ月後)に25人が利用 → リテンション率 25%
・4月(3ヶ月後)に20人が利用 → リテンション率 20%

重要性:
・リテンション率が高い = 顧客が定着している
・リテンション率が低い = 離脱が多い → 改善が必要

コホートの種類

種類 定義方法 用途
時間ベース 登録月でグループ化 1月登録、2月登録… 最も一般的、リテンション分析
行動ベース 初回購入時期でグループ化 1月初購入、2月初購入… 購買行動の分析
属性ベース 流入元でグループ化 Google経由、SNS経由… チャネル評価
施策ベース キャンペーン参加でグループ化 キャンペーンA、B… 施策効果測定

📊 2. コホート表の作成

基本的なコホート表

📌 コホート表の構造

行:コホート(登録月)
列:経過期間(0ヶ月、1ヶ月、2ヶ月…)
値:リテンション率

登録月 ユーザー数 0ヶ月 1ヶ月 2ヶ月 3ヶ月
2024年1月 500人 100% 40% 25% 20%
2024年2月 600人 100% 50% 35%
2024年3月 700人 100% 55%
2024年4月 800人 100%
📝 読み方

・1月コホート:0ヶ月100% → 1ヶ月後40% → 2ヶ月後25% → 3ヶ月後20%
・2月コホート:0ヶ月100% → 1ヶ月後50% → 2ヶ月後35%
→ 2月、3月とリテンション率が改善している!

Pythonでの実装

# ============================================ # コホート分析の実装 # ============================================ # コホート分析とは? # → 同じ時期に獲得した顧客グループの行動を追跡 # → 例:1月に登録したユーザーが、2月、3月にどれだけ残るか import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # ============================================ # サンプルデータ作成 # ============================================ np.random.seed(42) # ユーザーデータを生成 n_users = 1000 signup_dates = pd.date_range(‘2024-01-01’, ‘2024-06-30′, freq=’D’) data = [] for user_id in range(1, n_users + 1): # ランダムに登録日を設定 signup_date = np.random.choice(signup_dates[:150]) # ランダムに利用日を生成 n_activities = np.random.poisson(5) # 平均5回の利用 for _ in range(n_activities): days_after = np.random.exponential(30) # 指数分布で利用間隔 activity_date = signup_date + pd.Timedelta(days=int(days_after)) if activity_date <= signup_dates[-1]: data.append({ 'user_id': user_id, 'signup_date': signup_date, 'activity_date': activity_date }) df = pd.DataFrame(data) print("【データ確認】") print(f"総レコード数: {len(df)}") print(f"ユニークユーザー数: {df['user_id'].nunique()}") print(df.head()) # ============================================ # 日付を月単位に変換 # ============================================ # .dt.to_period('M'): 日付を月単位の期間に変換 # '2024-03-15' → '2024-03' # # なぜ月単位に丸めるか? # → 日単位だと細かすぎて傾向が見えにくい # → 月単位で集計するのが一般的 df['signup_month'] = df['signup_date'].dt.to_period('M') df['activity_month'] = df['activity_date'].dt.to_period('M') # ============================================ # 経過月数を計算 # ============================================ # activity_month - signup_month で期間の差を計算 # .apply(lambda x: x.n)で数値(月数)に変換 # → 登録月と同じ月 = 0 # → 1ヶ月後 = 1、2ヶ月後 = 2... df['months_since_signup'] = (df['activity_month'] - df['signup_month']).apply(lambda x: x.n) # 0以上の経過月数のみ(登録前の活動を除外) df = df[df['months_since_signup'] >= 0] # ============================================ # コホート×経過月のユニークユーザー数を集計 # ============================================ # groupby(): グループ化して集計 # nunique(): ユニークな値の数をカウント # → 同じユーザーが複数回利用しても1人とカウント cohort_data = df.groupby([‘signup_month’, ‘months_since_signup’])[‘user_id’].nunique().reset_index() cohort_data.columns = [‘signup_month’, ‘months_since_signup’, ‘active_users’] # 各コホートの初期ユーザー数 cohort_sizes = df.groupby(‘signup_month’)[‘user_id’].nunique().reset_index() cohort_sizes.columns = [‘signup_month’, ‘cohort_size’] # ============================================ # リテンション率を計算 # ============================================ # リテンション率 = アクティブユーザー数 / コホートサイズ × 100 cohort_data = cohort_data.merge(cohort_sizes, on=’signup_month’) cohort_data[‘retention_rate’] = (cohort_data[‘active_users’] / cohort_data[‘cohort_size’] * 100).round(1) # ============================================ # ピボットテーブルに変換(見やすい形式に) # ============================================ # .pivot(): 行・列・値を指定して表を変形 # index: 行にする列(signup_month = コホート) # columns: 列にする列(months_since_signup = 経過月) # values: セルの値(retention_rate = リテンション率) retention_table = cohort_data.pivot( index=’signup_month’, columns=’months_since_signup’, values=’retention_rate’ ) print(“\n【コホート分析:リテンション率(%)】”) print(retention_table) print(“\n→ 行: 登録月(コホート)”) print(“→ 列: 登録からの経過月数”) print(“→ 値: その月にアクティブだったユーザーの割合”)
# 出力例 【データ確認】 総レコード数: 4523 ユニークユーザー数: 847 user_id signup_date activity_date 0 1 2024-03-15 2024-03-15 1 1 2024-03-15 2024-04-02 2 1 2024-03-15 2024-03-29 3 2 2024-02-28 2024-03-14 4 2 2024-02-28 2024-02-28 【コホート分析:リテンション率(%)】 months_since_signup 0 1 2 3 4 5 signup_month 2024-01 100.0 42.3 28.5 21.2 16.8 12.4 2024-02 100.0 48.7 32.1 24.5 18.9 NaN 2024-03 100.0 51.2 35.6 26.8 NaN NaN 2024-04 100.0 54.3 38.2 NaN NaN NaN 2024-05 100.0 56.1 NaN NaN NaN NaN

ヒートマップで可視化

# ヒートマップで可視化 import matplotlib.pyplot as plt import seaborn as sns # 日本語フォント設定(環境に応じて変更) plt.rcParams[‘font.family’] = ‘DejaVu Sans’ # ヒートマップ作成 plt.figure(figsize=(12, 6)) sns.heatmap( retention_table, annot=True, # 数値を表示 fmt=’.1f’, # 小数点1桁 cmap=’RdYlGn’, # 赤→黄→緑のカラーマップ cbar_kws={‘label’: ‘Retention Rate (%)’}, vmin=0, vmax=100, linewidths=0.5 ) plt.title(‘Cohort Analysis: Retention Rate’, fontsize=14, fontweight=’bold’) plt.xlabel(‘Months Since Signup’, fontsize=12) plt.ylabel(‘Signup Month’, fontsize=12) plt.tight_layout() plt.savefig(‘cohort_heatmap.png’, dpi=150, bbox_inches=’tight’) plt.show() print(“→ ヒートマップを保存しました: cohort_heatmap.png”) # サマリー統計 print(“\n【サマリー】”) print(f”1ヶ月目リテンション平均: {retention_table[1].mean():.1f}%”) print(f”2ヶ月目リテンション平均: {retention_table[2].mean():.1f}%”) print(f”3ヶ月目リテンション平均: {retention_table[3].mean():.1f}%”)
# 出力例 → ヒートマップを保存しました: cohort_heatmap.png 【サマリー】 1ヶ月目リテンション平均: 50.5% 2ヶ月目リテンション平均: 33.6% 3ヶ月目リテンション平均: 24.2%

📈 3. コホート分析の解釈

パターンの読み取り

💡 コホート分析から読み取れること

1. 初期離脱の確認
・0ヶ月→1ヶ月の落ち込みが大きい
→ オンボーディングに問題あり

2. 長期的なトレンド
・最近のコホートほど、リテンション率が高い
→ サービス改善の効果が出ている!

3. 季節性の影響
・特定の月のコホートだけ低い
→ 季節要因やキャンペーンの影響

4. 安定するタイミング
・3ヶ月目以降はリテンション率が横ばい
→ 3ヶ月継続すれば、定着する

縦と横の読み方

📊 横方向(同じコホート)

・同じユーザー群の時間経過を追跡
・「このコホートはどう変化したか?」
・減少カーブの形を確認
・急激に落ちる vs 緩やかに落ちる

📊 縦方向(同じ経過月)

・異なるコホートを同じタイミングで比較
・「1ヶ月後の定着率は改善しているか?」
・施策効果の確認
・最近のコホートが良いか確認

アクションへの変換

# コホート分析からアクションを導出 def analyze_cohort_patterns(retention_table): “””コホート分析からパターンを抽出””” print(“=” * 60) print(“コホート分析レポート”) print(“=” * 60) # 1. 初期離脱の分析 month1_retention = retention_table[1].dropna() avg_month1 = month1_retention.mean() print(f”\n【1. 初期離脱の分析】”) print(f”1ヶ月目リテンション平均: {avg_month1:.1f}%”) print(f”初期離脱率: {100 – avg_month1:.1f}%”) if avg_month1 < 40: print("⚠️ 警告: 初期離脱が非常に高い") print(" → オンボーディングの改善が急務") elif avg_month1 < 50: print("⚠️ 注意: 初期離脱が高め") print(" → 初回体験の見直しを推奨") else: print("✅ 良好: 初期離脱は許容範囲") # 2. トレンド分析 print(f"\n【2. トレンド分析】") trend = month1_retention.diff().dropna() avg_trend = trend.mean() if avg_trend > 0: print(f”✅ 改善傾向: 平均 +{avg_trend:.1f}%ポイント/月”) print(” → サービス改善の効果あり”) elif avg_trend < -2: print(f"⚠️ 悪化傾向: 平均 {avg_trend:.1f}%ポイント/月") print(" → 原因調査が必要") else: print(f"→ 横ばい傾向: 平均 {avg_trend:.1f}%ポイント/月") # 3. 最良・最悪コホートの特定 print(f"\n【3. コホート比較】") best_cohort = month1_retention.idxmax() worst_cohort = month1_retention.idxmin() print(f"最良コホート: {best_cohort} ({month1_retention.max():.1f}%)") print(f"最悪コホート: {worst_cohort} ({month1_retention.min():.1f}%)") print(f"差: {month1_retention.max() - month1_retention.min():.1f}%ポイント") # 4. 安定化タイミング print(f"\n【4. 安定化タイミング】") for col in retention_table.columns[1:]: if col > 0: prev_col = col – 1 drop = retention_table[prev_col].mean() – retention_table[col].mean() if drop < 3: # 3%未満の減少で安定とみなす print(f"→ {col}ヶ月目で安定化(減少幅 {drop:.1f}%)") break # 5. 推奨アクション print(f"\n【5. 推奨アクション】") if avg_month1 < 50: print("1. オンボーディングプロセスの見直し") print("2. 初回利用後のフォローアップ強化") if avg_trend < 0: print("3. 最悪コホートの離脱理由を調査") print("4. 最良コホートの成功要因を分析して横展開") print("=" * 60) # 実行 analyze_cohort_patterns(retention_table)
# 出力例 ============================================================ コホート分析レポート ============================================================ 【1. 初期離脱の分析】 1ヶ月目リテンション平均: 50.5% 初期離脱率: 49.5% ⚠️ 注意: 初期離脱が高め → 初回体験の見直しを推奨 【2. トレンド分析】 ✅ 改善傾向: 平均 +3.5%ポイント/月 → サービス改善の効果あり 【3. コホート比較】 最良コホート: 2024-05 (56.1%) 最悪コホート: 2024-01 (42.3%) 差: 13.8%ポイント 【4. 安定化タイミング】 → 4ヶ月目で安定化(減少幅 2.8%) 【5. 推奨アクション】 1. オンボーディングプロセスの見直し 2. 初回利用後のフォローアップ強化 4. 最良コホートの成功要因を分析して横展開 ============================================================

📑 4. Excelでの実装

データ準備

【必要なデータ形式】 列A: user_id(ユーザーID) 列B: signup_date(登録日) 列C: activity_date(利用日) 例: user_id | signup_date | activity_date ——–|————-|————— 1001 | 2024-01-15 | 2024-01-15 1001 | 2024-01-15 | 2024-02-03 1001 | 2024-01-15 | 2024-02-20 1002 | 2024-01-22 | 2024-01-22 1002 | 2024-01-22 | 2024-03-10

計算式の追加

【Excelでの計算式】 1. 登録月を計算(列D) =TEXT(B2, “yyyy-mm”) 2. 利用月を計算(列E) =TEXT(C2, “yyyy-mm”) 3. 経過月数を計算(列F) =DATEDIF(B2, C2, “m”) ※ 同じ月内は0になる 4. ピボットテーブルを作成 – 行: signup_month(登録月) – 列: months_since_signup(経過月数) – 値: user_id(重複を除いたカウント) 5. リテンション率を計算 各セルを「0ヶ月」の値で割る × 100

条件付き書式でヒートマップ

【Excelでヒートマップ風に表示】 1. リテンション率のセル範囲を選択 2. ホーム → 条件付き書式 → カラースケール 3. 「赤-黄-緑」のカラースケールを選択 – 最小値(赤): 0 – 中間値(黄): 50 – 最大値(緑): 100 → Pythonのヒートマップと同様の見た目になる

💼 5. 実務での活用

活用シーン

📌 コホート分析の活用シーン

例1:オンボーディング改善
・3月に新しいチュートリアルを導入
・3月コホートのリテンション率が改善
→ チュートリアルの効果あり!

例2:施策の効果測定
・4月にプッシュ通知を強化
・4月コホートの2ヶ月目リテンションが向上
→ プッシュ通知が有効

例3:ターゲット変更の影響
・5月から獲得チャネルを変更
・5月コホートのリテンションが低下
→ 新チャネルの質が低い

例4:プロダクト改善の効果
・6月に大型アップデート
・6月以降のコホートが全期間で改善
→ アップデートの効果が持続的

レポーティングのポイント

💡 経営層への報告ポイント

1. 結論を先に
「1ヶ月目リテンションが42%→56%に改善しました」

2. ヒートマップで視覚的に
色で一目でわかるように表示

3. 改善・悪化の要因を説明
「3月からのオンボーディング改善が効いています」

4. 次のアクションを提案
「さらに初回体験を強化することを推奨します」

📝 STEP 23 のまとめ

✅ このステップで学んだこと

1. コホートの概念

  • 同時期に同じ体験をしたユーザーグループ
  • 時間ベース、行動ベース、属性ベースなど

2. リテンション率

  • 一定期間後の継続利用率
  • リテンション率 = 継続者数 / 初期者数 × 100%

3. コホート表

  • 各コホートの行動を時系列で追跡
  • ヒートマップで視覚的にパターンを把握

4. 実務活用

  • 施策効果の測定
  • 改善ポイントの発見
  • トレンドの把握
💡 最も大切なポイント

コホート分析は、顧客の長期的な行動を理解する強力なツールです!

コホート分析の価値:
・単純な全体平均では見えないパターンを発見
・施策の長期的な効果を測定
・コホート間の違いから学びを得る

次のSTEP 24では、ファネル分析を学びます!

🎯 次のステップの予告

STEP 24では、「ファネル分析」を学びます。顧客の購買プロセスを段階ごとに分析し、離脱ポイントを特定する方法を習得しましょう!

📝 練習問題

問題 1 基礎

コホート分析とは何ですか?簡潔に説明してください。

【解答】

コホート分析とは、同じ時期に同じ体験をしたユーザーグループ(コホート)を追跡し、時間経過に伴う行動パターンを分析する手法です。

例:
・1月登録ユーザー、2月登録ユーザー…を別々に追跡
・各コホートのリテンション率(継続率)を比較
・施策効果やトレンドを把握

問題 2 基礎

以下のコホート表を見て、どのコホートが最も優れていますか?

登録月0ヶ月1ヶ月2ヶ月
1月100%30%15%
2月100%50%35%
3月100%60%45%

【解答】3月コホートが最も優れている

理由:

・1月コホート:1ヶ月後30%、2ヶ月後15%
・2月コホート:1ヶ月後50%、2ヶ月後35%
・3月コホート:1ヶ月後60%、2ヶ月後45%

3月コホートが全期間で最も高いリテンション率を示しています。

解釈:

・時間が経つにつれて改善傾向
・サービス改善の効果が表れている可能性
・3月に何か変更があったか確認すべき

問題 3 応用

1月コホートは100人登録、1ヶ月後に40人が利用していました。

(1) リテンション率を計算してください。
(2) 60人が離脱したことは、何を意味しますか?

【解答】

(1) リテンション率の計算:

リテンション率 = (1ヶ月後の利用者数 / 初期の利用者数) × 100%
= (40 / 100) × 100%
= 40%

(2) 60人離脱の意味:

チャーン率60%:10人中6人が離脱
・非常に高い離脱率

考えられる原因:
・オンボーディングが不十分
・サービスの価値が伝わっていない
・競合サービスに流出

改善アクション:
・離脱ユーザーにアンケート
・初回体験(FTU)の改善
・リマインド施策の強化

問題 4 応用

コホート分析で「縦方向」と「横方向」の読み方の違いを説明してください。

【解答】

横方向(同じコホート内):

同じユーザー群の時間経過を追跡
・「このコホートはどう変化したか?」
・減少カーブの形を確認
・例:1月コホートの0ヶ月→1ヶ月→2ヶ月の変化

縦方向(同じ経過月):

異なるコホートを同じタイミングで比較
・「1ヶ月後の定着率は改善しているか?」
・施策効果の確認
・例:全コホートの「1ヶ月目」リテンションを比較

問題 5 実践

以下のコホートデータを分析し、改善策を提案してください。

登録月ユーザー数0ヶ月1ヶ月2ヶ月3ヶ月
1月1000100%35%20%15%
2月1200100%38%22%17%
3月1500100%55%40%32%
4月1800100%58%42%

【解答】

分析結果:

1. 初期離脱:
・1-2月:65%が1ヶ月で離脱(非常に高い)
・3-4月:42-45%が1ヶ月で離脱(改善)

2. トレンド:
・3月から大幅に改善(+17%ポイント)
・3月に何か施策があった可能性

3. 長期定着:
・1-2月コホート:3ヶ月後15-17%
・3月コホート:3ヶ月後32%(2倍以上!)

改善策:

1. 3月の成功要因を分析
・何を変えたか確認して横展開

2. 1-2月コホートへのアプローチ
・休眠ユーザーへの再活性化キャンペーン
・新機能の案内

3. 初期離脱のさらなる改善
・まだ40%以上が1ヶ月で離脱
・オンボーディングのさらなる強化
・初回体験の改善

❓ よくある質問

Q1: リテンション率とアクティブ率の違いは?
基準となる母数が異なります。

リテンション率:
・分母:そのコホートの初期ユーザー数
・例:1月登録100人中、2月に40人利用 → 40%
・「登録時から何%残っているか」

アクティブ率:
・分母:全ユーザー数(累積)
・例:全体1000人中、今月400人利用 → 40%
・「今、何%がアクティブか」

使い分け:
・リテンション率:コホートごとの定着度を見る
・アクティブ率:サービス全体の健全性を見る
Q2: コホートサイズが小さい場合、どうすれば良いですか?
複数月をまとめる、または週次で分析します。

問題:
・1月登録:10人、2月登録:15人など
・サンプルが小さく、ノイズが大きい

対処法1:複数月をまとめる
・1〜3月登録をまとめて「Q1コホート」
・4〜6月登録をまとめて「Q2コホート」

対処法2:週次コホート
・月次ではなく、週次でコホートを作る
・より細かい変化を追跡できる

目安:
各コホート最低50〜100人は欲しい
Q3: Excelでコホート分析はできますか?
はい、ピボットテーブルで可能です。

手順:
1. データ準備:user_id, signup_date, activity_date
2. 月を計算:=TEXT(signup_date, “yyyy-mm”)
3. 経過月数:=DATEDIF(signup_date, activity_date, “m”)
4. ピボットテーブル:行=登録月、列=経過月数、値=ユーザー数
5. リテンション率:各セル / 0ヶ月の値 × 100

ヒートマップ風表示:
条件付き書式でカラースケールを適用
Q4: 良いリテンション率の基準は?
業界やサービスの種類によって大きく異なります。

一般的な目安:
SaaS:1ヶ月後 60〜70%、12ヶ月後 30〜40%
モバイルゲーム:1日後 30〜40%、30日後 5〜10%
Eコマース:3ヶ月後 20〜30%
SNS:1ヶ月後 40〜50%

重要なのは:
・自社の過去データとの比較
・競合他社とのベンチマーク
・改善傾向にあるか
Q5: コホート分析はどの頻度で行うべき?
月次が基本、重要な施策後は随時確認。

月次レポート:
・定期的なモニタリング
・経営報告用

施策後の分析:
・大きな変更があった後は即座に
・1週間後、1ヶ月後など複数回確認

ダッシュボード化:
・リアルタイムで確認できる仕組みを作る
・異常値を早期発見
Q6: コホート分析とファネル分析の違いは?
時間軸 vs プロセス軸の違いです。

コホート分析:
時間軸での追跡
・同時期に登録したユーザーの変化を見る
・「1ヶ月後、2ヶ月後…どうなった?」
・用途:リテンション、LTV分析

ファネル分析:
プロセス軸での追跡
・購買プロセスの各段階を見る
・「訪問→登録→購入…どこで離脱?」
・用途:コンバージョン改善

組み合わせ:
両方を組み合わせることで、より深い分析が可能
📝

学習メモ

ビジネスデータ分析・意思決定 - Step 23

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE