# 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:**
```python
{
'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:
```python
# 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:
```python
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:**
```python
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:
```html
Emotion Analysis
Anger
Confidence: 92%
Intensity: 0.85 / 1.0
```
**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
```python
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
```python
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
```html
Emotion: {{ complaint.get_emotion_display }}
Intensity: {{ complaint.emotion_intensity|floatformat:2 }}
Confidence: {{ complaint.emotion_confidence|floatformat:2 }}
{{ complaint.get_emotion_display }}
```
## Use Cases
### 1. Prioritization
High-intensity anger complaints can be prioritized:
```python
# 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:
```python
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:
```python
if complaint.emotion in ['anger', 'fear']:
# Assign to senior staff
complaint.assigned_to = get_senior_staff_member()
```
### 4. Analytics
Track emotion trends over time:
```python
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:
```python
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