Spaces:
Running
on
Zero
Running
on
Zero
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)]
|