untracked files on main: dceb101 feat(#63): IMP-34 R1 donor capacity measured bound (u1+u2)

This commit is contained in:
2026-05-21 22:07:41 +09:00
commit 8f085a28d3
3220 changed files with 985495 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
"""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}**<br>정답 = 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}")