Spaces:
Running
Running
CodeGovindz
commited on
Commit
·
af88b32
1
Parent(s):
3047859
Add calculate_day_score endpoint for emotion scoring
Browse files
app.py
CHANGED
|
@@ -937,3 +937,118 @@ def get_mental_health_details(email: str):
|
|
| 937 |
raise
|
| 938 |
except Exception as e:
|
| 939 |
raise HTTPException(status_code=500, detail=f"Error fetching mental health details: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 937 |
raise
|
| 938 |
except Exception as e:
|
| 939 |
raise HTTPException(status_code=500, detail=f"Error fetching mental health details: {str(e)}")
|
| 940 |
+
|
| 941 |
+
|
| 942 |
+
# =============================================================================
|
| 943 |
+
# DAILY EMOTION SCORE CALCULATION
|
| 944 |
+
# =============================================================================
|
| 945 |
+
|
| 946 |
+
# Valence Mapping for emotions
|
| 947 |
+
EMO_VALENCE = {
|
| 948 |
+
"Angry": -0.80,
|
| 949 |
+
"Disgust": -0.60,
|
| 950 |
+
"Fear": -0.70,
|
| 951 |
+
"Happy": 0.90,
|
| 952 |
+
"Sad": -0.90,
|
| 953 |
+
"Surprise": 0.20,
|
| 954 |
+
"Neutral": 0.0,
|
| 955 |
+
# text emotions
|
| 956 |
+
"sadness": -0.90,
|
| 957 |
+
"joy": 0.90,
|
| 958 |
+
"love": 0.80,
|
| 959 |
+
"anger": -0.80,
|
| 960 |
+
"fear": -0.70,
|
| 961 |
+
"surprise": 0.20
|
| 962 |
+
}
|
| 963 |
+
|
| 964 |
+
def valence_from_probabilities(probabilities: Dict[str, float]) -> float:
|
| 965 |
+
if not probabilities:
|
| 966 |
+
return 0.0
|
| 967 |
+
v = 0.0
|
| 968 |
+
total = sum(probabilities.values()) or 1.0
|
| 969 |
+
for emo, p in probabilities.items():
|
| 970 |
+
key = emo if emo in EMO_VALENCE else emo.capitalize()
|
| 971 |
+
v += p * EMO_VALENCE.get(key, 0.0)
|
| 972 |
+
return v / total
|
| 973 |
+
|
| 974 |
+
def valence_to_score(v: float) -> float:
|
| 975 |
+
return (v + 1) / 2 * 100 # [-1..1] → [0..100]
|
| 976 |
+
|
| 977 |
+
class EmotionItem(BaseModel):
|
| 978 |
+
emotion: str
|
| 979 |
+
probabilities: Optional[Dict[str, float]] = None
|
| 980 |
+
confidence: Optional[float] = 1.0
|
| 981 |
+
|
| 982 |
+
class ScoreRequest(BaseModel):
|
| 983 |
+
face_results: Optional[List[EmotionItem]] = []
|
| 984 |
+
audio_results: Optional[List[EmotionItem]] = []
|
| 985 |
+
text_results: Optional[List[EmotionItem]] = []
|
| 986 |
+
|
| 987 |
+
@app.post("/calculate_day_score")
|
| 988 |
+
def calculate_day_score(payload: ScoreRequest):
|
| 989 |
+
"""Calculate weighted day score from face, audio, and text emotions."""
|
| 990 |
+
source_weights = {
|
| 991 |
+
"face": 0.4,
|
| 992 |
+
"audio": 0.35,
|
| 993 |
+
"text": 0.25
|
| 994 |
+
}
|
| 995 |
+
|
| 996 |
+
accum_num = 0.0
|
| 997 |
+
accum_den = 0.0
|
| 998 |
+
breakdown = {"face": [], "audio": [], "text": []}
|
| 999 |
+
|
| 1000 |
+
# FACE
|
| 1001 |
+
for item in payload.face_results:
|
| 1002 |
+
v = valence_from_probabilities(item.probabilities) \
|
| 1003 |
+
if item.probabilities else EMO_VALENCE.get(item.emotion, 0.0)
|
| 1004 |
+
score = valence_to_score(v)
|
| 1005 |
+
w = source_weights["face"] * (item.confidence or 1.0)
|
| 1006 |
+
accum_num += score * w
|
| 1007 |
+
accum_den += w
|
| 1008 |
+
breakdown["face"].append({
|
| 1009 |
+
"emotion": item.emotion,
|
| 1010 |
+
"valence": v,
|
| 1011 |
+
"score": score,
|
| 1012 |
+
"weight": w
|
| 1013 |
+
})
|
| 1014 |
+
|
| 1015 |
+
# AUDIO
|
| 1016 |
+
for item in payload.audio_results:
|
| 1017 |
+
v = valence_from_probabilities(item.probabilities) \
|
| 1018 |
+
if item.probabilities else EMO_VALENCE.get(item.emotion, 0.0)
|
| 1019 |
+
score = valence_to_score(v)
|
| 1020 |
+
w = source_weights["audio"] * (item.confidence or 1.0)
|
| 1021 |
+
accum_num += score * w
|
| 1022 |
+
accum_den += w
|
| 1023 |
+
breakdown["audio"].append({
|
| 1024 |
+
"emotion": item.emotion,
|
| 1025 |
+
"confidence": item.confidence,
|
| 1026 |
+
"valence": v,
|
| 1027 |
+
"score": score,
|
| 1028 |
+
"weight": w
|
| 1029 |
+
})
|
| 1030 |
+
|
| 1031 |
+
# TEXT
|
| 1032 |
+
for item in payload.text_results:
|
| 1033 |
+
v = valence_from_probabilities(item.probabilities) \
|
| 1034 |
+
if item.probabilities else EMO_VALENCE.get(item.emotion.lower(), 0.0)
|
| 1035 |
+
score = valence_to_score(v)
|
| 1036 |
+
w = source_weights["text"] * (item.confidence or 1.0)
|
| 1037 |
+
accum_num += score * w
|
| 1038 |
+
accum_den += w
|
| 1039 |
+
breakdown["text"].append({
|
| 1040 |
+
"emotion": item.emotion,
|
| 1041 |
+
"confidence": item.confidence,
|
| 1042 |
+
"valence": v,
|
| 1043 |
+
"score": score,
|
| 1044 |
+
"weight": w
|
| 1045 |
+
})
|
| 1046 |
+
|
| 1047 |
+
final_score = accum_num / accum_den if accum_den > 0 else None
|
| 1048 |
+
|
| 1049 |
+
return {
|
| 1050 |
+
"day_score": final_score,
|
| 1051 |
+
"breakdown": breakdown,
|
| 1052 |
+
"numerator": accum_num,
|
| 1053 |
+
"denominator": accum_den
|
| 1054 |
+
}
|