์ด๋ํ
[REFACTOR] ํ๋ฅด์๋ ๋ผ๋ฒจ ํค extra_intents โ expected_intents ๋ฆฌ๋ค์ด๋ฐ
d504def | from __future__ import annotations | |
| """ | |
| ๊ฒฐํฉ(bundle-v3) Intent ๋ถํฌ ์๋ฎฌ๋ ์ดํฐ (๋ก์ง ๊ณ ๋ํ์ฉ). | |
| ๊ฐ ํ๋ฅด์๋๊ฐ ์ค๋ฌธ(๋ํ ๋ต๋ณ)์ ์๋ตํ๊ณ ๋ํ ํ๋ ์ํ์ค๋ฅผ ์ํํ์ ๋, | |
| ๊ธฐ๋ intent(expected_intents)๊ฐ ์์ ๋ถํฌ์ ๋จ๋์ง ์ ์ํํด "๋ฉ๋ ๊ฐ๋ฅํ ๋ถํฌ"์ธ์ง ํ๊ฐํ๋ค. | |
| ์งํ: | |
| - cov@5 / cov@10 : expected_intents ์ค final top-5/top-10์ ๋ ๋น์จ | |
| - avg_rank : expected_intents์ ํ๊ท final ์์ (๋ฎ์์๋ก ์ข์) | |
| - ํ๋ฅด์๋๋ณ + ์ ์ฒด ํ๊ท | |
| ์คํ: python scripts/sim_bundle.py [--behavior] (--behavior: ๋ํ ํ๋ ์ํ์ค๊น์ง ๋ฐ์) | |
| """ | |
| import argparse | |
| import random | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).parent.parent)) | |
| from core.engines import config # noqa: E402 | |
| from core.extractor import get_extractor # noqa: E402 | |
| from core.inference import infer_batch, infer_with_behavior, to_topn_with_others # noqa: E402 | |
| from scripts.build_bundle_dataset import PERSONAS # noqa: E402 | |
| SID = "bundle-v3" | |
| def _sample_answers(answer_dist: dict, rng: random.Random) -> dict[str, str]: | |
| """answer_dist ๋ถํฌ์์ 1๋ช ์ ์๋ต์ ์ํ๋ง (์ค์ ์์ฐ์ ์๋ต์ ๋ชจ์ฌ).""" | |
| return {qid: rng.choices(list(d), weights=list(d.values()), k=1)[0] | |
| for qid, d in answer_dist.items()} | |
| def _behavior_map() -> dict[str, tuple[str, str]]: | |
| """behavior_id โ (event_type, entity). BACK/EXIT ํฌํจ.""" | |
| bc = config.get_behaviors(SID) | |
| m: dict[str, tuple[str, str]] = {} | |
| for b in bc["step1"]["behaviors"]: | |
| m[b["id"]] = (b["event_type"], b["entity"]) | |
| for items in bc["step2"]["by_parent"].values(): | |
| for b in items: | |
| m[b["id"]] = (b["event_type"], b["entity"]) | |
| for b in bc["step2"].get("common", []): | |
| m[b["id"]] = (b["event_type"], b["entity"]) | |
| m.setdefault("BACK", ("navigate_back", "back_to_step1")) | |
| m.setdefault("EXIT", ("app_exit", "session_end")) | |
| return m | |
| def _intent_names() -> dict[str, str]: | |
| return {i["id"]: i["name"] for i in config.get_taxonomy(SID)["intents"]} | |
| def _rank_of(scores: list, intent_id: str) -> int: | |
| """final ์์(1-๊ธฐ๋ฐ). ์์ผ๋ฉด 999.""" | |
| for s in scores: | |
| if s.intent_id == intent_id: | |
| return s.rank | |
| return 999 | |
| def run(use_behavior: bool, k: int = 40, seed: int = 7) -> None: | |
| """ํ๋ฅด์๋๋ง๋ค answer_dist์์ k๋ช ์ ์ํ๋งํด cov@5/10ยทavg_rank ํ๊ท (๋ถํฌ ์ถฉ์ค).""" | |
| bmap = _behavior_map() | |
| ext = get_extractor() | |
| rng = random.Random(seed) | |
| p_cov5, p_cov10, rank_all = [], [], [] | |
| for p in PERSONAS: | |
| expected = p["expected_intents"] | |
| c5s, c10s, rks = [], [], [] | |
| for j in range(k): | |
| answers = _sample_answers(p["answer_dist"], rng) | |
| if use_behavior: | |
| seq = rng.choice(p["action_seqs"]) | |
| sess = f"__sim__{p['id']}_{j}" | |
| ext.reset(sess) | |
| for bid in seq: | |
| et, ent = bmap.get(bid, (None, None)) | |
| if et: | |
| ext.add_event(sess, et, ent) | |
| _, scores = infer_with_behavior(answers, sess, SID) | |
| ext.reset(sess) | |
| else: | |
| _, scores = infer_batch(answers, SID) | |
| top_ids = [s.intent_id for s in sorted(scores, key=lambda s: s.final_score, reverse=True)] | |
| top5, top10 = set(top_ids[:5]), set(top_ids[:10]) | |
| c5s.append(sum(1 for e in expected if e in top5) / len(expected)) | |
| c10s.append(sum(1 for e in expected if e in top10) / len(expected)) | |
| rks.extend(_rank_of(scores, e) for e in expected) | |
| cov5, cov10 = sum(c5s) / k, sum(c10s) / k | |
| p_cov5.append(cov5); p_cov10.append(cov10); rank_all.extend(rks) | |
| print(f" {p['id']} {p['name'][:22]:22} cov@5={cov5:.2f} cov@10={cov10:.2f} " | |
| f"avg_rank={sum(rks)/len(rks):4.1f}") | |
| n = len(PERSONAS) | |
| print("=" * 64) | |
| print(f" ์ ์ฒด ํ๊ท cov@5={sum(p_cov5)/n:.3f} cov@10={sum(p_cov10)/n:.3f} " | |
| f"avg_rank={sum(rank_all)/len(rank_all):.1f} ({'ํ๋๋ฐ์' if use_behavior else '์ค๋ฌธ๋ง'}, k={k})") | |
| print("=" * 64) | |
| if __name__ == "__main__": | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--behavior", action="store_true", help="๋ํ ํ๋ ์ํ์ค๊น์ง ๋ฐ์") | |
| args = ap.parse_args() | |
| run(args.behavior) | |