File size: 2,210 Bytes
599f4e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
"""
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