""" Narrative framing detection. Identifikasi angle/frame yang digunakan media dalam meliput suatu berita. """ from typing import List, Dict import re # Frame categories berdasarkan teori framing media FRAME_PATTERNS: Dict[str, List[str]] = { "conflict": ["konflik", "versus", "lawan", "sengketa", "pertentangan", "tuduh", "serang", "bantah", "polemik", "debat", "perang"], "human_interest": ["korban", "keluarga", "anak", "ibu", "kisah", "cerita", "perjuangan", "nasib", "derita", "harapan hidup"], "economic": ["rupiah", "inflasi", "harga", "ekonomi", "bisnis", "investasi", "saham", "anggaran", "pajak", "untung", "rugi", "pasar"], "morality": ["etika", "moral", "haram", "halal", "dosa", "adil", "korupsi", "integritas", "tanggung jawab", "amanah"], "attribution": ["pemerintah", "presiden", "menteri", "DPR", "partai", "kebijakan", "regulasi", "aturan", "instruksi", "perintah"], "solution": ["solusi", "program", "langkah", "upaya", "strategi", "inovasi", "rencana", "pembangunan", "perbaikan", "reformasi"], "sensational": ["viral", "heboh", "gempar", "terungkap", "rahasia", "skandal", "mencengangkan", "bikin", "wow", "ternyata"], } def detect_framing(text: str) -> Dict: text_lower = text.lower() scores = {} for frame, keywords in FRAME_PATTERNS.items(): hits = sum(1 for kw in keywords if kw in text_lower) scores[frame] = hits total = sum(scores.values()) if total == 0: return {"frames": {k: 0.0 for k in FRAME_PATTERNS}, "dominant_frame": "neutral", "score": 0.0} normalized = {k: round(v / total, 3) for k, v in scores.items()} dominant = max(scores, key=scores.get) return { "frames": normalized, "dominant_frame": dominant, "score": round(scores[dominant] / total, 3), } def analyze_batch(items: List) -> List[Dict]: results = [] for item in items: framing = detect_framing(item.text) results.append({"id": item.id, **framing}) return results