한국은행 동태예측모형 · BOKDPM · 교육용
모형이 무엇인지, 눈에 안 보이는 변수를 어떻게 다루는지, 그리고 베이지언 추정과 MCMC가 무엇인지 — 처음 보는 분도 따라올 수 있게 쉽게 설명합니다.
BOKDPM(Bank of Korea Dynamic Projection Model)은 경제 전체를 방정식으로 엮은 지도입니다. 물가·성장·금리·환율·고용·대출이 서로 어떻게 밀고 당기는지를 70개 방정식으로 표현합니다.
핵심 아이디어는 갭(gap)입니다 — 각 변수가 "장기 정상수준(추세)에서 얼마나 벗어나 있나"로 움직임을 봅니다. 예컨대 산출갭(실제 GDP − 잠재 GDP)이 크면 물가가 오르고, 중앙은행이 금리를 올립니다.
경제의 많은 것은 직접 관측되지 않습니다. "잠재 GDP(추세)", "중립 금리", "자연 실업률", "기대인플레이션" 같은 것은 통계표에 없죠. 이런 잠재변수(숨은 상태)를 다루는 틀이 상태공간(state-space)입니다. (반면 산출갭은 이 모형에서 HP필터로 미리 계산해 데이터로 넣으므로 관측변수 20개에 포함됩니다 — 잠재변수가 아닙니다.)
예를 들어 관찰방정식은 이렇게 생겼습니다:
이 모형의 실제 측정식은 UNR_kor = UNR_kor_BAR + UNR_kor_GAP입니다. 왼쪽은 관측변수 하나(실업률), 오른쪽은 둘 다 잠재상태(자연실업률·실업갭)입니다. 우리는 왼쪽만 보고, 칼만필터가 오른쪽 두 상태를 데이터에 맞게 갈라냅니다.
파라미터(계수·충격 크기)를 정하는 방식이 베이지언 추정입니다. 한 문장으로:
0 기각(유의성). 사후분포의 신용구간이 0을 포함하지 않으면 "그 계수는 0이 아니다(유의하다)"고 판단합니다. 우리 결과는 20개 계수·34개 충격이 모두 0을 기각했습니다.
사전분포와 사후분포가 같은 분포족이면 "켤레(conjugate)"라 부릅니다. 이때는 복잡한 적분 없이 간단한 갱신 규칙만으로 사후가 나옵니다 — 다른 문제에도 그대로 응용됩니다.
| 데이터(우도) | 켤레 사전 | 사후 | 갱신 규칙 | 대표 응용 |
|---|---|---|---|---|
| 이항·베르누이 (0/1, 성공·실패) | 베타 Beta(α,β) | Beta(α+성공, β+실패) | 성공·실패 수를 더함 | 비율·확률(전환율·부도율) |
| 포아송 (건수) | 감마 Gamma(a,b) | Gamma(a+Σy, b+n) | 건수합·관측수를 더함 | 사고·도착·불량 건수 |
| 정규 (평균, 분산 알려짐) | 정규 Normal(m,τ²) | 정규 (정밀도 가중평균) | 사전·데이터 정밀도로 가중 | 연속지표 평균 |
| 정규 (평균·분산 둘 다 미지) | 정규–역감마 (NIG) | 정규–역감마 | 평균·분산 동시 갱신 | 회귀계수 + 오차분산 |
※ 흔한 오해: 이항(binary)의 켤레는 감마가 아니라 베타입니다. 감마는 포아송(건수)의 켤레입니다. "정규–감마"는 정규 우도의 정밀도(1/분산)에 감마를 쓰는 형태로, 분산에 역감마를 쓰는 것과 짝을 이룹니다.
x가 y에 주는 영향은 회귀 기울기 계수 b입니다(y = a + b·x + 오차). "약/중/강" 같은 정성적 감을 b의 사전분포로 바꾸고, 실제 (x, y)를 관측해 사후분포를 만듭니다 — 정규–정규 켤레입니다.
판정. 사후 신용구간이 0을 제외하면 "x가 y에 영향 있다(유의)", 구간 위치로 약/중/강을 읽습니다. 예: 사전 '중' N(0.3, 0.2) + 데이터 b̂=0.5·SE=0.15 → 사후 N(0.43, 0.12), 95% [0.19, 0.66] → 0 제외 → 유의(중~강). (분산도 미지면 정규–역감마로 b·분산을 동시에 추정.)
"강/중/약"을 분포로 바꾸는 것은 측정이 아니라 명시적 규칙에 따른 번역입니다. 정당성은 규칙이 공개·재현·검증 가능하다는 데 있습니다. 두 축으로 번역합니다: 강도→중심(평균), 확신도→폭(표준편차).
| 정성 강도 | 중심 μ₀ (표준화 기울기) | 확신도 | 폭 σ₀ | 95% 신용구간 |
|---|---|---|---|---|
| 영향 없음 | 0.0 | — | 0.10 | [−0.20, 0.20] |
| 약 | 0.1 | 보통 | 0.15 | [−0.20, 0.40] |
| 중 | 0.3 | 보통 | 0.15 | [0.00, 0.60] |
| 강 | 0.6 | 보통 | 0.15 | [0.30, 0.90] |
| 중(매우 확신) | 0.3 | 강 | 0.05 | [0.20, 0.40] |
| 중(반신반의) | 0.3 | 약 | 0.40 | [−0.50, 1.10] |
정당화 3원칙. ① 표준화로 단위에서 자유로운 공통 척도 위에서 관례(0.1약·0.3중·0.5+강)를 적용 · ② 답할 수 있는 질문("b가 0.4~0.8일 것"·"양(+)일 확률 95%")으로 폭을 역산 · ③ 선행연구 앵커링 + 민감도 분석으로 자의성 통제. 데이터가 충분하면 사전은 씻겨나가므로, 사전이 결정적인 것은 데이터가 약할 때뿐입니다.
문제가 하나 있습니다: 사후분포의 공식을 직접 구할 수 없습니다(변수가 많고 복잡). 그래서 공식 대신 사후분포에서 표본을 아주 많이 뽑아 그 모양을 그립니다. 이것이 MCMC(마르코프체인 몬테카를로)입니다.
채택률(acceptance ratio)은 제안이 받아들여지는 비율입니다. 너무 높아도(안 움직임) 낮아도(다 거절) 안 좋고 0.23~0.4가 이상적입니다 — 우리 추정은 25.6 / 25.8%로 건강했습니다. 안정성은 번인(burn-in)으로 초기 표본을 버리고, 여러 체인을 비교해 확인합니다(우리: 2체인 × 30,000, 번인 30%).
Dynare에서 실제로 추정을 실행하는 한 줄입니다:
| 옵션 | 뜻 |
|---|---|
datafile=BOKDPM_data_2025 | 관측 데이터 파일(20변수) |
nobs=104 | 관측치 104분기(2000Q1–2025Q4) 사용 |
diffuse_filter | 확산 칼만필터 — 추세(비정상·단위근) 변수의 초기 상태를 무정보로 처리(로그GDP·물가 등 때문) |
mode_compute=5 | 사후 최빈값(mode) 탐색 알고리즘 5번(newrat) — MH 시작점·초기 제안분산(헤시안) 산출 |
mh_replic=30000 | 체인당 MH 표집 3만 회 |
mh_nblocks=2 | 독립 체인 2개(서로 다른 시작점) — 수렴 진단용 |
mh_jscale=0.3 | 제안분포 점프 크기 — 채택률 조절(0.23~0.4 겨냥). 우리 결과 25.6/25.8% |
mh_drop=0.3 | 각 체인 앞 30% 번인 폐기 → 3만 중 9천 버리고 2.1만 사용(체인당) |
요약: 104분기 데이터를 확산 칼만필터로 우도 계산 → 최빈값 탐색 후 → 2체인×3만 MH 표집(점프 0.3), 앞 30% 버림 → 체인당 2.1만·총 4.2만 사후표본.
전 과정은 로컬 JupyterLab에서 세 노트북으로 재현됩니다: 데이터입수 → 모형추정 → 기준선 전망·시나리오.
bokdpm_pipeline에 정리돼 있어, 팀원이 각자 PC에서 Restart & Run All 하면 같은 결과가 나옵니다. 실제로 재추정을 다시 돌려 계수·충격이 완전히 일치함을 확인했고(상관 1.0), 관측 20변수 중 17개는 ECOS/FRED에서 값까지 완전 재현, GE(통합재정 901Y013/B01)·유가(두바이 POILDUBUSDM)도 라이브 출처로 정확히 재현됩니다.