feat(macro): comprehensive variable exploration, R²=0.028→0.747

- New: data/macro_analysis.py (15 base × 6 transforms = 116 candidates)
  - Top correlations: CORP_AA_LOGR(r=-0.75), credit spread, term spread
  - Exhaustive 3-var search (1749 combos), best adj.R²=0.71
- Modified: data/macro_data.py
  - Added GOVT_3Y, CORP_AA, CORP_BBB ECOS queries + fallback data
  - New: compute_derived_features() for optimal 3 predictors
- Modified: main.py
  - Computes derived features + passes combined input to stepwise
  - Scenario paths now include derived features for prediction
- Selected 3 variables: CORP_AA_LOGR, CPI_GROWTH, CREDIT_SPREAD_LAG1
- All 8/8 validation tests pass (incl. R² now Pass)
This commit is contained in:
Variet Agent
2026-03-11 06:55:02 +09:00
parent 8af743e6f3
commit 811d6ee843
3 changed files with 636 additions and 31 deletions

32
main.py
View File

@@ -38,7 +38,7 @@ from data.transition_matrices import (
load_transition_matrices, compute_ttc_matrix,
get_default_rates, display_matrix, RATING_GRADES
)
from data.macro_data import load_macro_data, _fallback_macro_data
from data.macro_data import load_macro_data, _fallback_macro_data, compute_derived_features
from models.credit_cycle import estimate_zt_series, estimate_rho_and_zt
from models.vasicek import conditional_pd, worst_case_pd
from models.macro_model import build_macro_zt_model
@@ -121,6 +121,12 @@ def main():
print(f" 변수: {', '.join(macro_data.columns)}")
print(macro_data.tail(5).to_string())
# 파생변수 계산 (회사채 로그수익률, 기간/신용스프레드)
derived_features = compute_derived_features(macro_data)
if not derived_features.empty:
print(f"\n 파생변수: {', '.join(derived_features.columns)}")
print(derived_features.tail(5).to_string())
# ================================================================
# 2. Belkin & Suchower Zt 추정
# ================================================================
@@ -152,7 +158,14 @@ def main():
print(" [3/7] 거시연계 회귀모형 (Zt ~ 거시변수)")
print("=" * 70)
macro_model = build_macro_zt_model(zt_dict, macro_data, method="stepwise_aic")
# 파생변수가 있으면 원본 + 파생 결합
if not derived_features.empty:
model_input = pd.concat([macro_data, derived_features], axis=1)
model_input = model_input.loc[:, ~model_input.columns.duplicated()]
else:
model_input = macro_data
macro_model = build_macro_zt_model(zt_dict, model_input, method="stepwise_aic")
print(f"\n 선택된 변수: {macro_model.selected_vars}")
print(macro_model.summary())
@@ -177,6 +190,21 @@ def main():
macro_data, base_year=2025, forecast_years=5
)
# 시나리오에 파생변수 추가 (history + forecast로 lag/diff 계산)
if not derived_features.empty:
for sname, sdf in macro_scenarios.items():
# history + forecast 결합하여 파생변수 계산
combined = pd.concat([macro_data, sdf])
combined = combined[~combined.index.duplicated(keep='last')]
combined = combined.sort_index()
feat = compute_derived_features(combined)
# forecast 연도만 추출 후 시나리오에 결합
forecast_years = sdf.index
feat_forecast = feat.loc[feat.index.intersection(forecast_years)]
if not feat_forecast.empty:
macro_scenarios[sname] = pd.concat([sdf, feat_forecast], axis=1)
macro_scenarios[sname] = macro_scenarios[sname].loc[:, ~macro_scenarios[sname].columns.duplicated()]
# Zt 경로 생성
z_paths = scenario_engine.generate_z_paths(
zt_dict, macro_model, macro_scenarios, base_year=2025