"대충 일주일?" 같은 감 추정은 이제 그만.
미 해군이 핵잠수함 프로젝트에 사용한 PERT 기법부터, 애자일 팀들이 사랑하는 플래닝 포커까지.
과학적 추정 방법을 알아봅시다.
PERT: 3점 추정의 마법
PERT(Program Evaluation and Review Technique)는 1950년대 미 해군이 폴라리스 미사일 프로젝트를 위해 개발했습니다. 2년을 단축시킨 비결이죠.
기본 공식
def pert_estimation(optimistic, realistic, pessimistic):
"""
O: 낙관적 (모든 게 완벽할 때)
R: 현실적 (보통의 경우)
P: 비관적 (모든 게 꼬일 때)
"""
# PERT 공식
expected = (O + 4*R + P) / 6
# 표준편차 (불확실성)
std_dev = (P - O) / 6
return {
"expected": expected,
"std_dev": std_dev,
"range_68%": (expected - std_dev, expected + std_dev),
"range_95%": (expected - 2*std_dev, expected + 2*std_dev)
}
# 실제 예시: 로그인 API 개발
result = pert_estimation(
optimistic=4, # 최선: 4시간
realistic=8, # 현실: 8시간
pessimistic=16 # 최악: 16시간
)
print(f"예상: {result['expected']:.1f}시간") # 8.7시간
print(f"68% 확률: {result['range_68%']}") # (6.7, 10.7)
print(f"95% 확률: {result['range_95%']}") # (4.7, 12.7)
왜 4를 곱할까? 정규분포에서 최빈값(mode)에 더 가중치를 주기 위해서입니다.
플래닝 포커: 집단지성의 힘
애자일 팀의 필수 도구입니다.
진행 방법
1. 모두가 카드를 준비 (1, 2, 3, 5, 8, 13, 21...)
2. 동시에 공개
3. 차이가 크면 토론
4. 합의 도출
피보나치를 쓰는 이유
fibonacci = [1, 2, 3, 5, 8, 13, 21, 34]
# 작업이 클수록 불확실성도 커진다
# 1과 2의 차이는 명확하지만
# 21과 34의 차이는 모호하다
심리학적 효과: 큰 숫자일수록 간격이 넓어져 과도한 정밀도를 피합니다.
몬테카를로 시뮬레이션
1000번 시뮬레이션으로 확률을 계산합니다.
import random
import numpy as np
def monte_carlo_simulation(tasks, iterations=1000):
"""프로젝트 완료 시간 시뮬레이션"""
results = []
for _ in range(iterations):
total_time = 0
for task in tasks:
# 각 작업의 실제 시간을 무작위로 선택
actual = random.triangular(
task['min'],
task['max'],
task['likely']
)
total_time += actual
results.append(total_time)
return {
"mean": np.mean(results),
"p50": np.percentile(results, 50), # 중간값
"p90": np.percentile(results, 90), # 90% 확률
"p95": np.percentile(results, 95) # 95% 확률
}
# 프로젝트 작업들
tasks = [
{"name": "설계", "min": 2, "likely": 3, "max": 5},
{"name": "개발", "min": 5, "likely": 8, "max": 15},
{"name": "테스트", "min": 2, "likely": 3, "max": 6}
]
result = monte_carlo_simulation(tasks)
print(f"50% 확률로 {result['p50']:.1f}일 내 완료")
print(f"90% 확률로 {result['p90']:.1f}일 내 완료")
벨로시티 기반 추정
과거 데이터를 활용한 추정입니다.
class VelocityEstimator:
def __init__(self, past_sprints):
self.velocities = past_sprints
def estimate(self, total_points):
avg_velocity = np.mean(self.velocities)
std_velocity = np.std(self.velocities)
sprints_needed = total_points / avg_velocity
return {
"expected_sprints": sprints_needed,
"optimistic": total_points / (avg_velocity + std_velocity),
"pessimistic": total_points / (avg_velocity - std_velocity)
}
# 지난 10개 스프린트 속도
past_velocities = [23, 28, 25, 30, 22, 27, 26, 24, 29, 26]
estimator = VelocityEstimator(past_velocities)
result = estimator.estimate(total_points=150)
print(f"예상: {result['expected_sprints']:.1f} 스프린트")
print(f"범위: {result['optimistic']:.1f} ~ {result['pessimistic']:.1f}")
와이드밴드 델파이
전문가 합의 기법입니다.
Round 1: 익명으로 추정 제출
├── 개발자A: 10일
├── 개발자B: 5일
├── 개발자C: 15일
└── 편차가 크네요
Round 2: 이유 공유 후 재추정
├── A: "DB 마이그레이션 고려하면..."
├── B: "아, 그걸 빼먹었네요"
├── C: "테스트 자동화도 포함인가요?"
└── 재추정: 8일, 9일, 10일
Round 3: 합의
└── 최종: 9일
실전 적용 가이드
작은 프로젝트 (1-2주)
- 추천: 플래닝 포커
- 이유: 빠르고 팀 합의 도출 용이
중간 프로젝트 (1-3개월)
- 추천: PERT + 벨로시티
- 이유: 적절한 정확도와 실용성
대규모 프로젝트 (3개월+)
- 추천: 몬테카를로 + 와이드밴드 델파이
- 이유: 높은 정확도 필요
추정 정확도 개선 팁
1. 참조 클래스 예측
# 비슷한 과거 프로젝트 찾기
similar_projects = [
{"name": "로그인 시스템 A", "estimated": 20, "actual": 35},
{"name": "로그인 시스템 B", "estimated": 15, "actual": 28},
{"name": "로그인 시스템 C", "estimated": 25, "actual": 40}
]
adjustment_factor = np.mean([p["actual"]/p["estimated"]
for p in similar_projects])
# 1.73배
new_estimate = raw_estimate * adjustment_factor
2. 추정 회고
## 스프린트 추정 회고
| 작업 | 추정 | 실제 | 차이 | 원인 |
|------|------|------|------|------|
| API 개발 | 8h | 12h | +4h | 인증 복잡도 |
| UI 구현 | 6h | 5h | -1h | 템플릿 재사용 |
| 테스트 | 4h | 8h | +4h | 엣지 케이스 |
**교훈**: 인증과 테스트는 1.5배 버퍼 필요
마무리: 추정은 과학이다
"감"으로 하는 추정의 시대는 끝났습니다.
PERT로 불확실성을 계산하고,
플래닝 포커로 집단지성을 활용하고,
몬테카를로로 확률을 시뮬레이션하세요.
기억하세요:
- 하나의 숫자가 아닌 범위로 추정
- 과거 데이터를 반드시 활용
- 팀 전체가 참여하는 추정
- 지속적인 추정 개선
정확한 추정은 신뢰를 만들고,
신뢰는 성공적인 프로젝트를 만듭니다.
과학적 추정과 프로젝트 관리가 필요하신가요? Plexo를 확인해보세요.
댓글 없음:
댓글 쓰기