Retention Analysis (리텐션 분석)
개요
Retention은 서비스 성장의 가장 중요한 지표다. 신규 유입보다 기존 사용자의 유지가 5-25배 저렴하고, 리텐션 5% 개선이 이익 25-95% 증가로 이어진다.
리텐션 유형
┌─────────────────────────────────────────────────────────────┐
│ Retention Types │
│ │
│ Day N Retention (클래식) │
│ ├─ 가입 후 정확히 N일째 복귀한 비율 │
│ └─ 예: D1 = 40%, D7 = 20%, D30 = 10% │
│ │
│ Rolling Retention (범위) │
│ ├─ N일 이후 언제든 복귀한 비율 │
│ └─ 예: D7+ = N일 이후 한 번이라도 복귀 │
│ │
│ Bracket Retention (구간) │
│ ├─ 특정 기간 구간 내 복귀 비율 │
│ └─ 예: Week 1, Week 2-4, Month 2-3 │
│ │
│ Unbounded Retention (누적) │
│ ├─ 가입 이후 전체 기간 중 활성 일수 비율 │
│ └─ DAU/MAU 기반 stickiness │
└─────────────────────────────────────────────────────────────┘
측정 방법
Day N Retention 계산
import pandas as pd
def calculate_retention(events_df, cohort_col='signup_date',
activity_col='activity_date', user_col='user_id'):
# 코호트별 사용자 수
cohort_sizes = events_df.groupby(cohort_col)[user_col].nunique()
# Day N 계산
events_df['day_n'] = (events_df[activity_col] - events_df[cohort_col]).dt.days
# 리텐션 피벗
retention = events_df.groupby([cohort_col, 'day_n'])[user_col].nunique().unstack()
# 비율 계산
retention_rate = retention.divide(cohort_sizes, axis=0)
return retention_rate
결과 예시
| Cohort |
D0 |
D1 |
D7 |
D14 |
D30 |
| Jan W1 |
100% |
42% |
21% |
15% |
9% |
| Jan W2 |
100% |
45% |
23% |
16% |
10% |
| Jan W3 |
100% |
38% |
19% |
13% |
8% |
리텐션 커브
표준 패턴
┌─────────────────────────────────────────────────────────────┐
│ Retention Curve Shapes │
│ │
│ 100% ┤ │
│ │╲ │
│ │ ╲ │
│ │ ╲_____ Flattening (좋음) │
│ │ ╲ │
│ │ ╲_____ Declining (경고) │
│ │ ╲ │
│ │ ╲_____ 0으로 수렴 (위험) │
│ 0% ┤ │
│ └──────────────────────────────────────── │
│ D0 D7 D14 D30 D60 D90 │
└─────────────────────────────────────────────────────────────┘
좋은 리텐션 커브:
- 초반 급락 후 안정화 (flattening)
- 장기 리텐션 > 0
나쁜 리텐션 커브:
- 지속적 하락
- 0으로 수렴 (leaky bucket)
산업별 벤치마크
| 산업 |
D1 |
D7 |
D30 |
특징 |
| 소셜 미디어 |
40-50% |
25-30% |
15-20% |
네트워크 효과 중요 |
| 모바일 게임 |
35-45% |
15-20% |
5-10% |
초반 훅이 관건 |
| SaaS B2B |
90%+ |
85%+ |
80%+ |
월간 기준, 해지율 낮음 |
| E-commerce |
20-30% |
10-15% |
5-10% |
재구매 주기 길음 |
| 핀테크 |
40-50% |
30-35% |
20-25% |
습관 형성 중요 |
심화 분석
1. 코호트별 비교
import matplotlib.pyplot as plt
import seaborn as sns
def plot_retention_heatmap(retention_df):
plt.figure(figsize=(12, 8))
sns.heatmap(
retention_df,
annot=True,
fmt='.1%',
cmap='YlOrRd_r',
vmin=0,
vmax=1
)
plt.title('Retention by Cohort')
plt.xlabel('Days Since Signup')
plt.ylabel('Cohort')
2. 세그먼트별 분석
┌─────────────────────────────────────────────────────────────┐
│ Retention by Segment │
│ │
│ Acquisition Channel: │
│ ├─ Organic Search: D30 = 15% │
│ ├─ Paid Ads: D30 = 8% │
│ └─ Referral: D30 = 22% ← 최고 │
│ │
│ Onboarding Completion: │
│ ├─ Complete: D30 = 25% │
│ ├─ Partial: D30 = 10% │
│ └─ Skip: D30 = 3% │
│ │
│ First Week Actions: │
│ ├─ 5+ actions: D30 = 30% │
│ ├─ 2-4 actions: D30 = 12% │
│ └─ 1 action: D30 = 4% │
└─────────────────────────────────────────────────────────────┘
3. 이탈 시점 분석
def find_critical_moments(retention_series):
"""리텐션 급락 시점 탐지"""
daily_drop = retention_series.diff()
# 일별 이탈률이 평균보다 2배 이상인 시점
critical_days = daily_drop[daily_drop < daily_drop.mean() * 2]
return critical_days
# 결과: D1(-30%), D3(-8%), D7(-5%) → D1이 가장 critical
리텐션 개선 전략
1. 온보딩 최적화
┌─────────────────────────────────────────────────────────────┐
│ Onboarding Funnel │
│ │
│ 가입 → 프로필 설정 → 핵심 기능 경험 → Aha Moment │
│ 100% 70% 45% 30% │
│ │
│ 개선 포인트: │
│ - 프로필 설정: 선택 항목 최소화 │
│ - 핵심 기능: 강제 튜토리얼 vs 자연스러운 유도 │
│ - Aha Moment: 가치 경험까지 스텝 수 감소 │
└─────────────────────────────────────────────────────────────┘
2. Aha Moment 발견
# Aha Moment = 리텐션과 상관관계 높은 초기 행동
def find_aha_moment(users_df, actions_df, retention_threshold_days=30):
# 각 액션별 실행 여부
action_flags = actions_df.pivot_table(
index='user_id',
columns='action_type',
values='count',
aggfunc='sum'
).fillna(0)
# 리텐션 여부
retained = users_df['retained_d30']
# 상관관계 계산
correlations = action_flags.corrwith(retained)
return correlations.sort_values(ascending=False)
# 결과 예시:
# connect_friends 0.45 ← Aha Moment 후보
# complete_profile 0.32
# make_first_post 0.28
3. 리인게이지먼트
| 이탈 시점 |
채널 |
메시지 |
| D1 |
Push |
"설정 완료하고 첫 보상 받기" |
| D3 |
Email |
"놓친 업데이트 확인하기" |
| D7 |
SMS |
"친구가 활동 중, 확인해보세요" |
| D30 |
Email |
"돌아오시면 특별 혜택" |
고급 기법
1. 생존 분석 (Survival Analysis)
from lifelines import KaplanMeierFitter
kmf = KaplanMeierFitter()
kmf.fit(
durations=users_df['tenure_days'],
event_observed=users_df['churned']
)
# 생존 곡선
kmf.plot_survival_function()
# 중간 생존 시간 (50%가 이탈하는 시점)
median_survival = kmf.median_survival_time_
2. Cox 비례 위험 모델
from lifelines import CoxPHFitter
cph = CoxPHFitter()
cph.fit(
users_df[['tenure_days', 'churned', 'feature1', 'feature2', 'segment']],
duration_col='tenure_days',
event_col='churned'
)
# 위험 비율 (Hazard Ratio)
cph.print_summary()
# feature1 HR=1.5 → 이탈 위험 50% 증가
# feature2 HR=0.7 → 이탈 위험 30% 감소
3. 예측 모델
from sklearn.ensemble import GradientBoostingClassifier
# 이탈 예측 모델
features = ['days_since_last_login', 'total_sessions',
'feature_usage_score', 'support_tickets']
model = GradientBoostingClassifier()
model.fit(X_train[features], y_train)
# 이탈 위험 점수
churn_risk = model.predict_proba(X_current[features])[:, 1]
# 고위험군 선별 (상위 20%)
high_risk_users = users_df[churn_risk > 0.8]
대시보드 메트릭
┌─────────────────────────────────────────────────────────────┐
│ Retention Dashboard │
│ │
│ 핵심 지표: │
│ ├─ D1/D7/D30 Retention (코호트별) │
│ ├─ Stickiness (DAU/MAU) │
│ ├─ Churn Rate (월간/연간) │
│ └─ Customer Lifetime (평균 사용 기간) │
│ │
│ 세그먼트 분석: │
│ ├─ 채널별, 플랜별, 지역별 리텐션 │
│ └─ Power Users vs Casual Users │
│ │
│ 트렌드: │
│ ├─ 주간/월간 리텐션 추이 │
│ └─ 코호트 간 리텐션 비교 │
└─────────────────────────────────────────────────────────────┘
체크리스트
□ 측정 설정
□ 리텐션 정의 (Day N, Rolling, Bracket)
□ 활성 사용자 정의 (로그인? 특정 액션?)
□ 코호트 기준 (가입일, 첫 구매일?)
□ 분석
□ 벤치마크 대비 현황
□ 세그먼트별 차이
□ Critical moments 식별
□ 개선
□ Aha Moment 정의
□ 온보딩 퍼널 최적화
□ 리인게이지먼트 자동화
□ 모니터링
□ 주간 코호트 리포트
□ 이탈 예측 알림
□ 실험 영향 추적
참고 자료
- Amplitude, "Mastering Retention" Guide
- Reforge, "Retention Deep Dive" Course
- Chen, Andrew, "The Power User Curve"