HH/docs/EMOTION_ANALYSIS.md

9.5 KiB

Emotion Analysis Implementation

Overview

The AI service now performs emotion analysis on complaints, identifying the primary emotion (Anger, Sadness, Confusion, Fear, or Neutral) with an intensity score (0.0 to 1.0) and confidence score (0.0 to 1.0). This helps staff better understand the emotional state of patients and prioritize responses accordingly.

Changes Made

1. AI Service (apps/core/ai_service.py)

New Method: analyze_emotion

Analyzes text to identify the primary emotion and its intensity.

Input:

  • text: Text to analyze (supports both English and Arabic)

Output:

{
    'emotion': 'anger' | 'sadness' | 'confusion' | 'fear' | 'neutral',
    'intensity': float,  # 0.0 to 1.0 (how strong the emotion is)
    'confidence': float  # 0.0 to 1.0 (how confident AI is)
}

Emotion Categories:

  • anger: Strong feelings of displeasure, hostility, or rage
  • sadness: Feelings of sorrow, grief, or unhappiness
  • confusion: Lack of understanding, bewilderment, or uncertainty
  • fear: Feelings of anxiety, worry, or being afraid
  • neutral: No strong emotion detected

Features:

  • Bilingual support (English and Arabic)
  • Input validation for intensity and confidence scores
  • Automatic clamping to valid range (0.0 to 1.0)
  • Detailed logging for debugging

2. Complaint Tasks (apps/complaints/tasks.py)

Updated analyze_complaint_with_ai Task:

Now performs both standard AI analysis AND emotion analysis:

# Analyze complaint using AI service
analysis = AIService.analyze_complaint(...)

# Analyze emotion using AI service
emotion_analysis = AIService.analyze_emotion(text=complaint.description)

Metadata Storage: Emotion analysis is stored in complaint metadata:

complaint.metadata['ai_analysis'] = {
    # ... other fields ...
    'emotion': emotion_analysis.get('emotion', 'neutral'),
    'emotion_intensity': emotion_analysis.get('intensity', 0.0),
    'emotion_confidence': emotion_analysis.get('confidence', 0.0),
}

Timeline Update: Emotion is included in the bilingual AI analysis timeline message:

AI analysis complete: Severity=high, Priority=medium, Category=Quality of Care,
Department=Nursing, Emotion=anger (Intensity: 0.85)

اكتمل تحليل الذكاء الاصطناعي: الشدة=high, الأولوية=medium, الفئة=Quality of Care,
القسم=Nursing, العاطفة=anger (الشدة: 0.85)

3. Complaint Model (apps/complaints/models.py)

Added Properties:

  • emotion - Primary emotion (anger/sadness/confusion/fear/neutral)
  • emotion_intensity - Intensity score (0.0 to 1.0)
  • emotion_confidence - Confidence score (0.0 to 1.0)
  • get_emotion_display - Human-readable emotion name
  • get_emotion_badge_class - Bootstrap badge class for emotion

Usage Example:

complaint = Complaint.objects.get(id=some_id)

# Get emotion data
emotion = complaint.emotion  # 'anger'
intensity = complaint.emotion_intensity  # 0.85
confidence = complaint.emotion_confidence  # 0.92

# Get display values
display_name = complaint.get_emotion_display  # 'Anger'
badge_class = complaint.get_emotion_badge_class  # 'danger'

Badge Color Mapping:

  • Anger → danger (red)
  • Sadness → primary (blue)
  • Confusion → warning (yellow)
  • Fear → info (cyan)
  • Neutral → secondary (gray)

4. Complaint Detail Template (templates/complaints/complaint_detail.html)

New Section: Emotion Analysis

Added to the AI Analysis section in the Details tab:

<div class="mb-3">
    <div class="info-label">Emotion Analysis</div>
    <div class="card">
        <div class="card-body">
            <!-- Emotion Badge -->
            <span class="badge bg-danger">
                <i class="bi bi-emoji-frown"></i> Anger
            </span>

            <!-- Confidence -->
            <small class="text-muted">Confidence: 92%</small>

            <!-- Intensity Progress Bar -->
            <div class="progress">
                <div class="progress-bar bg-danger" style="width: 85%"></div>
            </div>
            <small>Intensity: 0.85 / 1.0</small>
        </div>
    </div>
</div>

Visual Features:

  • Color-coded badge based on emotion type
  • Progress bar showing intensity (0.0 to 1.0)
  • Confidence percentage display
  • Gradient background card design

Usage

Accessing Emotion Data in Code

from apps.complaints.models import Complaint

# Get a complaint
complaint = Complaint.objects.get(id=complaint_id)

# Check if emotion analysis exists
if complaint.emotion:
    print(f"Primary emotion: {complaint.get_emotion_display}")
    print(f"Intensity: {complaint.emotion_intensity:.2f}")
    print(f"Confidence: {complaint.emotion_confidence:.2f}")

    # Check for high-intensity anger (may need escalation)
    if complaint.emotion == 'anger' and complaint.emotion_intensity > 0.8:
        print("⚠️ High-intensity anger detected - consider escalation")

Accessing Raw Metadata

ai_analysis = complaint.metadata.get('ai_analysis', {})

if ai_analysis:
    emotion = ai_analysis.get('emotion', 'neutral')
    intensity = ai_analysis.get('emotion_intensity', 0.0)
    confidence = ai_analysis.get('emotion_confidence', 0.0)

Displaying in Templates

<!-- Basic display -->
<div>Emotion: {{ complaint.get_emotion_display }}</div>
<div>Intensity: {{ complaint.emotion_intensity|floatformat:2 }}</div>
<div>Confidence: {{ complaint.emotion_confidence|floatformat:2 }}</div>

<!-- With badge -->
<span class="badge bg-{{ complaint.get_emotion_badge_class }}">
    {{ complaint.get_emotion_display }}
</span>

<!-- Progress bar -->
<div class="progress">
    <div class="progress-bar bg-{{ complaint.get_emotion_badge_class }}"
         style="width: {{ complaint.emotion_intensity|mul:100 }}%">
    </div>
</div>

Use Cases

1. Prioritization

High-intensity anger complaints can be prioritized:

# Get high-intensity anger complaints
urgent_complaints = Complaint.objects.filter(
    metadata__ai_analysis__emotion='anger',
    metadata__ai_analysis__emotion_intensity__gte=0.7
).order_by('-metadata__ai_analysis__emotion_intensity')

2. Automatic Escalation

Trigger escalation for high-intensity emotions:

if complaint.emotion == 'anger' and complaint.emotion_intensity > 0.8:
    escalate_complaint_auto.delay(str(complaint.id))

3. Staff Assignment

Assign complaints with negative emotions to more experienced staff:

if complaint.emotion in ['anger', 'fear']:
    # Assign to senior staff
    complaint.assigned_to = get_senior_staff_member()

4. Analytics

Track emotion trends over time:

from collections import Counter

# Get emotion distribution
complaints = Complaint.objects.filter(
    created_at__gte=start_date
)

emotion_counts = Counter([
    c.emotion for c in complaints if c.emotion
])

# Result: {'anger': 15, 'sadness': 8, 'confusion': 12, 'fear': 5, 'neutral': 20}

Emotion Examples

Emotion Example Text Intensity Badge
Anger "This is unacceptable! I demand to speak to management!" 0.9 🔴 Danger
Sadness "I'm very disappointed with the care my father received" 0.7 🔵 Primary
Confusion "I don't understand what happened, can you explain?" 0.5 🟡 Warning
Fear "I'm worried about the side effects of this medication" 0.6 🔵 Info
Neutral "I would like to report a minor issue" 0.2 Secondary

Testing

To test emotion analysis:

from apps.core.ai_service import AIService

# Test English text
result = AIService.analyze_emotion(
    "This is unacceptable! I demand to speak to management!"
)
print(result)
# Output: {'emotion': 'anger', 'intensity': 0.9, 'confidence': 0.95}

# Test Arabic text
result = AIService.analyze_emotion(
    "أنا قلق جداً من الآثار الجانبية لهذا الدواء"
)
print(result)
# Output: {'emotion': 'fear', 'intensity': 0.7, 'confidence': 0.88}

Benefits

  1. Better Understanding: Identifies specific emotions instead of generic sentiment
  2. Intensity Tracking: Shows how strong the emotion is (helps prioritize)
  3. Bilingual Support: Works with both English and Arabic complaints
  4. Visual Feedback: Easy-to-read badges and progress bars
  5. Actionable: High-intensity emotions can trigger automatic responses
  6. Confidence Scoring: Knows how reliable the analysis is

Future Enhancements

Possible future improvements:

  1. Add emotion trend tracking for patients
  2. Create dashboard visualizations for emotion statistics
  3. Add more emotion categories (frustration, joy, surprise)
  4. Emotion-based routing to specialized staff
  5. Patient emotion profiles over time
  6. Integration with CRM systems

API Reference

AIService.analyze_emotion(text)

Parameters:

  • text (str): Text to analyze

Returns:

  • dict: Emotion analysis with keys:
    • emotion (str): Primary emotion category
    • intensity (float): Emotion strength (0.0 to 1.0)
    • confidence (float): AI confidence (0.0 to 1.0)

Raises:

  • AIServiceError: If API call fails

Complaint.emotion (property)

Returns:

  • str: Primary emotion code

Complaint.emotion_intensity (property)

Returns:

  • float: Emotion intensity (0.0 to 1.0)

Complaint.emotion_confidence (property)

Returns:

  • float: AI confidence in emotion detection (0.0 to 1.0)

Complaint.get_emotion_display (property)

Returns:

  • str: Human-readable emotion name

Complaint.get_emotion_badge_class (property)

Returns:

  • str: Bootstrap badge class for emotion