""" Opinion vs Fact classifier. Klasifikasi apakah artikel bersifat opini/editorial atau berita faktual. """ from typing import List, Dict import re OPINION_MARKERS = [ "menurut saya", "saya rasa", "seharusnya", "sebaiknya", "idealnya", "opini", "editorial", "kolom", "perspektif", "pandangan", "hemat saya", "saya pikir", "kita harus", "perlu diakui", "jelas bahwa", "tidak bisa dipungkiri", "menariknya", ] FACT_MARKERS = [ "berdasarkan data", "menurut", "kata", "ujar", "ungkap", "dilaporkan", "tercatat", "statistik", "survei", "rilis", "laporan", "konferensi pers", "siaran pers", "resmi", "diumumkan", "ditetapkan", "diresmikan", ] SUBJECTIVE_WORDS = [ "terbaik", "terburuk", "luar biasa", "mengecewakan", "menyedihkan", "mengesankan", "fantastis", "mengerikan", "sempurna", "parah", "indah", "jelek", "hebat", "bodoh", "cerdas", ] def classify(text: str) -> Dict: text_lower = text.lower() opinion_hits = sum(1 for m in OPINION_MARKERS if m in text_lower) fact_hits = sum(1 for m in FACT_MARKERS if m in text_lower) subjective_hits = sum(1 for w in SUBJECTIVE_WORDS if w in text_lower) opinion_score = opinion_hits * 3 + subjective_hits * 2 fact_score = fact_hits * 3 total = opinion_score + fact_score if total == 0: return {"classification": "unknown", "opinion_pct": 50, "fact_pct": 50, "confidence": 0} opinion_pct = round((opinion_score / total) * 100) fact_pct = 100 - opinion_pct if opinion_pct > 60: classification = "opinion" elif fact_pct > 60: classification = "fact" else: classification = "mixed" confidence = round(abs(opinion_pct - 50) / 50, 2) return { "classification": classification, "opinion_pct": opinion_pct, "fact_pct": fact_pct, "confidence": confidence, } def analyze_batch(items: List) -> List[Dict]: results = [] for item in items: result = classify(item.text) results.append({"id": item.id, **result}) return results