"""키워드 전체 리포트: MDX 유닛별 + Figma 프레임별 + 매칭 공통 키워드""" import sys import math import json from collections import Counter from pathlib import Path sys.path.insert(0, str(Path(__file__).parent)) from common import load_figma_texts, tokenize_simple from extract_units import extract_units ROOT = Path(r"d:\ad-hoc\kei\design_agent") PREVIEW_DIR = ROOT / "data" / "figma_previews" UNIT_ORDER = [ ("MDX01-intro", "중목차 앞 본문"), ("MDX01-intro-details", "팝업"), ("MDX01-1", "중목차 - 1. 용어 정의"), ("MDX01-2", "중목차 - 2. 용어간 상호관계"), ("MDX01-2-image", "이미지"), ("MDX01-2-details", "팝업+표"), ("MDX02-1", "중목차 - 1. DX의 궁극적 목표"), ("MDX02-1-image", "이미지"), ("MDX02-2", "중목차(컨테이너)"), ("MDX02-2.1", "소목차 - 2.1 업무 수행 과정 변화"), ("MDX02-2.2", "소목차 - 2.2 주체별 기대효과"), ("MDX02-2.2-table", "표"), ("MDX03-1", "중목차 - 1. 필수 요건"), ("MDX03-2", "중목차(컨테이너)"), ("MDX03-2.1", "소목차 - 2.1 과정의 혁신"), ("MDX03-2.1-table", "표"), ("MDX03-2.2", "소목차 - 2.2 결과의 변화"), ] def main(): # 전체 corpus 준비 units = extract_units() figma = load_figma_texts() all_docs = {} for uid, text in units.items(): all_docs[f"MDX:{uid}"] = tokenize_simple(text) for fid, text in figma.items(): all_docs[f"FIG:{fid}"] = tokenize_simple(text) # IDF 계산 df = Counter() for toks in all_docs.values(): for w in set(toks): df[w] += 1 N = len(all_docs) idf = {w: math.log(N / c) for w, c in df.items()} with open(PREVIEW_DIR / "index.json", encoding="utf-8") as f: idx_data = json.load(f) frame_to_short = {info["frame_id"]: sid for sid, info in idx_data.items()} # 각 문서별 "희귀 단어 TOP N" — IDF 높은 단어만 def top_rare_words(tokens, n=15, min_idf=1.5): # 중복 제거한 단어 중 IDF 높은 순 unique = set(tokens) ranked = sorted( [(w, idf[w], df[w]) for w in unique if w in idf and idf[w] >= min_idf], key=lambda x: -x[1], ) return ranked[:n] # 매칭 (IDF-Sum 방식) def idf_sum(query_tokens, doc_tokens): q = set(query_tokens) d = set(doc_tokens) common = q & d return sum(idf.get(w, 0) for w in common), common # 리포트 생성 lines = [] lines.append("# 키워드 전체 리포트 (MDX + Figma + 매칭)") lines.append("") lines.append(f"전체 corpus: MDX {len(units)}개 유닛 + Figma {len(figma)}개 프레임 = **{N}개 문서**") lines.append(f"IDF 기준 희귀 단어(IDF ≥ 1.5)만 표시") lines.append("") lines.append("> IDF가 클수록 희귀한 단어 (해당 단어가 등장하는 문서 수가 적음).") lines.append("> IDF = log(전체 문서 수 / 단어 등장 문서 수)") lines.append("") # ═══ 1부: MDX 유닛별 키워드 ═══ lines.append("## 1부. MDX 유닛별 핵심 키워드") lines.append("") for uid, kind in UNIT_ORDER: if uid not in units: continue tokens = tokenize_simple(units[uid]) top = top_rare_words(tokens, n=15) lines.append(f"### {uid} — {kind}") lines.append("") if top: words = [f"**{w}**(IDF={s:.1f})" for w, s, _ in top] lines.append("- " + " · ".join(words)) else: lines.append("- _(희귀 단어 없음 또는 텍스트 없음)_") lines.append("") # ═══ 2부: Figma 프레임별 키워드 ═══ lines.append("---") lines.append("") lines.append("## 2부. Figma 프레임별 핵심 키워드") lines.append("") for short_id in sorted(idx_data.keys()): info = idx_data[short_id] fid = info["frame_id"] title = info.get("title_text", "").strip() or "_(제목없음)_" if fid not in figma: continue tokens = tokenize_simple(figma[fid]) top = top_rare_words(tokens, n=15) lines.append(f"### {short_id}. {title[:40]}") lines.append("") if top: words = [f"**{w}**({s:.1f})" for w, s, _ in top] lines.append("- " + " · ".join(words)) else: lines.append("- _(희귀 단어 없음)_") lines.append("") # ═══ 3부: MDX ↔ Figma 매칭 공통 키워드 ═══ lines.append("---") lines.append("") lines.append("## 3부. MDX ↔ Figma Top-5 매칭 + 공통 키워드") lines.append("") lines.append("각 MDX 유닛에 대해 IDF 합 기준 Top-5 매칭 프레임과 **공통 희귀 단어** 표시.") lines.append("") for uid, kind in UNIT_ORDER: if uid not in units: continue q_tokens = tokenize_simple(units[uid]) # Top-5 프레임 매칭 frame_scores = [] for fid, text in figma.items(): d_tokens = tokenize_simple(text) score, common = idf_sum(q_tokens, d_tokens) frame_scores.append((fid, score, common)) frame_scores.sort(key=lambda x: -x[1]) lines.append(f"### {uid} — {kind}") lines.append("") lines.append("| 순위 | 프레임 | IDF 합 | 공통 희귀 키워드 (IDF ≥ 1.5) |") lines.append("|:---:|:---:|:---:|-----|") for rank, (fid, score, common) in enumerate(frame_scores[:5], 1): short = frame_to_short.get(str(fid), "?") # 공통 단어 중 IDF ≥ 1.5인 것만, IDF 높은 순 rare_common = sorted( [(w, idf[w]) for w in common if w in idf and idf[w] >= 1.5], key=lambda x: -x[1], )[:12] words_str = " · ".join(f"{w}({s:.1f})" for w, s in rare_common) if rare_common else "-" lines.append(f"| {rank} | **{short}** | {score:.1f} | {words_str} |") lines.append("") out_path = Path(__file__).parent / "KEYWORD_REPORT.md" out_path.write_text("\n".join(lines), encoding="utf-8") print(f"완료: {out_path}") if __name__ == "__main__": main()