How every feedback score is calculated
AI reads the student text and selects labels. The backend then recalculates every numeric score with fixed formulas, attaches a score audit, and sends transparent values to the dashboard.
Pipeline
One record moves through four deterministic checkpoints before it reaches juries or dashboards.
Core Formula Inputs
These values are computed for every feedback before scoring starts.
rating_score
rating_score = (rating - 1) / 4
If no rating exists, the neutral default is 0.5.
label_score
positive = 0.80 · neutral = 0.50 · negative = 0.20
The AI chooses the label; the backend maps it to this fixed numeric value.
specificity
clip(0.15 + 0.55*min(word_count/20,1) + 0.30*specific_marker_present)
Specific markers include academic, dimension, or explicit risk terms found in the raw text.
alignment
alignment = 1 - abs(label_score - rating_score)
Contradictory rating/text pairs reduce confidence and credibility.
context_modifier
+0.02 / -0.03 / 0
+0.02 for specific senior high-attendance/high-GPA feedback. -0.03 for vague low-attendance feedback. Context is only a weak modifier.
rating_weight
0.25 if vague · 0.15 if specific · 0 if no rating
If rating and text strongly conflict, rating weight is capped at 0.10. For explicit risk allegations with random-positive ratings, rating_weight becomes 0.
Feedback-Level Scores
These are the numbers juries see on each analyzed record.
Sentiment score
clip((1-rating_weight)*label_score + rating_weight*rating_score + context_modifier)
Text label is primary. Rating becomes secondary, especially when the text is vague.
Credibility
clip(0.10 + 0.35*specificity + 0.25*alignment + 0.15*attendance_signal + 0.15*domain_evidence)
Vague feedback is capped at 0.45. Spam-like or irrelevant text is capped at 0.25.
Confidence
clip(0.20 + 0.35*specificity + 0.20*alignment + 0.25*domain_evidence)
Vague feedback is capped at 0.50 because the system should not overclaim certainty.
Emotion intensity
clip(0.55*emotion_base + 0.25*abs(sentiment_score-0.5)*2 + 0.10*rating_extremity + 0.10*specificity)
Emotion labels come from AI, but intensity is calculated from fixed base values and evidence strength.
Satisfaction Dimensions
Dimensions are scored only when raw text directly mentions the dimension. Otherwise they stay null.
Dimension polarity
negative markers = 0.20 · positive markers = 0.85 · mixed markers = 0.50 · otherwise sentiment_score
For assessment fairness and grading transparency, neutral grading markers with negative sentiment use 0.30.
Dimension score
null if no direct evidence; otherwise clip(0.80*polarity + 0.15*sentiment_score + 0.05*effective_rating_score + context_modifier)
Only dimensions with direct raw-text evidence contribute to their dashboard average.
Overall satisfaction
clip(0.70*sentiment_score + 0.20*effective_rating_score + 0.10*mean(non_null_dimensions or sentiment_score))
Overall always exists. If explicit risk evidence appears, a positive/random rating is replaced by the text-derived sentiment score.
Risk and Impact
Risk fields remain empty unless explicit risk evidence appears in raw_text.
No explicit risk evidence
risk.types = []
risk.probability = 0.0
risk.impact_scopes = []
Ordinary complaints may still have recommended_action, but they are not treated as legal/safety risks.
Explicit risk probability
clip(base_by_evidence_level + 0.10*specificity + 0.03*min(type_count,3))
Evidence bases: weak 0.35, explicit 0.55, serious 0.75. Teacher money-request wording is treated as corruption_allegation and routed to teacher_instructor + department for investigation.
Risk impact score
clip(0.55*risk_probability + 0.30*max_scope_weight + 0.15*severity_weight)
Used for dashboard ranking and institutional risk summaries.
Severity weights
none 0.00 · low 0.20 · medium 0.45 · high 0.75 · critical 1.00
Scope weights
individual_student 0.20 · group_of_students 0.35 · course_section 0.45 · teacher_instructor 0.50 · staff_admin 0.55 · department 0.65 · faculty 0.75 · institute 0.85 · education_system 1.00 · external_community 0.65 · digital_platform 0.55
Dashboard Aggregates
University, course, teacher, trend, and dimension dashboards use weighted calculations.
max(0.05, credibility * confidence)
sum(sentiment_score * record_weight) / sum(record_weight)
weighted average of overall_satisfaction
weighted average of non-null dimension_score[key]
weighted average of risk_impact_score
output.score_audit.formulas + components + scores
Two Example Outcomes
The examples below show why the system does not guess hidden dimensions.
“chummadim”
Direct evidence exists for clarity only. Risk is empty. Other dimensions stay null.
- sentiment_score
- 0.2125
- clarity
- 0.2044
- overall_satisfaction
- 0.2192
“xullasi bitta abed ekande 5”
Text is vague and non-academic, so credibility is low and non-overall dimensions stay null.
- credibility
- 0.25
- risk
- empty
- overall_satisfaction
- 0.756