Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -305,12 +305,36 @@ def detect_negation(text):
|
|
| 305 |
return True
|
| 306 |
return False
|
| 307 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
def detect_mixed_emotions(text, prosodic_features):
|
| 309 |
"""
|
| 310 |
Advanced mixed emotion detection using text and audio features
|
|
|
|
| 311 |
"""
|
| 312 |
text_lower = text.lower()
|
| 313 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 314 |
mixed_indicators = [
|
| 315 |
'कभी', 'कभी कभी', 'sometimes',
|
| 316 |
'लेकिन', 'पर', 'मगर', 'but', 'however',
|
|
@@ -319,24 +343,27 @@ def detect_mixed_emotions(text, prosodic_features):
|
|
| 319 |
'शायद', 'maybe', 'perhaps'
|
| 320 |
]
|
| 321 |
|
| 322 |
-
positive_words = ['खुश', 'प्यार', 'अच्छा', 'बढ़िया', 'मज़ा', 'happy', 'love', 'good', 'nice']
|
| 323 |
-
negative_words = ['दुख', 'रो', 'गुस्सा', 'बुरा', 'परेशान', 'sad', 'cry', 'angry', 'bad', 'upset']
|
| 324 |
|
| 325 |
has_mixed_indicators = any(ind in text_lower for ind in mixed_indicators)
|
| 326 |
has_positive = any(word in text_lower for word in positive_words)
|
| 327 |
has_negative = any(word in text_lower for word in negative_words)
|
| 328 |
|
| 329 |
-
|
| 330 |
-
|
|
|
|
| 331 |
|
| 332 |
-
|
| 333 |
-
|
|
|
|
| 334 |
|
| 335 |
return text_mixed or audio_mixed
|
| 336 |
|
| 337 |
def enhanced_sentiment_analysis(text, prosodic_features, raw_results):
|
| 338 |
"""
|
| 339 |
Enhanced sentiment analysis combining text and prosodic features
|
|
|
|
| 340 |
"""
|
| 341 |
sentiment_scores = {}
|
| 342 |
|
|
@@ -365,34 +392,44 @@ def enhanced_sentiment_analysis(text, prosodic_features, raw_results):
|
|
| 365 |
|
| 366 |
initial_confidence = max(sentiment_scores.values())
|
| 367 |
|
| 368 |
-
#
|
| 369 |
-
|
| 370 |
-
if
|
| 371 |
-
print("
|
| 372 |
-
|
| 373 |
-
sentiment_scores['
|
| 374 |
-
sentiment_scores['
|
| 375 |
-
|
| 376 |
-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
|
| 380 |
-
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
if
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
sentiment_scores['
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 396 |
|
| 397 |
# Normalize
|
| 398 |
total = sum(sentiment_scores.values())
|
|
|
|
| 305 |
return True
|
| 306 |
return False
|
| 307 |
|
| 308 |
+
def detect_crisis_keywords(text):
|
| 309 |
+
"""
|
| 310 |
+
Detect crisis/emergency keywords that indicate strong negative emotion
|
| 311 |
+
"""
|
| 312 |
+
crisis_keywords = [
|
| 313 |
+
'बचाओ', 'मदद', 'help', 'save', # Distress calls
|
| 314 |
+
'मार', 'पीट', 'हिंसा', 'beat', 'hit', 'violence', # Violence
|
| 315 |
+
'डर', 'खतरा', 'fear', 'danger', # Fear/danger
|
| 316 |
+
'मर', 'मौत', 'death', 'die', # Death
|
| 317 |
+
'छोड़', 'leave me', 'stop' # Desperate pleas
|
| 318 |
+
]
|
| 319 |
+
|
| 320 |
+
text_lower = text.lower()
|
| 321 |
+
for keyword in crisis_keywords:
|
| 322 |
+
if keyword in text_lower:
|
| 323 |
+
return True
|
| 324 |
+
return False
|
| 325 |
+
|
| 326 |
def detect_mixed_emotions(text, prosodic_features):
|
| 327 |
"""
|
| 328 |
Advanced mixed emotion detection using text and audio features
|
| 329 |
+
CRITICAL: Don't mark crisis/distress as mixed emotions
|
| 330 |
"""
|
| 331 |
text_lower = text.lower()
|
| 332 |
|
| 333 |
+
# FIRST: Check if this is a crisis situation (never mixed)
|
| 334 |
+
if detect_crisis_keywords(text):
|
| 335 |
+
print("⚠️ Crisis keywords detected - NOT treating as mixed emotion")
|
| 336 |
+
return False
|
| 337 |
+
|
| 338 |
mixed_indicators = [
|
| 339 |
'कभी', 'कभी कभी', 'sometimes',
|
| 340 |
'लेकिन', 'पर', 'मगर', 'but', 'however',
|
|
|
|
| 343 |
'शायद', 'maybe', 'perhaps'
|
| 344 |
]
|
| 345 |
|
| 346 |
+
positive_words = ['खुश', 'प्यार', 'अच्छा', 'बढ़िया', 'मज़ा', 'happy', 'love', 'good', 'nice', 'सुंदर', 'प्रसन्न']
|
| 347 |
+
negative_words = ['दुख', 'रो', 'गुस्सा', 'बुरा', 'परेशान', 'sad', 'cry', 'angry', 'bad', 'upset', 'निराश', 'चिंता']
|
| 348 |
|
| 349 |
has_mixed_indicators = any(ind in text_lower for ind in mixed_indicators)
|
| 350 |
has_positive = any(word in text_lower for word in positive_words)
|
| 351 |
has_negative = any(word in text_lower for word in negative_words)
|
| 352 |
|
| 353 |
+
# Only prosodic if both high pitch AND high energy variation
|
| 354 |
+
high_pitch_variation = prosodic_features['pitch_std'] > 35
|
| 355 |
+
high_energy_variation = prosodic_features['energy_std'] > 0.08
|
| 356 |
|
| 357 |
+
# Text must have BOTH opposing emotions to be truly mixed
|
| 358 |
+
text_mixed = has_mixed_indicators and (has_positive and has_negative)
|
| 359 |
+
audio_mixed = high_pitch_variation and high_energy_variation and (has_positive and has_negative)
|
| 360 |
|
| 361 |
return text_mixed or audio_mixed
|
| 362 |
|
| 363 |
def enhanced_sentiment_analysis(text, prosodic_features, raw_results):
|
| 364 |
"""
|
| 365 |
Enhanced sentiment analysis combining text and prosodic features
|
| 366 |
+
CRITICAL: Properly handle crisis/distress situations
|
| 367 |
"""
|
| 368 |
sentiment_scores = {}
|
| 369 |
|
|
|
|
| 392 |
|
| 393 |
initial_confidence = max(sentiment_scores.values())
|
| 394 |
|
| 395 |
+
# CRITICAL: Check for crisis keywords first
|
| 396 |
+
is_crisis = detect_crisis_keywords(text)
|
| 397 |
+
if is_crisis:
|
| 398 |
+
print("🚨 CRISIS DETECTED - Strongly amplifying negative sentiment")
|
| 399 |
+
# Heavily boost negative sentiment for crisis situations
|
| 400 |
+
sentiment_scores['Negative'] = min(0.95, sentiment_scores['Negative'] * 1.8)
|
| 401 |
+
sentiment_scores['Neutral'] = max(0.02, sentiment_scores['Neutral'] * 0.2)
|
| 402 |
+
sentiment_scores['Positive'] = max(0.01, sentiment_scores['Positive'] * 0.1)
|
| 403 |
+
is_mixed = False # Crisis is NEVER mixed emotion
|
| 404 |
+
else:
|
| 405 |
+
# Negation detection (only for non-crisis)
|
| 406 |
+
has_negation = detect_negation(text)
|
| 407 |
+
if has_negation:
|
| 408 |
+
print("🔄 Negation detected - adjusting sentiment")
|
| 409 |
+
temp = sentiment_scores['Positive']
|
| 410 |
+
sentiment_scores['Positive'] = sentiment_scores['Negative']
|
| 411 |
+
sentiment_scores['Negative'] = temp
|
| 412 |
+
|
| 413 |
+
# Mixed emotions (only for non-crisis)
|
| 414 |
+
is_mixed = detect_mixed_emotions(text, prosodic_features)
|
| 415 |
+
if is_mixed:
|
| 416 |
+
print("🔄 Mixed emotions detected - boosting neutral")
|
| 417 |
+
neutral_boost = 0.20 # Reduced from 0.25
|
| 418 |
+
sentiment_scores['Neutral'] = min(0.65, sentiment_scores['Neutral'] + neutral_boost)
|
| 419 |
+
sentiment_scores['Positive'] = max(0.1, sentiment_scores['Positive'] - neutral_boost/2)
|
| 420 |
+
sentiment_scores['Negative'] = max(0.1, sentiment_scores['Negative'] - neutral_boost/2)
|
| 421 |
+
|
| 422 |
+
# Prosodic adjustments (only for non-crisis)
|
| 423 |
+
if prosodic_features['pitch_std'] > 45 and prosodic_features['energy_mean'] > 0.12:
|
| 424 |
+
print("🎵 Strong emotional prosody detected")
|
| 425 |
+
if sentiment_scores['Positive'] > sentiment_scores['Negative']:
|
| 426 |
+
sentiment_scores['Positive'] = min(0.9, sentiment_scores['Positive'] * 1.2)
|
| 427 |
+
else:
|
| 428 |
+
sentiment_scores['Negative'] = min(0.9, sentiment_scores['Negative'] * 1.2)
|
| 429 |
+
sentiment_scores['Neutral'] = max(0.05, sentiment_scores['Neutral'] * 0.8)
|
| 430 |
+
elif prosodic_features['energy_mean'] < 0.03 and prosodic_features['pitch_std'] < 15:
|
| 431 |
+
print("🎵 Calm/neutral prosody detected")
|
| 432 |
+
sentiment_scores['Neutral'] = min(0.8, sentiment_scores['Neutral'] * 1.2)
|
| 433 |
|
| 434 |
# Normalize
|
| 435 |
total = sum(sentiment_scores.values())
|