Monte Carlo 시뮬레이션으로 리스크와 민감도 분석하기
입력 분포와 상관구조를 반영해 Monte Carlo 시뮬레이션으로 리스크 지표와 Sobol 민감도를 산출하고 수렴·재현성을 관리하는 방법
2026-08-14 · 최초 발행 2024-04-29
입력 불확실성을 결과 분포로 바꾸는 방법
Monte Carlo Simulation(MCS)은 불확실한 입력을 확률분포로 모델링한 뒤 반복 샘플링으로 출력 분포를 근사하는 통계적 시뮬레이션 기법이다. 추정량의 표준오차는 O(1/√N)로 수렴한다.
리스크 분석에서는 출력 분포에서 평균, 표준편차, Value at Risk(VaR), Conditional VaR(CVaR), P95/P99 같은 신뢰구간과 극단위험 지표를 계산한다. 민감도 분석은 각 입력 변수가 결과 변동성에 얼마나 기여하는지, 변수 간 상호작용은 어떤지를 분해하는 절차다. 전역 민감도에는 Sobol 지수, 변수 선별에는 Morris 스크리닝을 적용할 수 있다.
분포·상관·표본 설계가 결과를 좌우한다
입력 변수에는 정규, 로그정규, 삼각, 베타, 감마, 경험적(ECDF) 분포를 적용할 수 있다. 분포를 고를 때는 데이터 적합도(GoF)와 비즈니스 제약을 함께 검증해야 한다. 변수 사이의 관계는 공분산, 스피어만 상관, 코퓰라로 표현하며, 시료 변환(ICDF)과 순위 보존 방식을 사용한다.
표본을 만드는 방식도 수렴에 영향을 준다. 단순 난수 외에 라틴 하이퍼큐브(LHS), 준난수(Sobol/Halton)를 비교할 수 있으며, 같은 시료 수에서 수렴 향상을 기대할 수 있다. 공통 난수(CRN), 반대수(Antithetic), 제어변수(Control variates)는 추정량 분산을 줄이는 데 쓴다.
모델 실행은 결정론적 모델 f(x)를 반복 평가하는 구조다. 반복 계산 비용은 캐시와 메모이제이션으로 낮출 수 있고, 처리량은 GPU·멀티코어 병렬화와 벡터화로 높일 수 있다. 결과는 중심 경향과 꼬리위험을 함께 평가하고, VaR/CVaR 백테스트와 신뢰구간 산출을 포함해 집계한다. 시나리오 집합은 포트폴리오나 프로젝트 단위로 관리한다.
Sobol 지수는 1차 효과와 총효과를 통해 전역 민감도를 추정하며, 2차 이상의 상호작용 항도 탐지할 수 있다. 고차원 입력에서는 Morris 스크리닝으로 유의 변수를 먼저 선별할 수 있다.
샘플링부터 수렴 판정까지의 반복 루프
분포 파라미터(μ, σ, α, β 등), 상관 또는 코퓰라, 시료 수 N, 리스크·민감도 목표를 먼저 정한다. 이후 샘플링, 모델 평가, 결과 저장, 지표 산출, 수렴·오류 검사를 반복한다. 산출물은 요약 통계, VaR/CVaR, 민감도 지수, 신뢰구간, 보고서 또는 대시보드가 된다.
분포 파라미터 범위, 코퓰라의 양의 정부호성, 음수 불가 같은 모델 도메인 제약을 검증해야 한다. 수렴은 지표별 표준오차와 신뢰구간 폭, 러닝 평균·분산의 안정성, Sobol 반복 오차를 기준으로 판단한다.
재현성을 위해 시드를 관리하고 PRNG(PCG/MT/Philox)의 일관성을 유지한다. CRN을 쓴다면 적용 범위도 명시해야 한다.
위험과 의사결정이 만나는 지점
금융 포트폴리오에서는 수익률 분포를 추정하고 10일 99% VaR/CVaR를 산출하며, 스트레스 시나리오를 병행할 수 있다.
수요·재고 정책에서는 수요·리드타임 불확실성 하 재고정책(S,s)의 성과 분포를 평가하고 서비스레벨과 재고비용의 트레이드오프를 분석한다. 에너지·인프라 투자에서는 CAPEX/OPEX/가격 변동성을 반영해 NPV/IRR 분포를 추정하고, 민감도 지수로 가치 드라이버를 규명한다.
프로젝트 일정 리스크에는 활동기간 분포를 기반으로 PERT/CPM 시뮬레이션을 수행해 준공 일정 P80/P90을 추정하고 크리티컬 리스크를 식별할 수 있다.
수렴 성능과 운영 특성의 차이
| 기법 | 성능(수렴) | 확장성 | 일관성(재현성) | 안정성(분산/오류) | 운영 편의 |
|---|---|---|---|---|---|
| 단순 MC | 기준 수준, 느린 수렴 | 매우 높음 | 시드 관리 용이 | 분산 큼 | 구현 매우 간단 |
| LHS | 중간~빠름 | 높음 | 샘플 설계 고정 시 양호 | 층화로 분산 감소 | 약간의 설계 비용 |
| 준난수(Sobol) | 빠름 | 매우 높음 | 시드 개념 대신 점열 관리 | 고차원에서 효익 감소 가능 | 라이브러리 필요 |
| CRN(공통난수) | 비교 차이의 분산 감소 | 높음 | 실험 간 시드 동기화 필요 | 상관 설계 미흡 시 역효과 | 실험 설계 요구 |
준난수와 LHS는 모형에 따라 동일 정확도 대비 시료 수를 30~70% 절감할 수 있다. 표준오차 O(1/√N) 특성은 신뢰구간 관리에 활용할 수 있다. 꼬리위험을 가시화하고 민감도를 기준으로 우선순위를 세우면 의사결정 품질을 높일 수 있으며, 변수 기여도 분해는 이해관계자와의 커뮤니케이션에도 도움이 된다.
운영에서는 적응형 N 증분(배치 러닝)으로 CI 목표에 도달하면 조기 중단하는 방식을 사용할 수 있다. 준난수와 분산 감소 기법을 병용하는 선택지도 있다. 멀티코어·GPU 환경에서는 시드 스트림 분할과 상관구조 보존을 설계해야 하며, 통신 오버헤드와 스루풋 사이의 트레이드오프가 존재한다.
입력 분포의 적합·검증 로그, 버전 관리, 결과 재현 리포트 자동화도 필요하다. 블랙박스 모델을 사용하는 경우에는 민감도 분석으로 설명을 보강한다.
리스크 지표와 Sobol 분석 코드
전제조건
- Python 3.10+, numpy 1.26+, scipy 1.11+, (옵션) SALib 1.5+
- 실행 환경: 로컬/노트북, 단일 파일 실행 가정
리스크 지표를 추정하는 Monte Carlo 예시는 로그정규 수익률 모형을 사용한다.
import numpy as np
rng = np.random.default_rng(42)
N = 50000 # 샘플 수
# 예시 포트폴리오 수익률: 로그정규 모형 가정
mu, sigma = 0.05, 0.2
returns = rng.lognormal(mean=mu - 0.5*sigma**2, sigma=sigma, size=N) - 1.0
# 손실(음수 수익) 관점 변환
loss = -returns
# 지표 산출
mean_loss = float(loss.mean())
var_99 = float(np.quantile(loss, 0.99))
cvar_99 = float(loss[loss >= var_99].mean())
print({"mean_loss": mean_loss, "VaR_99": var_99, "CVaR_99": cvar_99})
아래 예시는 SALib를 이용해 전역 Sobol 민감도를 계산한다.
# pip install SALib
import numpy as np
from SALib.sample import saltelli
from SALib.analyze import sobol
# 문제 정의: 3개 변수, [0,1] 균등
problem = {
"num_vars": 3,
"names": ["x1", "x2", "x3"],
"bounds": [[0,1],[0,1],[0,1]],
}
# 샘플 생성(Saltelli: Sobol 기반)
param_values = saltelli.sample(problem, N=1024, calc_second_order=False, seed=7)
# 모델 정의: 예시 비선형 함수
def model(x):
x1, x2, x3 = x
return 2*x1 + x2**2 + 0.5*x1*x3
Y = np.array([model(row) for row in param_values])
# Sobol 분석
Si = sobol.analyze(problem, Y, calc_second_order=False, print_to_console=False)
print("S1:", dict(zip(problem["names"], Si["S1"])))
print("ST:", dict(zip(problem["names"], Si["ST"])))
입력 분포와 상관은 실제 데이터 적합 및 도메인 제약을 반영해야 한다. 수렴 여부는 N을 점증시키며 CI 폭을 모니터링해 확인한다. 준난수나 CRN을 사용할 때는 실험 비교 사이의 일관성을 유지하도록 설계한다.