😊 STEP 53: 実践プロジェクト4 – 顧客満足度調査分析
NPS調査結果から改善優先度を特定し、アクションプランを作成しよう
📋 このプロジェクトで取り組むこと
- NPS(ネットプロモータースコア)調査結果の分析
- 前期比較と変化要因の特定
- セグメント別分析と統計的検証
- テキストマイニング(自由回答の分析)
- 改善優先度の特定とアクションプラン策定
難易度: 実践レベル(顧客の声を戦略的改善につなげる)
📊 1. プロジェクトの概要
あなたに与えられたミッション
あなたはB2B SaaS企業「CloudWork」のカスタマーサクセス部に所属しています。
四半期ごとに実施している顧客満足度調査(NPS調査)の結果、
前期比でNPSスコアが10ポイント低下しました。
「今期のNPSは35で、前期の45から大幅に下落している。
この状況は解約率(チャーン)の増加につながる危険信号だ。
何が問題なのか、どこから手をつけるべきか、
具体的なアクションプランを1週間以内に提示してほしい。
特に批判者(Detractor)の声に注目してほしい。」
調査概要:
・調査対象: 既存顧客500社
・回答数: 380社(回答率76%)
・調査項目: NPS質問、製品機能満足度、サポート満足度、自由記述
NPSとは何か
「この製品/サービスを友人や同僚に勧める可能性はどのくらいですか?」
(0〜10点で回答)
回答者の分類:
・推奨者(Promoter): 9-10点 → 積極的に勧める
・中立者(Passive): 7-8点 → 満足だが熱狂的ではない
・批判者(Detractor): 0-6点 → 不満、解約リスク高い
NPSの計算:
→ -100〜+100の範囲で表される
現在の状況
| 指標 | 今期 | 前期 | 目標 | 業界平均 |
|---|---|---|---|---|
| NPS | 35 | 45 | 50 | 42 |
| 推奨者 | 42% | 50% | – | – |
| 中立者 | 35% | 35% | – | – |
| 批判者 | 23% | 15% | – | – |
問題: 推奨者が8pp減少、批判者が8pp増加 → NPS 10pt低下
プロジェクトの全体像
→ スコアの変化と内訳を確認
STEP 2: セグメント別分析
→ どの顧客層で問題が起きているか特定
STEP 3: 満足度ドライバー分析
→ NPSに最も影響する要因を特定
STEP 4: テキストマイニング
→ 自由回答から具体的な問題を抽出
STEP 5: 改善優先度マトリックス
→ インパクト×実現性で優先順位付け
STEP 6: アクションプランと効果予測
→ 具体的な施策とROI試算
STEP 7: リスク分析と対策
→ 期待損失の計算と予備費確保
📈 2. STEP 1: NPS基本分析と前期比較
データの準備
まず、必要なライブラリを読み込み、調査データを作成します。
・pandas: データを表形式で扱う
・numpy: 数値計算
・scipy.stats: 統計検定
・調査回答データを生成(実務では実データをインポート)
# 必要なライブラリを読み込む
import pandas as pd
import numpy as np
from scipy import stats
from collections import Counter
# 調査データの生成(実務では実データをインポート)
np.random.seed(42)
n_responses = 380 # 回答数
# NPSスコアを生成(批判者23%、中立者35%、推奨者42%の分布)
nps_scores = []
# 批判者(0-6点): 23%
detractors = np.random.choice(range(0, 7), size=int(n_responses * 0.23))
nps_scores.extend(detractors)
# 中立者(7-8点): 35%
passives = np.random.choice([7, 8], size=int(n_responses * 0.35))
nps_scores.extend(passives)
# 推奨者(9-10点): 42%
promoters = np.random.choice([9, 10], size=int(n_responses * 0.42))
nps_scores.extend(promoters)
nps_scores = np.array(nps_scores[:n_responses])
顧客属性データを追加
セグメント分析のため、顧客の属性情報を追加します。
# 顧客属性を生成
# np.random.choice(): 指定した選択肢からランダムに選ぶ
# p=: 各選択肢の確率を指定
company_sizes = np.random.choice(
['小規模', '中規模', '大規模'],
size=n_responses,
p=[0.4, 0.4, 0.2] # 小規模40%、中規模40%、大規模20%
)
industries = np.random.choice(
['IT', '製造', '小売', 'サービス'],
size=n_responses,
p=[0.3, 0.25, 0.25, 0.2]
)
tenure_months = np.random.choice(
['6ヶ月未満', '6-12ヶ月', '12ヶ月以上'],
size=n_responses,
p=[0.25, 0.35, 0.4]
)
plans = np.random.choice(
['Basic', 'Professional', 'Enterprise'],
size=n_responses,
p=[0.4, 0.4, 0.2]
)
# データフレームを作成
survey_df = pd.DataFrame({
'NPS_Score': nps_scores,
'企業規模': company_sizes,
'業種': industries,
'利用期間': tenure_months,
'プラン': plans
})
NPSカテゴリに分類する
スコアを推奨者・中立者・批判者に分類します。
# NPSカテゴリ分類関数
# スコアに応じて推奨者/中立者/批判者に分類
def classify_nps(score):
if score >= 9:
return '推奨者'
elif score >= 7:
return '中立者'
else:
return '批判者'
# apply(): 各行に関数を適用
survey_df['NPSカテゴリ'] = survey_df['NPS_Score'].apply(classify_nps)
# カテゴリ別に集計
# value_counts(): 各カテゴリの出現回数をカウント
nps_counts = survey_df['NPSカテゴリ'].value_counts()
nps_percentages = (nps_counts / len(survey_df) * 100).round(1)
print("【NPSカテゴリ別集計】")
for category in ['推奨者', '中立者', '批判者']:
if category in nps_counts.index:
count = nps_counts[category]
pct = nps_percentages[category]
print(f"{category}: {count}人 ({pct}%)")
NPSスコアを計算
# NPSスコア計算
promoters_pct = nps_percentages.get('推奨者', 0)
detractors_pct = nps_percentages.get('批判者', 0)
nps = promoters_pct - detractors_pct
print("【NPSスコア計算】")
print(f"NPS = 推奨者% - 批判者%")
print(f"NPS = {promoters_pct}% - {detractors_pct}%")
print(f"NPS = {nps:.0f}")
# 前期・目標との比較
previous_nps = 45
target_nps = 50
industry_avg = 42
print()
print("【比較】")
print(f"今期NPS: {nps:.0f}")
print(f"前期NPS: {previous_nps} (変化: {nps - previous_nps:+.0f})")
print(f"目標NPS: {target_nps} (ギャップ: {nps - target_nps:+.0f})")
print(f"業界平均: {industry_avg} (差: {nps - industry_avg:+.0f})")
前期との詳細比較
# 前期データ(実務では実データ)
previous_data = {'推奨者': 50, '中立者': 35, '批判者': 15}
current_data = {
'推奨者': promoters_pct,
'中立者': nps_percentages.get('中立者', 0),
'批判者': detractors_pct
}
print("【カテゴリ別変化】")
print(f"{'カテゴリ':<8} {'前期':<10} {'今期':<10} {'変化':<10}")
print("-" * 40)
for cat in ['推奨者', '中立者', '批判者']:
prev = previous_data[cat]
curr = current_data[cat]
change = curr - prev
print(f"{cat:<8} {prev:<10.1f}% {curr:<10.1f}% {change:+.1f}pp")
・推奨者が8pp減少(50% → 42%)
・批判者が8pp増加(15% → 23%)
・中立者は変化なし(35%)
次のアクション:
セグメント別に分析し、どの顧客層で問題が起きているかを特定する
📈 3. STEP 2: セグメント別分析と統計的検証
セグメント別NPS計算関数
各セグメント(企業規模、プラン、利用期間など)ごとにNPSを計算する関数を作成します。
# セグメント別NPS計算関数
def calculate_segment_nps(df, segment_col, segment_value):
"""
指定したセグメントのNPSを計算する
引数:
df: データフレーム
segment_col: セグメント列名(例: '企業規模')
segment_value: セグメント値(例: '小規模')
戻り値:
nps: NPSスコア
n: 回答数
promoter_pct: 推奨者割合
detractor_pct: 批判者割合
"""
# 指定セグメントのデータを抽出
segment_data = df[df[segment_col] == segment_value]
if len(segment_data) == 0:
return None, 0, 0, 0
# カテゴリ別にカウント
promoters = len(segment_data[segment_data['NPSカテゴリ'] == '推奨者'])
detractors = len(segment_data[segment_data['NPSカテゴリ'] == '批判者'])
n = len(segment_data)
# 割合を計算
promoter_pct = promoters / n * 100
detractor_pct = detractors / n * 100
nps = promoter_pct - detractor_pct
return nps, n, promoter_pct, detractor_pct
企業規模別NPS
# 企業規模別NPSを計算
print("【企業規模別NPS】")
print()
size_nps = {}
for size in ['小規模', '中規模', '大規模']:
nps_val, n, prom_pct, det_pct = calculate_segment_nps(survey_df, '企業規模', size)
size_nps[size] = nps_val
print(f"{size}:")
print(f" 回答数: {n}")
print(f" NPS: {nps_val:.0f}")
print(f" 推奨者: {prom_pct:.1f}% 批判者: {det_pct:.1f}%")
print()
統計的検定:セグメント間の差の有意性
企業規模によってNPSに本当に差があるのか、統計的に検証します。
2つのカテゴリ変数(例: 企業規模とNPSカテゴリ)の間に
関連があるかどうかを検証する統計手法です。
・p値 < 0.05 → 関連がある(有意)
・p値 >= 0.05 → 関連があるとは言えない
# カイ二乗検定: 企業規模とNPSカテゴリの関連
# クロス集計表を作成
# pd.crosstab(): 2つのカテゴリ変数の組み合わせをカウント
contingency_table = pd.crosstab(survey_df['企業規模'], survey_df['NPSカテゴリ'])
print("【クロス集計表】")
print(contingency_table)
print()
# カイ二乗検定を実行
# stats.chi2_contingency(): カイ二乗検定を行う
chi2, p_value, dof, expected = stats.chi2_contingency(contingency_table)
print("【カイ二乗検定の結果】")
print(f"カイ二乗統計量: {chi2:.2f}")
print(f"自由度: {dof}")
print(f"p値: {p_value:.4f}")
print()
if p_value < 0.05:
print("✓ 統計的に有意(p < 0.05)")
print(" → 企業規模によってNPSカテゴリの分布が異なる")
else:
print("✗ 統計的に有意ではない(p >= 0.05)")
print(" → 企業規模とNPSに明確な関連はない")
2群間の比較(t検定)
小規模企業と大規模企業のNPSスコアに差があるか、t検定で検証します。
# 2群間比較: 小規模 vs 大規模
# 各グループのスコアを抽出
small_scores = survey_df[survey_df['企業規模'] == '小規模']['NPS_Score']
large_scores = survey_df[survey_df['企業規模'] == '大規模']['NPS_Score']
# t検定を実行
# stats.ttest_ind(): 2つの独立したグループの平均を比較
t_stat, t_pvalue = stats.ttest_ind(small_scores, large_scores)
print("【2群間比較: 小規模 vs 大規模】")
print(f"小規模 平均スコア: {small_scores.mean():.2f}")
print(f"大規模 平均スコア: {large_scores.mean():.2f}")
print(f"差: {small_scores.mean() - large_scores.mean():.2f}")
print()
print(f"t統計量: {t_stat:.3f}")
print(f"p値: {t_pvalue:.4f}")
print()
if t_pvalue < 0.05:
print("✓ 統計的に有意な差あり")
else:
print("✗ 統計的に有意な差なし")
効果量(Cohen's d)
差が「統計的に有意」かだけでなく、「実務的に意味のある大きさ」かも確認します。
# 効果量(Cohen's d)を計算
# 差の大きさを標準偏差で割って、実務的な意味を評価
def cohens_d(group1, group2):
"""Cohen's dを計算する関数"""
n1, n2 = len(group1), len(group2)
var1, var2 = group1.var(), group2.var()
# プールした標準偏差
pooled_std = np.sqrt(((n1-1)*var1 + (n2-1)*var2) / (n1+n2-2))
return (group1.mean() - group2.mean()) / pooled_std
d = cohens_d(small_scores, large_scores)
print(f"効果量(Cohen's d): {d:.3f}")
# 効果量の解釈
if abs(d) < 0.2:
effect_size = "小さい(ほぼ差なし)"
elif abs(d) < 0.5:
effect_size = "小〜中程度"
elif abs(d) < 0.8:
effect_size = "中程度"
else:
effect_size = "大きい"
print(f"効果量の解釈: {effect_size}")
| 効果量 | 解釈 | 実務的意味 |
|---|---|---|
| d < 0.2 | 小さい | 差はほぼ無視できる |
| 0.2 ≤ d < 0.5 | 小〜中 | 注意すべき差 |
| 0.5 ≤ d < 0.8 | 中程度 | 明確な差がある |
| d ≥ 0.8 | 大きい | 実務的に重要な差 |
プラン別・利用期間別NPS
# プラン別NPS
print("【プラン別NPS】")
plan_nps = {}
for plan in ['Basic', 'Professional', 'Enterprise']:
nps_val, n, _, _ = calculate_segment_nps(survey_df, 'プラン', plan)
plan_nps[plan] = nps_val
print(f"{plan}: NPS {nps_val:.0f} (n={n})")
print()
# 利用期間別NPS
print("【利用期間別NPS】")
tenure_nps = {}
for tenure in ['6ヶ月未満', '6-12ヶ月', '12ヶ月以上']:
nps_val, n, _, _ = calculate_segment_nps(survey_df, '利用期間', tenure)
tenure_nps[tenure] = nps_val
print(f"{tenure}: NPS {nps_val:.0f} (n={n})")
・小規模企業: NPS 28(最低)→ オンボーディング強化必須
・6ヶ月未満顧客: NPS 25 → 初期体験改善が急務
・Basicプラン: NPS 30 → サポート拡充検討
次のアクション:
満足度ドライバー分析で、NPSに最も影響する要因を特定する
📈 4. STEP 3: 満足度ドライバー分析
満足度項目データの準備
製品機能とサポートの各項目について、5段階評価のデータを追加します。
# 満足度項目を定義
satisfaction_items = {
# 製品機能(7項目)
'機能_使いやすさ': [],
'機能_機能の豊富さ': [],
'機能_カスタマイズ性': [],
'機能_パフォーマンス': [],
'機能_モバイル対応': [],
'機能_セキュリティ': [],
'機能_API連携': [],
# サポート(5項目)
'サポート_対応速度': [],
'サポート_問題解決力': [],
'サポート_担当者の知識': [],
'サポート_ドキュメント': [],
'サポート_オンボーディング': []
}
# NPSカテゴリに応じた満足度スコアを生成
for idx, row in survey_df.iterrows():
category = row['NPSカテゴリ']
# 推奨者は高評価、批判者は低評価の傾向
base_score = 4.5 if category == '推奨者' else 3.5 if category == '中立者' else 2.0
for item in satisfaction_items.keys():
# サポート対応速度とオンボーディングは特に低い傾向
if 'サポート_対応速度' in item:
noise = -0.4
elif 'オンボーディング' in item:
noise = -0.3
else:
noise = 0
# np.clip(): 値を1〜5の範囲に制限
score = np.clip(base_score + noise + np.random.uniform(-0.3, 0.3), 1, 5)
satisfaction_items[item].append(score)
# データフレームに追加
for item, scores in satisfaction_items.items():
survey_df[item] = scores
項目別満足度を確認
# 列名を抽出
feature_items = [col for col in survey_df.columns if col.startswith('機能_')]
support_items = [col for col in survey_df.columns if col.startswith('サポート_')]
print("【製品機能の満足度】")
for item in feature_items:
item_name = item.replace('機能_', '')
mean_score = survey_df[item].mean()
print(f" {item_name}: {mean_score:.2f}")
print()
print("【サポートの満足度】")
for item in support_items:
item_name = item.replace('サポート_', '')
mean_score = survey_df[item].mean()
print(f" {item_name}: {mean_score:.2f}")
NPSとの相関分析(重要度分析)
各満足度項目とNPSスコアの相関を計算し、NPSに最も影響する要因を特定します。
「どの項目を改善すれば、NPSが上がるか」を特定します。
相関係数が高い項目 = NPSへの影響が大きい = 優先的に改善すべき
# 各項目とNPSの相関を計算
all_items = feature_items + support_items
correlations = {}
for item in all_items:
# stats.pearsonr(): ピアソン相関係数とp値を計算
corr, pval = stats.pearsonr(survey_df['NPS_Score'], survey_df[item])
correlations[item] = {'corr': corr, 'pvalue': pval}
# 相関係数の絶対値で降順ソート
sorted_correlations = sorted(
correlations.items(),
key=lambda x: abs(x[1]['corr']),
reverse=True
)
print("【NPSとの相関(上位5項目)】")
print("→ これらがNPS向上のドライバー")
print()
for i, (item, vals) in enumerate(sorted_correlations[:5], 1):
item_name = item.replace('機能_', '').replace('サポート_', '')
# 有意性を示すマーク
if vals['pvalue'] < 0.001:
sig = "***"
elif vals['pvalue'] < 0.01:
sig = "**"
else:
sig = "*"
print(f"{i}. {item_name}: 相関 {vals['corr']:.3f} {sig}")
1. サポート対応速度: 相関 0.82 → 最重要
2. オンボーディング: 相関 0.78
3. パフォーマンス: 相関 0.75
優先改善項目:
サポート対応速度とオンボーディングの改善が急務
📈 5. STEP 4: テキストマイニング(自由回答分析)
批判者のコメントを分析
自由回答から具体的な問題点を抽出します。
# 批判者のコメント(サンプル)
detractor_comments = [
"サポートの対応が遅すぎる。問い合わせから3日待たされた。",
"機能は良いが、動作が重い。大量データの処理に時間がかかる。",
"初期設定が複雑で、使い始めるまでに時間がかかった。",
"モバイルアプリの使い勝手が悪い。",
"価格が高い割に機能が限られている。",
"バグが多く、作業が中断される。",
"ドキュメントが不十分で、使い方が分からない。",
"API連携がうまくいかない。",
"サポート担当者の知識不足を感じる。",
"オンボーディングのサポートが不足している。",
"以前は良かったが、最近サポートの質が落ちた。",
"競合製品の方が使いやすくなってきている。"
]
print(f"批判者コメント数: {len(detractor_comments)}件")
カテゴリ別に問題を分類
# 問題カテゴリとキーワード
categories = {
'サポート品質': ['サポート', '対応', '問い合わせ', '担当者'],
'パフォーマンス': ['遅い', '重い', '時間がかかる', 'バグ'],
'使いやすさ': ['複雑', '分かりにくい', '使い方', 'UI'],
'機能・連携': ['機能', 'カスタマイズ', '連携', 'API'],
'オンボーディング': ['初期設定', 'オンボーディング', '導入']
}
# 各カテゴリに該当するコメント数をカウント
print("【問題カテゴリの分類】")
print()
category_counts = {}
for category, keywords in categories.items():
# any(): いずれかのキーワードが含まれていればTrue
count = sum(1 for c in detractor_comments if any(k in c for k in keywords))
category_counts[category] = count
# 件数の多い順にソート
for category, count in sorted(category_counts.items(), key=lambda x: x[1], reverse=True):
pct = count / len(detractor_comments) * 100
bar = '█' * int(pct / 5) # 簡易バーチャート
print(f"{category:<15} {count}件 ({pct:>5.1f}%) {bar}")
1. サポート品質(対応速度、知識): 最多
2. パフォーマンス(動作の重さ、バグ)
3. オンボーディング(初期設定の複雑さ)
具体的な声:
・「問い合わせから3日待たされた」
・「初期設定が複雑」
・「最近サポートの質が落ちた」
📈 6. STEP 5: 改善優先度マトリックス
インパクト×実現性で優先順位付け
改善項目を「インパクト(効果)」と「実現性(容易さ)」の2軸で評価し、
優先順位を決める手法です。
Quick Wins: 高インパクト×高実現性 → 最優先
Major Projects: 高インパクト×低実現性 → 計画的に実施
# 改善項目の評価
improvement_items = [
{'項目': 'サポート対応速度', 'インパクト': 0.82, '容易性': 0.7, 'コスト': '中'},
{'項目': 'パフォーマンス改善', 'インパクト': 0.75, '容易性': 0.4, 'コスト': '高'},
{'項目': 'オンボーディング強化', 'インパクト': 0.78, '容易性': 0.8, 'コスト': '低'},
{'項目': 'ドキュメント充実', 'インパクト': 0.65, '容易性': 0.9, 'コスト': '低'},
{'項目': 'UI改善', 'インパクト': 0.70, '容易性': 0.5, 'コスト': '中'},
{'項目': 'モバイルアプリ改善', 'インパクト': 0.60, '容易性': 0.3, 'コスト': '高'},
{'項目': 'API連携強化', 'インパクト': 0.55, '容易性': 0.6, 'コスト': '中'}
]
improvement_df = pd.DataFrame(improvement_items)
# 優先度スコア = インパクト × 容易性
improvement_df['優先度スコア'] = improvement_df['インパクト'] * improvement_df['容易性']
# スコア順にソート
improvement_df = improvement_df.sort_values('優先度スコア', ascending=False)
print("【優先度ランキング】")
print()
for i, (_, row) in enumerate(improvement_df.iterrows(), 1):
print(f"{i}. {row['項目']}")
print(f" スコア: {row['優先度スコア']:.2f}")
print(f" インパクト: {row['インパクト']}, 容易性: {row['容易性']}, コスト: {row['コスト']}")
print()
分類結果
# Quick Wins(高インパクト×高容易性)
print("【Quick Wins(最優先)】")
print("→ 高インパクト×高容易性: すぐに着手")
for _, row in improvement_df.iterrows():
if row['インパクト'] >= 0.7 and row['容易性'] >= 0.7:
print(f" • {row['項目']}")
print()
# Major Projects(高インパクト×低容易性)
print("【Major Projects(計画的に実施)】")
print("→ 高インパクト×低容易性: 時間とリソースを確保")
for _, row in improvement_df.iterrows():
if row['インパクト'] >= 0.7 and row['容易性'] < 0.7:
print(f" • {row['項目']}")
| 分類 | 項目 | 優先度 |
|---|---|---|
| Quick Wins | オンボーディング強化 | 0.62 |
| サポート対応速度 | 0.57 | |
| Major Projects | パフォーマンス改善 | 0.30 |
| UI改善 | 0.35 |
📈 7. STEP 6: アクションプランと効果予測
3ヶ月改善アクションプラン
新規顧客向けウェルカムプログラム刷新
• ドキュメント充実: 1.5M円
FAQ拡充、動画チュートリアル作成
• サポート対応速度改善: 5M円
サポート人員増強、チャットボット導入
インフラ増強、コード最適化
• UI改善: 6M円
ユーザビリティテスト、UI刷新
効果予測
# 各施策の効果予測
improvements = {
'オンボーディング強化': {'NPS改善': 5, '影響顧客%': 25, '確度': 0.8},
'ドキュメント充実': {'NPS改善': 3, '影響顧客%': 60, '確度': 0.9},
'サポート対応速度': {'NPS改善': 7, '影響顧客%': 40, '確度': 0.85},
'パフォーマンス改善': {'NPS改善': 6, '影響顧客%': 50, '確度': 0.7},
'UI改善': {'NPS改善': 4, '影響顧客%': 70, '確度': 0.75}
}
# 総合改善効果を計算
# 各施策の効果 = NPS改善 × 影響顧客% × 確度
current_nps = 35
total_improvement = sum(
e['NPS改善'] * (e['影響顧客%'] / 100) * e['確度']
for e in improvements.values()
)
predicted_nps = current_nps + total_improvement
print("【NPS改善予測】")
print(f"現在のNPS: {current_nps}")
print(f"予測改善幅: +{total_improvement:.0f}pt")
print(f"3ヶ月後のNPS: {predicted_nps:.0f}")
ビジネスインパクト
# ビジネスインパクトの計算
current_churn = 3.5 # 現在のチャーン率(%)
# NPSが10pt改善するとチャーン率は約1%改善する(経験則)
expected_churn = current_churn - (total_improvement / 10)
print("【ビジネスインパクト】")
print(f"チャーン率: {current_churn}% → {expected_churn:.1f}%")
# 投資とリターン
total_investment = 22.5 # M円
annual_benefit = 51 # M円(チャーン改善による収益保持)
net_profit = annual_benefit - total_investment
roi = (net_profit / total_investment) * 100
print()
print(f"投資額: {total_investment}M円")
print(f"年間便益: {annual_benefit}M円")
print(f"純利益: {net_profit}M円")
print(f"ROI: {roi:.0f}%")
・NPS: 35 → 49(+14pt)
・チャーン率: 3.5% → 2.1%
・年間便益: 51M円
・ROI: 127%、回収5.3ヶ月
📈 8. STEP 7: リスク分析と対策
主要リスクの評価
# リスク評価
risks = [
{'リスク': 'リソース不足', '確率': 0.40, '影響(万円)': 1500,
'対策': '外部パートナー活用、優先度低プロジェクト停止'},
{'リスク': '効果不足', '確率': 0.35, '影響(万円)': 1000,
'対策': '2週間ごとのNPSサンプル調査、予算20%予備確保'},
{'リスク': 'チャーン加速', '確率': 0.30, '影響(万円)': 2000,
'対策': '批判者への即時アウトリーチ、特別対応枠確保'},
{'リスク': '協力不足', '確率': 0.20, '影響(万円)': 800,
'対策': '経営会議でコミット、部門KPIにNPS組込み'}
]
# 期待損失を計算
print("【リスク評価】")
print()
print(f"{'リスク':<12} {'確率':<8} {'影響額':<10} {'期待損失':<10}")
print("-" * 50)
total_expected_loss = 0
for r in risks:
# 期待損失 = 確率 × 影響額
expected_loss = r['確率'] * r['影響(万円)']
total_expected_loss += expected_loss
print(f"{r['リスク']:<12} {r['確率']:<8.0%} ¥{r['影響(万円)']:<8}万 ¥{expected_loss:<8.0f}万")
print("-" * 50)
print(f"合計期待損失: ¥{total_expected_loss:.0f}万")
print(f"リスク対策予備費(50%): ¥{total_expected_loss * 0.5:.0f}万")
| リスク | 確率 | 対策 |
|---|---|---|
| リソース不足 | 40% | 外部パートナー活用 |
| 効果不足 | 35% | 2週間ごとのNPSサンプル調査 |
| チャーン加速 | 30% | 批判者への即時アウトリーチ |
期待損失: 1,580万円 / 予備費: 790万円
📊 9. CCO向けエグゼクティブサマリー
NPSは35で前期比-10pt。オンボーディング・サポート・パフォーマンスの
3領域を3ヶ月で改善し、NPS 49まで回復可能。
投資22.5M円、ROI 127%を見込む。
【現状分析】
・今期NPS: 35(前期45、目標50)
・推奨者: 42%(前期50%から-8pp)
・批判者: 23%(前期15%から+8pp)
・統計検証: 企業規模によるNPS差は有意(p<0.05)
【重点セグメント】
・小規模企業: NPS 28(最低)→ オンボーディング強化必須
・6ヶ月未満顧客: NPS 25 → 初期体験改善が急務
・Basicプラン: NPS 30 → サポート拡充検討
【期待効果】
・NPS: 35 → 49(+14pt)
・チャーン率: 3.5% → 2.1%
・年間便益: 51M円
・ROI: 127%、回収5.3ヶ月
【Next Steps】
◆ 今週: CCO承認
◆ 来週: キックオフ
◆ 1ヶ月後: Phase 1完了レビュー
📝 STEP 53 のまとめ
- NPS分析: 推奨者・中立者・批判者の分類と計算
- 統計的検定: カイ二乗検定、t検定、効果量で課題を検証
- ドライバー分析: 相関分析で重要要因を特定
- テキストマイニング: 自由回答から問題を抽出
- 優先度評価: インパクト×実現性マトリックス
- リスク分析: 期待損失を計算、対策と予備費を準備
- 効果予測: シナリオ別にROIを試算
スコアだけでなく「なぜ」を分析、相関と自由記述で具体化
2. 統計的に検証する
セグメント間の差は有意か? p値と効果量で判断
3. セグメント別に分析
全体平均では課題が見えない、どこに問題があるか特定
4. 批判者の声に最注目
解約リスクが高い、即時アウトリーチが重要
5. ビジネスインパクトで語る
NPS → チャーン率 → 収益保持 → ROIで経営層を納得
❓ よくある質問
・70以上: 世界クラス(Apple, Netflixなど)
・50-70: 優秀(業界トップクラス)
・30-50: 良好(改善余地あり)
・0-30: 改善必要(チャーンリスク高)
・0未満: 深刻(批判者 > 推奨者)
業界別平均:
SaaS 40-50、EC 30-40、金融 20-30、通信 10-20
CSAT: 「満足か」(1-5点)→ 特定体験への即時満足度
CES: 「簡単だったか」(1-7点)→ 顧客の労力・負担
使い分け:
・NPS: 四半期全体調査
・CSAT: 取引後すぐ
・CES: サポート対応後
・日本語: UserLocal、見える化エンジン、KH Coder(無料)
・Python: MeCab(形態素解析)、WordCloud、sklearn(LDA)
・クラウド: Google NL API、AWS Comprehend
ワークフロー:
1. クレンジング → 2. 形態素解析 → 3. 頻出語抽出 → 4. カテゴリ分類 → 5. 可視化
少量(〜1000件)なら手動でもOK、大量はツールで効率化!
批判者は解約リスクが高い。24時間以内にアウトリーチ。
2. 聴くことが第一
言い訳せず、まず不満をしっかり聞く。
3. 具体的な改善を約束
「検討します」ではなく「〇〇を△△までに改善します」
4. フォローアップ
対応後、再度連絡して状況を確認。
学習メモ
ビジネスデータ分析・意思決定 - Step 53