feat(lotto): evaluate_weekly 학습 신호를 forward lift로 승격

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-31 17:33:27 +09:00
parent 8e7b4adabd
commit 03056a4747
2 changed files with 36 additions and 0 deletions

View File

@@ -294,6 +294,35 @@ def evaluate_weekly() -> Dict[str, Any]:
winner = max(per_day, key=lambda d: d["avg_score"])
# 자가학습 강화: backtest forward 등수점수 lift로 winner 재선정
latest_no = latest["drw_no"]
runs = db.get_backtest_runs(draw_no=latest_no)
engine_runs = [r for r in runs if r["strategy"] == "engine_w"]
null_runs = [r for r in runs if r["strategy"] == "random_null"]
if engine_runs and null_runs:
random_score = prize_score_from_hist(null_runs[0])
per_w = []
for r in engine_runs:
per_w.append({
"trial_id": r["trial_id"],
"day_of_week": int(r["weight_label"][1:]) if r["weight_label"].startswith("w") else 0,
"weight": json.loads(r["weight_json"]) if r["weight_json"] else DEFAULT_UNIFORM[:],
"prize_score": prize_score_from_hist(r),
})
lift_winner = select_winner_by_lift(per_w, random_score=random_score)
if not lift_winner["gated"]:
winner = {
"trial_id": lift_winner["trial_id"],
"day_of_week": lift_winner["day_of_week"],
"weight": lift_winner["weight"],
"avg_score": winner["avg_score"],
"max_correct": winner["max_correct"],
"lift": lift_winner["lift"],
}
else:
# 노이즈 → base 유지 강제 (max_correct를 0으로 낮춰 unchanged 유도)
winner = {**winner, "max_correct": min(winner["max_correct"], 2), "lift": lift_winner["lift"]}
current_base = db.get_current_base()
new_base, reason = decide_base_update(
winner_max_correct=winner["max_correct"],

View File

@@ -135,3 +135,10 @@ def test_select_winner_by_lift_gating():
winner2 = we.select_winner_by_lift(per_w, random_score=3.0, epsilon=2.0)
assert winner2["gated"] is False
assert winner2["trial_id"] == 2 # prize 9 → lift +6
def test_prize_score_from_hist():
# 등수 가중치: 1등 매우 큼, 하위는 작게
s = we.prize_score_from_hist({"m3": 10, "m4": 2, "m5": 0, "m6": 0, "bonus_hits": 0})
s_big = we.prize_score_from_hist({"m3": 0, "m4": 0, "m5": 0, "m6": 1, "bonus_hits": 0})
assert s_big > s # 1등 1장이 5등 다수보다 큼