Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -112,44 +112,65 @@ def calculate_darvo_score(patterns, sentiment_before, sentiment_after, motifs_fo
|
|
112 |
contradiction_score = 1.0 if contradiction_flag else 0.0
|
113 |
return round(min(0.3 * pattern_score + 0.3 * sentiment_shift_score + 0.25 * motif_score + 0.15 * contradiction_score, 1.0), 3)
|
114 |
|
115 |
-
def generate_risk_snippet(
|
116 |
-
|
117 |
-
|
118 |
-
|
|
|
|
|
|
|
|
|
|
|
119 |
|
120 |
def analyze_single_message(text, thresholds, motif_flags):
|
121 |
motif_hits, matched_phrases = detect_motifs(text)
|
122 |
|
123 |
-
# Sentiment
|
124 |
input_ids = sentiment_tokenizer(f"emotion: {text}", return_tensors="pt").input_ids
|
125 |
with torch.no_grad():
|
126 |
-
|
127 |
-
emotion = sentiment_tokenizer.decode(
|
128 |
sentiment = EMOTION_TO_SENTIMENT.get(emotion, "undermining")
|
129 |
sentiment_score = 0.5 if sentiment == "undermining" else 0.0
|
130 |
|
131 |
-
#
|
132 |
adjusted_thresholds = {
|
133 |
-
k: v
|
134 |
for k, v in thresholds.items()
|
135 |
}
|
136 |
|
|
|
137 |
contradiction_flag = detect_contradiction(text)
|
138 |
-
motifs = [text for _, text in matched_phrases]
|
139 |
|
|
|
|
|
|
|
|
|
140 |
inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True)
|
141 |
with torch.no_grad():
|
142 |
outputs = model(**inputs)
|
143 |
scores = torch.sigmoid(outputs.logits.squeeze(0)).numpy()
|
144 |
|
145 |
-
threshold_labels = [
|
146 |
-
|
147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
|
149 |
-
|
150 |
darvo_score = calculate_darvo_score(pattern_labels, 0.0, sentiment_score, motifs, contradiction_flag)
|
151 |
|
152 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
|
154 |
def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
155 |
responses = answers_and_none[:len(ESCALATION_QUESTIONS)]
|
|
|
112 |
contradiction_score = 1.0 if contradiction_flag else 0.0
|
113 |
return round(min(0.3 * pattern_score + 0.3 * sentiment_shift_score + 0.25 * motif_score + 0.15 * contradiction_score, 1.0), 3)
|
114 |
|
115 |
+
def generate_risk_snippet(abuse_score, top_label):
|
116 |
+
if abuse_score >= 85:
|
117 |
+
risk_level = "high"
|
118 |
+
elif abuse_score >= 60:
|
119 |
+
risk_level = "moderate"
|
120 |
+
else:
|
121 |
+
risk_level = "low"
|
122 |
+
title, summary, advice = RISK_SNIPPETS[risk_level]
|
123 |
+
return f"\n\n{title}\n{summary} (Pattern: **{str(top_label)}**)\n💡 {advice}"
|
124 |
|
125 |
def analyze_single_message(text, thresholds, motif_flags):
|
126 |
motif_hits, matched_phrases = detect_motifs(text)
|
127 |
|
128 |
+
# Sentiment Analysis
|
129 |
input_ids = sentiment_tokenizer(f"emotion: {text}", return_tensors="pt").input_ids
|
130 |
with torch.no_grad():
|
131 |
+
outputs = sentiment_model.generate(input_ids)
|
132 |
+
emotion = sentiment_tokenizer.decode(outputs[0], skip_special_tokens=True).strip().lower()
|
133 |
sentiment = EMOTION_TO_SENTIMENT.get(emotion, "undermining")
|
134 |
sentiment_score = 0.5 if sentiment == "undermining" else 0.0
|
135 |
|
136 |
+
# Raise thresholds slightly if the sentiment is supportive
|
137 |
adjusted_thresholds = {
|
138 |
+
k: v + 0.05 if sentiment == "supportive" else v
|
139 |
for k, v in thresholds.items()
|
140 |
}
|
141 |
|
142 |
+
# Contradiction Check
|
143 |
contradiction_flag = detect_contradiction(text)
|
|
|
144 |
|
145 |
+
# Motifs
|
146 |
+
motifs = [phrase for _, phrase in matched_phrases]
|
147 |
+
|
148 |
+
# Model Prediction
|
149 |
inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True)
|
150 |
with torch.no_grad():
|
151 |
outputs = model(**inputs)
|
152 |
scores = torch.sigmoid(outputs.logits.squeeze(0)).numpy()
|
153 |
|
154 |
+
threshold_labels = [
|
155 |
+
label for label, score in zip(LABELS, scores)
|
156 |
+
if score > adjusted_thresholds[label]
|
157 |
+
]
|
158 |
+
top_patterns = sorted(
|
159 |
+
[(label, score) for label, score in zip(LABELS, scores)],
|
160 |
+
key=lambda x: x[1],
|
161 |
+
reverse=True
|
162 |
+
)[:2]
|
163 |
|
164 |
+
pattern_labels = threshold_labels + [label for label, _ in matched_phrases]
|
165 |
darvo_score = calculate_darvo_score(pattern_labels, 0.0, sentiment_score, motifs, contradiction_flag)
|
166 |
|
167 |
+
return (
|
168 |
+
np.mean([score for _, score in top_patterns]) * 100,
|
169 |
+
threshold_labels,
|
170 |
+
top_patterns,
|
171 |
+
darvo_score,
|
172 |
+
{"label": sentiment, "emotion": emotion}
|
173 |
+
)
|
174 |
|
175 |
def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
176 |
responses = answers_and_none[:len(ESCALATION_QUESTIONS)]
|