60 lines
2.3 KiB
Python
60 lines
2.3 KiB
Python
"""H5 검증 — 학습 검증 하네스 (PoC 본체).
|
|
|
|
핵심 판정(계획서 G): 학습형(qtable_ucb)이 random/static 대비 성과 우상향.
|
|
- 평균보상 우위(95%CI 분리) + '좋은 카드' 적중 우위 → 학습 루프 유효.
|
|
- 시뮬레이터 결정론(동일 seed 재현).
|
|
- 멀티테넌트 분리 실행(--tenant).
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from eval_harness.buyer import HeuristicBuyer, Scenario, make_card_effectiveness
|
|
from eval_harness.runner import run
|
|
from eval_harness.simulator import run_episode
|
|
from negotiation.qtable.domain.model.q_table import QTable
|
|
from negotiation.policies.qtable_policy import UCBQTablePolicy
|
|
from tenancy.config import RewardConfig, StateConfig
|
|
|
|
|
|
def test_simulator_deterministic():
|
|
eff = make_card_effectiveness(9, seed=1)
|
|
scn = Scenario(anchor_price=800, target_price=1000)
|
|
sc, rc = StateConfig(), RewardConfig()
|
|
|
|
def one():
|
|
b = HeuristicBuyer(eff, seed=7)
|
|
p = UCBQTablePolicy(QTable(sc.state_space_size, 9))
|
|
return run_episode(p, b, scn, sc, rc, 9, learn=False).total_reward
|
|
|
|
assert one() == one() # 동일 seed → 동일 결과
|
|
|
|
|
|
def test_card_effectiveness_has_good_cards():
|
|
eff = make_card_effectiveness(9, seed=42, n_good=3)
|
|
good = [a for a, e in eff.items() if e >= 0.7]
|
|
assert len(good) >= 3 # 효과 좋은 카드 존재 → 학습 대상 신호
|
|
|
|
|
|
@pytest.mark.parametrize("tenant", ["ktcommerce", "imarketkorea"])
|
|
def test_learning_beats_baseline(tenant):
|
|
report = run("configs/exp_default.yaml", tenant)
|
|
pols = report["policies"]
|
|
q = pols["qtable_ucb"]
|
|
rnd = pols["random"]
|
|
|
|
# 평균보상 우위 + 95%CI 비중첩
|
|
assert q["mean_reward"] > rnd["mean_reward"]
|
|
assert q["mean_reward"] - q["reward_ci95"] > rnd["mean_reward"] + rnd["reward_ci95"]
|
|
# 좋은 카드 적중 우위 (학습으로 카드 우열 파악)
|
|
assert q["good_card_hit_rate"] >= rnd["good_card_hit_rate"] + 0.2
|
|
assert q["good_card_hit_rate"] >= 0.7
|
|
# 종합 판정
|
|
assert report["verdict"]["pass"] is True
|
|
|
|
|
|
def test_static_does_not_learn():
|
|
report = run("configs/exp_default.yaml", "ktcommerce")
|
|
static = report["policies"]["static"]
|
|
# 정적 정책은 항상 고정 카드 → 좋은카드 적중 학습 없음(우연 일치만)
|
|
assert static["good_card_hit_rate"] <= report["policies"]["qtable_ucb"]["good_card_hit_rate"]
|