A comprehensive framework for detecting and analyzing human emotional states using the valence-arousal model.
This module provides tools for detecting and tracking emotional states in text, voice, or other input modalities. It uses the well-established valence-arousal model from psychological research, where:
- Valence represents the positivity or negativity of an emotion (ranging from -1.0 to 1.0)
- Arousal represents the intensity or activation level of an emotion (ranging from -1.0 to 1.0)
The model can optionally incorporate a third dimension, dominance, which represents the feeling of control (ranging from -1.0 to 1.0).
- Text-based emotion detection with a built-in emotion lexicon
- Voice feature analysis for emotional state detection
- Historical tracking of emotional states
- Detection of emotional shifts and trends
- Statistical analysis of emotional trajectories
- Visualization tools for emotional states and trajectories
- Serialization support for saving and loading emotional data
pip install -r requirements.txtfrom emotion_detection import AffectDetector
# Create an instance of the affect detector
detector = AffectDetector()
# Analyze text for emotional content
emotion_state = detector.analyze_text("I'm feeling really happy and excited today!")
print(f"Valence: {emotion_state.valence:.2f}, Arousal: {emotion_state.arousal:.2f}")
print(f"Emotional quadrant: {emotion_state.get_quadrant()}")
# Analyze multiple inputs over time
detector.analyze_text("I'm a bit nervous about the presentation.")
detector.analyze_text("The feedback was terrible, I'm so frustrated!")
detector.analyze_text("After some reflection, I'm feeling more calm now.")
# Get a summary of the emotional trajectory
summary = detector.get_emotional_summary()
print(f"Dominant emotion: {summary['dominant_quadrant']}")
print(f"Valence trend: {summary['trends']['valence']:.2f}")
print(f"Arousal trend: {summary['trends']['arousal']:.2f}")import matplotlib.pyplot as plt
from emotion_detection import utils
from emotion_detection.emotion_model import EmotionState
# Visualize a single emotional state
state = EmotionState(valence=0.7, arousal=0.5)
fig = utils.plot_emotion_state(state, title="Current Emotional State")
plt.show()
# Visualize an emotional trajectory
# (using the detector from the previous example)
states = detector.emotion_model.states
fig = utils.plot_emotion_trajectory(states, title="Emotional Journey")
plt.show()The valence-arousal model divides emotions into four quadrants:
- Happy/Excited (positive valence, positive arousal): joy, excitement, elation
- Relaxed/Content (positive valence, negative arousal): calm, peaceful, satisfied
- Angry/Anxious (negative valence, positive arousal): anger, fear, stress
- Sad/Depressed (negative valence, negative arousal): sadness, depression, boredom
This dimensional approach allows for continuous representation of emotions rather than discrete categories, making it suitable for tracking subtle emotional changes over time.
Represents a single emotional state at a point in time:
from emotion_detection.emotion_model import EmotionState
# Create a basic emotional state (happy/excited quadrant)
state = EmotionState(
valence=0.8, # Positive valence
arousal=0.6, # Moderate arousal
dominance=0.5, # Optional dominance dimension
source="text", # Source of the detection
confidence=0.85 # Confidence in the detection
)
# Get the quadrant
quadrant = state.get_quadrant() # Returns "happy"Tracks emotional states over time and provides analytical capabilities:
from emotion_detection.emotion_model import ValenceArousalModel, EmotionState
# Create a model
model = ValenceArousalModel(window_size=20)
# Add states
model.add_state(EmotionState(valence=0.7, arousal=0.5))
model.add_state(EmotionState(valence=0.5, arousal=0.3))
model.add_state(EmotionState(valence=0.2, arousal=0.1))
# Analyze trends
valence_trend, arousal_trend = model.get_trend()
print(f"Valence trend: {valence_trend:.2f}, Arousal trend: {arousal_trend:.2f}")
# Detect significant shifts
has_shifted = model.detect_emotional_shift(threshold=0.3)
# Get a comprehensive summary
summary = model.get_emotional_summary()The main interface for detecting and analyzing emotions:
from emotion_detection import AffectDetector
detector = AffectDetector()
# Text analysis
state = detector.analyze_text("I'm so excited about this project!")
# Voice analysis
state = detector.analyze_voice(
pitch=0.7, # Normalized pitch (high)
volume=0.8, # Normalized volume (loud)
speech_rate=0.6 # Normalized speech rate (fast)
)
# Get the current emotional state (weighted average of recent observations)
current = detector.get_current_emotional_state()
# Estimate overall sentiment
sentiment, confidence = detector.estimate_user_sentiment()
print(f"User sentiment: {sentiment} (confidence: {confidence:.2f})")You can provide your own emotion lexicon file:
detector = AffectDetector(lexicon_path="path/to/my_lexicon.csv")The lexicon file should be a CSV with format: word,valence,arousal[,dominance]
The framework can be extended to support other input modalities by creating additional analysis methods that produce EmotionState objects.
MIT License
This module is based on psychological research on the dimensional theory of emotions, particularly the valence-arousal model proposed by James Russell and others.