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:
32
main.py
32
main.py
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user