Spaces:
Running
Running
| """ | |
| Emotion detection granular. | |
| Deteksi emosi: anger, fear, joy, sadness, surprise, disgust, trust, anticipation. | |
| """ | |
| from typing import List, Dict | |
| import re | |
| # Lexicon emosi Bahasa Indonesia (extensible) | |
| EMOTION_LEXICON: Dict[str, List[str]] = { | |
| "anger": ["marah", "murka", "geram", "berang", "emosi", "kesal", "jengkel", "protes", "demo", "kecam", "tolak", "rusuh", "amuk"], | |
| "fear": ["takut", "khawatir", "cemas", "panik", "ancaman", "bahaya", "waspada", "darurat", "teror", "ngeri", "was-was", "resah"], | |
| "joy": ["senang", "gembira", "bahagia", "sukses", "juara", "menang", "prestasi", "bangga", "puas", "optimis", "harapan", "selebrasi"], | |
| "sadness": ["sedih", "duka", "meninggal", "tewas", "korban", "tragis", "pilu", "menderita", "kehilangan", "bela sungkawa", "nestapa"], | |
| "surprise": ["kejutan", "mendadak", "tiba-tiba", "mengejutkan", "tak terduga", "heboh", "viral", "gempar", "terungkap", "ternyata"], | |
| "disgust": ["jijik", "muak", "korupsi", "skandal", "busuk", "curang", "manipulasi", "penipuan", "menjijikkan", "tercela"], | |
| "trust": ["percaya", "yakin", "aman", "terpercaya", "jaminan", "komitmen", "konsisten", "transparan", "akuntabel", "integritas"], | |
| "anticipation": ["harap", "rencana", "siap", "target", "proyeksi", "prediksi", "antisipasi", "agenda", "akan", "berencana"], | |
| } | |
| def detect_emotions(text: str) -> Dict[str, float]: | |
| text_lower = text.lower() | |
| tokens = re.findall(r'\b\w+\b', text_lower) | |
| token_set = set(tokens) | |
| total_tokens = max(len(tokens), 1) | |
| scores = {} | |
| for emotion, keywords in EMOTION_LEXICON.items(): | |
| hits = sum(1 for kw in keywords if kw in text_lower or kw in token_set) | |
| scores[emotion] = round(hits / total_tokens * 10, 3) # normalized | |
| return scores | |
| def analyze_batch(items: List) -> List[Dict]: | |
| results = [] | |
| for item in items: | |
| scores = detect_emotions(item.text) | |
| dominant = max(scores, key=scores.get) if any(v > 0 for v in scores.values()) else "neutral" | |
| results.append({ | |
| "id": item.id, | |
| "emotions": scores, | |
| "dominant_emotion": dominant, | |
| "dominant_score": scores.get(dominant, 0), | |
| }) | |
| return results | |