feat(weights): shadow chronos/lgbm 예측 + ensemble_weights 자동 보정
- ensemble.predict() 가 chronos_raw / lgbm_raw 를 함께 반환
- predict_and_store() 가 매 호출마다 3종 행 적재:
model='ensemble' (user_triggered=인자)
model='chronos' (user_triggered=FALSE, shadow)
model='lgbm' (user_triggered=FALSE, shadow)
- retrain_weekly.adjust_weights(): 최근 30일 prediction_outcomes 의
chronos vs lgbm hit_rate 로 ensemble_weights upsert
w_chronos = clamp(0.1, hr_c/(hr_c+hr_l), 0.9), w_lgbm = 1 - w_chronos
모델별 표본 < 10 이면 기본값(0.6/0.4) 유지
- API 응답에 saved_shadow_ids 추가 (TS 타입도 동기화)
- README: 동작 모델 메모 섹션을 실제 구현과 일치하도록 갱신
리뷰어 지적 3번 (ensemble_weights 가 영원히 갱신 안됨, upsert_weights 미호출) 해결.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -19,7 +19,7 @@ Chronos 도 실패하면 LGBM 단독으로 진행.
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
import numpy as np
|
||||
|
||||
@@ -53,6 +53,10 @@ class EnsemblePrediction:
|
||||
horizons: list[int]
|
||||
steps: list[EnsembleStep]
|
||||
sources_used: list[str]
|
||||
# shadow 저장용 원본 출력 (predict_one.py 가 ensemble + chronos 단독 + lgbm 단독
|
||||
# 3 종을 predictions 에 적재해서 retrain_weekly 가 모델별 hit_rate 비교 가능하게 함).
|
||||
chronos_raw: ChronosForecast | None = None
|
||||
lgbm_raw: dict[int, LgbmForecast] = field(default_factory=dict)
|
||||
|
||||
|
||||
def _chronos_direction(samples: list[list[float]], base_close: float, horizon: int) -> tuple[float, float, float]:
|
||||
@@ -90,12 +94,14 @@ def predict(code: str, *, horizons: tuple[int, ...] = (1, 3, 5)) -> EnsemblePred
|
||||
logger.warning("chronos forecast failed for %s: %s", code, exc)
|
||||
|
||||
steps: list[EnsembleStep] = []
|
||||
lgbm_raw: dict[int, LgbmForecast] = {}
|
||||
for h in horizons:
|
||||
lf: LgbmForecast | None = None
|
||||
try:
|
||||
lf = lgbm_predict(code, h)
|
||||
if lf is not None:
|
||||
sources_used.append(f"lgbm_h{h}")
|
||||
lgbm_raw[h] = lf
|
||||
except Exception as exc: # noqa: BLE001
|
||||
logger.warning("lgbm predict failed for %s h=%d: %s", code, h, exc)
|
||||
|
||||
@@ -171,4 +177,6 @@ def predict(code: str, *, horizons: tuple[int, ...] = (1, 3, 5)) -> EnsemblePred
|
||||
horizons=list(horizons),
|
||||
steps=steps,
|
||||
sources_used=sources_used,
|
||||
chronos_raw=cf,
|
||||
lgbm_raw=lgbm_raw,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user