"""Phase 6 — 4개 유닛 × 7개 방법 통합표 가로 7개: 키워드 3 (TF-IDF, Char, Kiwi+BM25) + 구조 1 + 의미 3 (청킹+sbert, 청킹+E5, Cross) 데이터 소스: - Phase 2 MD: 키워드 3 + 구조 + SBERT-청크 (청킹+sbert) - Phase 4 MD: E5-청크 (청킹+E5), Cross-원본 (Cross) """ import re from pathlib import Path HERE = Path(__file__).parent TARGET_UNITS = [ ("6", "1. (MDX 1) 팝업 — DX와 BIM의 구분", "18"), ("12", "2. (MDX 2) 2.2 DX 시행 주체별 기대효과", "14"), ("13", "3. (MDX 03) 1. DX 시행을 위한 필수요건 — 기술·사람·자연", "13"), ("14", "4. (MDX 03) 2. Process 혁신과 Product 변화", "29"), ] # (소스 파일, 소스 방법명, 표시 이름) METHOD_MAP = [ ("phase2", "TF-IDF", "TF-IDF"), ("phase2", "Char-ngram", "Char 3-gram"), ("phase2", "Kiwi+BM25", "Kiwi+BM25"), ("phase2", "Structural", "구조 메타"), ("phase2", "SBERT-청크", "청킹+sbert"), ("phase4", "E5-청크", "청킹+E5"), ("phase4", "Cross-원본", "Cross"), ] def load_unit_blocks(md_name): md = (HERE / md_name).read_text(encoding="utf-8") parts = re.split(r"\n## (\d+)\. ", md) return {parts[i]: parts[i + 1] for i in range(1, len(parts), 2)} blocks_p2 = load_unit_blocks("MATRIX_PHASE2.md") blocks_p4 = load_unit_blocks("MATRIX_PHASE4.md") def extract_top3(block_text, method_name): for line in block_text.split("\n"): if line.startswith(f"| {method_name} |"): cells = line.split(" | ") if len(cells) >= 4: return [c.strip().rstrip("|").strip() for c in cells[1:4]] return ["-", "-", "-"] def mark_correct(cell, correct_id): if f"**{correct_id}**" in cell: return "⭐ " + cell return cell def get_top3(source, method, unit_num): blocks = blocks_p2 if source == "phase2" else blocks_p4 block = blocks.get(unit_num, "") return extract_top3(block, method) # 리포트 조립 lines = [] lines.append("# Phase 6 — 4개 유닛 × 7개 방법 통합표") lines.append("") lines.append("**콘텐츠 4개:**") for _, display_name, correct_id in TARGET_UNITS: lines.append(f"- {display_name} (정답 Frame **{correct_id}**)") lines.append("") lines.append("**방법 7개**: 키워드 3 + 구조 1 + 의미 3 (청킹+sbert / 청킹+E5 / Cross)") lines.append("") lines.append("정답 프레임은 ⭐ 표시") lines.append("") header = ["콘텐츠"] + [m[2] for m in METHOD_MAP] lines.append("| " + " | ".join(header) + " |") lines.append("|" + "|".join(["------"] * len(header)) + "|") for num, display_name, correct_id in TARGET_UNITS: method_tops = {} for source, src_name, disp in METHOD_MAP: method_tops[disp] = get_top3(source, src_name, num) header_cell = f"**{display_name}**
정답 = Frame **{correct_id}**" lines.append(f"| {header_cell} | " + " | ".join([""] * len(METHOD_MAP)) + " |") for rank_idx, rank_label in enumerate(["**1순위**", "**2순위**", "**3순위**"]): row = [rank_label] for _, _, disp in METHOD_MAP: cell = method_tops[disp][rank_idx] row.append(mark_correct(cell, correct_id)) lines.append("| " + " | ".join(row) + " |") lines.append("") lines.append("---") lines.append("") lines.append("## 방법별 1순위 정답 집계") lines.append("") lines.append("| 방법 | MDX1 팝업(18) | MDX2 2.2(14) | MDX03-1(13) | MDX03-2(29) | 정답 합계 |") lines.append("|------|---------------|--------------|-------------|-------------|----------|") for source, src_name, disp in METHOD_MAP: results = [] for num, _, correct_id in TARGET_UNITS: top3 = get_top3(source, src_name, num) top1 = top3[0] results.append(f"**{correct_id}**" in top1) marks = ["✓" if r else "✗" for r in results] score = sum(results) lines.append(f"| {disp} | {marks[0]} | {marks[1]} | {marks[2]} | {marks[3]} | **{score}/4** |") out_path = HERE / "MATRIX_PHASE6.md" out_path.write_text("\n".join(lines), encoding="utf-8") print(f"완료: {out_path}") # 검증 출력 print("\n=== 검증: 각 유닛 1순위 ===") for num, display_name, correct_id in TARGET_UNITS: print(f"\n[{display_name}] 정답={correct_id}") for source, src_name, disp in METHOD_MAP: top3 = get_top3(source, src_name, num) m = re.search(r"\*\*(\d{2})\*\*", top3[0]) fid = m.group(1) if m else "-" mark = "✓" if fid == correct_id else "✗" print(f" {disp:15s} (src={source}/{src_name}) → {fid} {mark}")