게임 산업 데이터 분석
게임 산업에서의 데이터 분석 가이드. 핵심 메트릭 체계, 유저 세그멘테이션, 리텐션 분석, 매출 예측, 밸런스 분석 등 게임 데이터 분석의 전 영역을 다룬다.
개요
게임 데이터 분석은 다른 산업과 구별되는 특수성이 있다. 실시간 이벤트 기반 데이터, 복잡한 경제 시스템, 유저 행동의 높은 다양성, 콘텐츠 소비 속도와 라이브 운영의 결합이 핵심 도전 과제다.
게임 데이터의 특수성
| 특성 |
설명 |
분석 영향 |
| 이벤트 기반 |
모든 행동이 이벤트로 기록 |
이벤트 설계가 분석 품질 결정 |
| 실시간성 |
라이브 운영, 즉시 반응 필요 |
실시간 대시보드 필수 |
| 세션 구조 |
접속-플레이-이탈 패턴 |
세션 기반 분석 |
| 경제 시스템 |
인게임 재화, 거래, 인플레이션 |
경제 시뮬레이션 |
| 소셜 요소 |
길드, 파티, PvP |
네트워크 분석 |
| 긴 수명 주기 |
출시-성장-성숙-하락 |
코호트 분석 |
핵심 메트릭 체계
유저 메트릭
| 메트릭 |
산식 |
의미 |
건강한 수치 |
| DAU |
일일 순 접속자 |
일일 활성 규모 |
장르 의존적 |
| MAU |
월간 순 접속자 |
월간 활성 규모 |
장르 의존적 |
| DAU/MAU |
DAU / MAU |
점착도 (Stickiness) |
20-30% (캐주얼), 40%+ (하드코어) |
| CCU |
동시 접속자 |
피크 부하 |
- |
| 세션 수 |
일인당 일 세션 |
접속 빈도 |
2-4회 |
| 세션 시간 |
평균 플레이 시간 |
몰입도 |
장르 의존적 |
| NRU |
신규 가입자 |
유입 규모 |
UA 예산 의존 |
리텐션 메트릭
| 메트릭 |
정의 |
목표 (모바일) |
| D1 Retention |
가입 다음날 복귀율 |
40-50% |
| D7 Retention |
가입 7일 후 복귀율 |
15-25% |
| D30 Retention |
가입 30일 후 복귀율 |
5-10% |
| Rolling Retention |
D이후 아무 때나 복귀 |
D1보다 높음 |
| Return Rate |
이탈 후 복귀율 |
5-15% |
매출 메트릭
| 메트릭 |
산식 |
의미 |
| Revenue |
총 매출 |
전체 수익 |
| ARPU |
Revenue / DAU |
유저당 평균 매출 |
| ARPPU |
Revenue / 결제 유저 수 |
결제 유저당 매출 |
| Paying Rate |
결제 유저 / DAU |
결제 전환율 (1-5%) |
| LTV |
유저 생애 총 매출 |
유저 가치 |
| CPI |
UA 비용 / 설치 수 |
설치당 획득 비용 |
| ROAS |
Revenue / UA 비용 |
광고 투자 수익률 |
LTV 계산
LTV = ARPDAU x Lifetime
Lifetime = SUM(D(n) Retention) for n = 1 to infinity
≈ SUM(D(n) Retention) for n = 1 to 365 (실무적 근사)
또는:
LTV = ARPDAU x (1 / (1 - Retention_rate)) -- 기하급수 근사
분석 영역
1. 유저 세그멘테이션
결제 행동 기반으로 유저를 분류하는 것은 게임 분석의 기본이다.
| 세그먼트 |
별칭 |
기준 (월 기준) |
비율 |
매출 기여 |
| Non-payer |
물고기 |
결제 0원 |
95-97% |
0% (광고 수익만) |
| Minnow |
작은 물고기 |
< 1만원 |
1-2% |
5-10% |
| Dolphin |
돌고래 |
1만-10만원 |
1-2% |
20-30% |
| Whale |
고래 |
> 10만원 |
0.1-0.5% |
50-70% |
| Super Whale |
초고래 |
> 100만원 |
< 0.05% |
10-20% |
def segment_users(df: pd.DataFrame) -> pd.DataFrame:
"""유저 세그멘테이션 (결제 기반)
Args:
df: columns = [user_id, total_revenue_monthly]
"""
conditions = [
df['total_revenue_monthly'] == 0,
df['total_revenue_monthly'] < 10000,
df['total_revenue_monthly'] < 100000,
df['total_revenue_monthly'] < 1000000,
df['total_revenue_monthly'] >= 1000000,
]
labels = ['Non-payer', 'Minnow', 'Dolphin', 'Whale', 'Super Whale']
df['segment'] = np.select(conditions, labels, default='Non-payer')
return df
2. 이탈 예측 및 방지
유저 이탈을 사전에 예측하고 개입하여 리텐션을 개선한다.
이탈 신호 특성:
| 특성 |
설명 |
중요도 |
| 접속 빈도 감소 |
최근 7일 세션 수 변화 |
높음 |
| 세션 시간 감소 |
평균 플레이 시간 변화 |
높음 |
| 콘텐츠 진행 정체 |
레벨업/스테이지 클리어 정체 |
중간 |
| 소셜 활동 감소 |
채팅, 길드 활동 변화 |
중간 |
| 결제 패턴 변화 |
결제 금액/빈도 변화 |
높음 |
| 접속 시간대 변화 |
주 접속 시간 이동 |
낮음 |
def build_churn_features(events_df: pd.DataFrame,
user_id: str,
ref_date: str) -> dict:
"""이탈 예측용 특성 생성"""
user_events = events_df[events_df['user_id'] == user_id]
# 최근 7일 vs 이전 7일 비교
recent = user_events[user_events['date'] >= ref_date - timedelta(days=7)]
previous = user_events[
(user_events['date'] >= ref_date - timedelta(days=14)) &
(user_events['date'] < ref_date - timedelta(days=7))
]
return {
'sessions_recent_7d': recent['session_id'].nunique(),
'sessions_prev_7d': previous['session_id'].nunique(),
'session_ratio': safe_div(
recent['session_id'].nunique(),
previous['session_id'].nunique()
),
'avg_session_duration_recent': recent.groupby('session_id')['duration'].sum().mean(),
'revenue_recent_7d': recent[recent['event'] == 'purchase']['amount'].sum(),
'revenue_prev_7d': previous[previous['event'] == 'purchase']['amount'].sum(),
'days_since_last_login': (ref_date - user_events['date'].max()).days,
'level_progress_7d': recent['level'].max() - previous['level'].max(),
'social_actions_7d': recent[recent['event'].isin(['chat', 'guild', 'friend'])].shape[0],
}
3. 매출 예측
총 매출 = DAU x Paying Rate x ARPPU
또는:
총 매출 = SUM(세그먼트별 유저 수 x 세그먼트별 ARPPU)
4. 밸런스 분석
게임 내 난이도, 경제 시스템의 균형을 데이터로 분석한다.
난이도 곡선 분석:
-- 스테이지별 클리어율, 시도 횟수, 이탈률
SELECT
stage_id,
COUNT(DISTINCT user_id) AS attempt_users,
SUM(CASE WHEN is_clear = 1 THEN 1 ELSE 0 END) AS clear_count,
ROUND(
SUM(CASE WHEN is_clear = 1 THEN 1.0 ELSE 0 END)
/ COUNT(DISTINCT user_id) * 100, 1
) AS clear_rate_pct,
ROUND(AVG(attempt_count), 1) AS avg_attempts,
-- 이 스테이지에서 최종 이탈한 유저 비율
ROUND(
SUM(CASE WHEN is_last_stage = 1 THEN 1.0 ELSE 0 END)
/ COUNT(DISTINCT user_id) * 100, 1
) AS churn_rate_pct
FROM stage_results
WHERE created_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY stage_id
ORDER BY stage_id;
경제 시스템 모니터링:
| 지표 |
설명 |
위험 신호 |
| 재화 생성량 |
일일 총 재화 유입 |
급증 = 익스플로잇 |
| 재화 소비량 |
일일 총 재화 소모 |
급감 = 콘텐츠 부족 |
| 재화 잔고 분포 |
유저별 보유 재화 |
양극화 = 경제 불균형 |
| 인플레이션율 |
거래소 평균 가격 변동 |
급등 = 재화 과잉 |
| Gini 계수 |
재화 분배 불균형 |
> 0.7 = 심각한 불균형 |
5. A/B 테스트 (라이브옵스)
from scipy import stats
def ab_test_analysis(control: pd.DataFrame,
treatment: pd.DataFrame,
metric: str,
alpha: float = 0.05) -> dict:
"""게임 A/B 테스트 분석
Args:
control: 대조군 데이터
treatment: 실험군 데이터
metric: 분석 대상 메트릭 (예: 'revenue', 'retention_d7')
"""
control_vals = control[metric].dropna()
treatment_vals = treatment[metric].dropna()
# Mann-Whitney U (비모수, 게임 데이터는 비정규 분포가 많음)
stat, p_value = stats.mannwhitneyu(
control_vals, treatment_vals, alternative='two-sided'
)
# 효과 크기
control_mean = control_vals.mean()
treatment_mean = treatment_vals.mean()
lift = (treatment_mean - control_mean) / control_mean * 100
return {
"control_n": len(control_vals),
"treatment_n": len(treatment_vals),
"control_mean": control_mean,
"treatment_mean": treatment_mean,
"lift_pct": lift,
"p_value": p_value,
"significant": p_value < alpha,
"recommendation": "adopt" if p_value < alpha and lift > 0 else "reject",
}
6. 소셜/길드 네트워크 분석
| 분석 |
방법 |
인사이트 |
| 길드 영향력 |
PageRank, Betweenness |
핵심 유저 식별 |
| 커뮤니티 탐지 |
Louvain, Label Propagation |
자연 그룹 발견 |
| 확산 분석 |
이벤트 참여 전파 |
바이럴 효과 측정 |
| 이탈 전파 |
길드원 이탈 영향 |
핵심 유저 이탈 시 연쇄 이탈 예측 |
이벤트 트래킹 설계
이벤트 스키마
{
"event_name": "stage_clear",
"timestamp": "2026-03-25T14:30:00+09:00",
"user_id": "user_12345",
"session_id": "sess_abc",
"device_id": "dev_xyz",
"properties": {
"stage_id": 150,
"attempt_count": 3,
"clear_time_sec": 45,
"score": 15000,
"stars": 3,
"items_used": ["boost_speed", "extra_life"],
"remaining_hp": 50
},
"user_properties": {
"level": 25,
"vip_tier": "gold",
"days_since_install": 14,
"total_revenue": 29000,
"country": "KR"
}
}
필수 이벤트 목록
| 카테고리 |
이벤트 |
필수 속성 |
| 세션 |
session_start, session_end |
device, platform, version |
| 진행 |
stage_start, stage_clear, stage_fail |
stage_id, result, duration |
| 경제 |
earn_currency, spend_currency |
currency_type, amount, source |
| 결제 |
purchase_start, purchase_complete |
product_id, price, currency |
| 소셜 |
guild_join, guild_leave, chat |
guild_id, channel |
| 시스템 |
tutorial_step, level_up, unlock |
step_id, new_level |
| 광고 |
ad_request, ad_show, ad_click |
ad_type, placement, network |
이벤트 트래킹 도구
| 도구 |
특징 |
가격 |
적합한 규모 |
| Firebase Analytics |
무료, Google 생태계 |
무료 |
소규모-중규모 |
| Amplitude |
분석 기능 강력 |
Free tier + 유료 |
중규모-대규모 |
| Mixpanel |
이벤트 분석 특화 |
Free tier + 유료 |
중규모 |
| 자체 구축 |
완전 커스텀 |
인프라 비용 |
대규모 |
유입 분석
어트리뷰션
| 모델