Upload 5 files
Browse files- combined_student_data.csv +0 -0
- feature_names.joblib +3 -0
- hugging_face_learner.py +261 -0
- random_forest_model.joblib +3 -0
- scaler.joblib +3 -0
combined_student_data.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
feature_names.joblib
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:417b94f07e2693a9be08a5996fd918d5a84f3f55bcd66f500c34577f24e0151f
|
| 3 |
+
size 444
|
hugging_face_learner.py
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# learner_app.py - Streamlit Dashboard with Hugging Face Suggestions (No OpenAI required)
|
| 2 |
+
|
| 3 |
+
import streamlit as st
|
| 4 |
+
import pandas as pd
|
| 5 |
+
import joblib
|
| 6 |
+
import os
|
| 7 |
+
import requests
|
| 8 |
+
import warnings
|
| 9 |
+
|
| 10 |
+
# --- Page Configuration ---
|
| 11 |
+
st.set_page_config(
|
| 12 |
+
page_title="Slow Learner Prediction Tool",
|
| 13 |
+
page_icon="π",
|
| 14 |
+
layout="wide",
|
| 15 |
+
initial_sidebar_state="expanded"
|
| 16 |
+
)
|
| 17 |
+
|
| 18 |
+
# --- Load Artifacts ---
|
| 19 |
+
@st.cache_resource
|
| 20 |
+
def load_artifacts():
|
| 21 |
+
try:
|
| 22 |
+
scaler = joblib.load("scaler.joblib")
|
| 23 |
+
model = joblib.load("random_forest_model.joblib")
|
| 24 |
+
features = joblib.load("feature_names.joblib")
|
| 25 |
+
return scaler, model, features
|
| 26 |
+
except Exception as e:
|
| 27 |
+
st.error(f"Error loading model files: {e}")
|
| 28 |
+
return None, None, None
|
| 29 |
+
|
| 30 |
+
scaler, model, feature_names = load_artifacts()
|
| 31 |
+
|
| 32 |
+
# --- Input Configuration ---
|
| 33 |
+
main_inputs = [
|
| 34 |
+
'study_hours_per_day', 'social_media_hours', 'attendance_percentage',
|
| 35 |
+
'sleep_hours', 'exam_score', 'mental_health_rating'
|
| 36 |
+
]
|
| 37 |
+
|
| 38 |
+
categorical_inputs = {
|
| 39 |
+
'gender': ['Female', 'Male', 'Other'],
|
| 40 |
+
'part_time_job': ['No', 'Yes'],
|
| 41 |
+
'diet_quality': ['Average', 'Good', 'Poor'],
|
| 42 |
+
'parental_education_level': ['Bachelor', 'High School', 'Master', 'Unknown'],
|
| 43 |
+
'internet_quality': ['Average', 'Good', 'Poor'],
|
| 44 |
+
'extracurricular_participation': ['No', 'Yes']
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
# --- Helper Functions ---
|
| 48 |
+
def prepare_input(user_input, cat_input, expected_features):
|
| 49 |
+
df = pd.DataFrame([user_input])
|
| 50 |
+
for col, value in cat_input.items():
|
| 51 |
+
df[col] = value
|
| 52 |
+
df = pd.get_dummies(df, drop_first=True)
|
| 53 |
+
for feat in expected_features:
|
| 54 |
+
if feat not in df.columns:
|
| 55 |
+
df[feat] = 0
|
| 56 |
+
df = df[expected_features]
|
| 57 |
+
return df
|
| 58 |
+
|
| 59 |
+
def predict_support(df, scaler, model):
|
| 60 |
+
scaled = scaler.transform(df)
|
| 61 |
+
pred = model.predict(scaled)[0]
|
| 62 |
+
prob = model.predict_proba(scaled)[0][1]
|
| 63 |
+
return pred, prob
|
| 64 |
+
|
| 65 |
+
def calculate_risk_score(study_hours, exam_score, attendance, participation, sleep_hours, social_media, prob):
|
| 66 |
+
score = 0
|
| 67 |
+
if study_hours < 2:
|
| 68 |
+
score += 25
|
| 69 |
+
if exam_score < 65:
|
| 70 |
+
score += 25
|
| 71 |
+
if attendance < 85:
|
| 72 |
+
score += 10
|
| 73 |
+
if participation <= 2:
|
| 74 |
+
score += 10
|
| 75 |
+
if sleep_hours < 6:
|
| 76 |
+
score += 10
|
| 77 |
+
if social_media > 4:
|
| 78 |
+
score += 10
|
| 79 |
+
if prob > 0.35:
|
| 80 |
+
score += 10
|
| 81 |
+
return score
|
| 82 |
+
|
| 83 |
+
def get_remedial_suggestions(score, probability, exam_score,
|
| 84 |
+
attendance_percentage, participation_rating,
|
| 85 |
+
study_hours, sleep_hours, social_media, part_time, extracurricular,
|
| 86 |
+
mental_health_rating):
|
| 87 |
+
suggestions = []
|
| 88 |
+
avg_metric = (study_hours * 10 + sleep_hours * 10 + mental_health_rating + exam_score + attendance_percentage + (6 - participation_rating) * 10 + (6 - mental_health_rating)) / 7
|
| 89 |
+
threshold = 60
|
| 90 |
+
|
| 91 |
+
if score >= 50 or avg_metric < threshold:
|
| 92 |
+
suggestions.append(f"**Student may benefit from additional support (Risk Score: {score}/100)**")
|
| 93 |
+
suggestions.append("---")
|
| 94 |
+
suggestions.append("### β
General Support Recommendations")
|
| 95 |
+
suggestions.extend([
|
| 96 |
+
"* Meet individually to identify challenges and learning preferences.",
|
| 97 |
+
"* Break down complex topics with step-by-step guidance.",
|
| 98 |
+
"* Provide more practice in weaker subjects.",
|
| 99 |
+
"* Incorporate visual learning aids and activities.",
|
| 100 |
+
"* Encourage active participation in a supportive setting.",
|
| 101 |
+
"* Recommend mentoring or peer learning sessions."
|
| 102 |
+
])
|
| 103 |
+
|
| 104 |
+
suggestions.append("\n---")
|
| 105 |
+
suggestions.append("### π Personalized Observations & Strategies")
|
| 106 |
+
triggered_specific = False
|
| 107 |
+
|
| 108 |
+
if exam_score < 45:
|
| 109 |
+
suggestions.append("* *Observation:* Very Low Standardized Test Score β Focus on core concepts and regular practice.")
|
| 110 |
+
triggered_specific = True
|
| 111 |
+
|
| 112 |
+
if attendance_percentage < 75:
|
| 113 |
+
suggestions.append("* *Observation:* Low Attendance β Discuss reasons and promote regular class routines.")
|
| 114 |
+
triggered_specific = True
|
| 115 |
+
|
| 116 |
+
if participation_rating <= 3:
|
| 117 |
+
suggestions.append("* *Observation:* Low Class Participation β Offer incentives and create non-judgmental space.")
|
| 118 |
+
triggered_specific = True
|
| 119 |
+
|
| 120 |
+
if study_hours < 2:
|
| 121 |
+
suggestions.append("* *Observation:* Insufficient Study Time β Design time tables with short, focused sessions.")
|
| 122 |
+
triggered_specific = True
|
| 123 |
+
|
| 124 |
+
if sleep_hours < 6:
|
| 125 |
+
suggestions.append("* *Observation:* Poor Sleep Habits β Promote healthy sleep routines (7-8 hrs/night).")
|
| 126 |
+
triggered_specific = True
|
| 127 |
+
|
| 128 |
+
if social_media > 4:
|
| 129 |
+
suggestions.append("* *Observation:* High Screen Time β Introduce productivity tools and digital detox plans.")
|
| 130 |
+
triggered_specific = True
|
| 131 |
+
|
| 132 |
+
if part_time == "Yes" and study_hours < 2:
|
| 133 |
+
suggestions.append("* *Observation:* Work-Study Conflict β Balance workload and offer weekend sessions.")
|
| 134 |
+
triggered_specific = True
|
| 135 |
+
|
| 136 |
+
if extracurricular == "Yes" and exam_score < 60:
|
| 137 |
+
suggestions.append("* *Observation:* Over-scheduled with Activities β Temporarily reduce extracurricular load.")
|
| 138 |
+
triggered_specific = True
|
| 139 |
+
|
| 140 |
+
if not triggered_specific:
|
| 141 |
+
suggestions.append("* No individual issues flagged. Support focus, motivation, and consistency.")
|
| 142 |
+
|
| 143 |
+
suggestions.append("\n---")
|
| 144 |
+
suggestions.append("**π Follow-Up:** Review student progress weekly and adjust interventions as needed.")
|
| 145 |
+
|
| 146 |
+
return suggestions
|
| 147 |
+
|
| 148 |
+
def get_hf_suggestions(student_profile_dict):
|
| 149 |
+
prompt = f"""
|
| 150 |
+
A student is showing signs of struggling in academics. Their profile is:
|
| 151 |
+
{student_profile_dict}
|
| 152 |
+
|
| 153 |
+
Based on this, generate 3 short, practical, and personalized remedial strategies.
|
| 154 |
+
"""
|
| 155 |
+
headers = {
|
| 156 |
+
"Authorization": f"Bearer {st.secrets['HF_API_KEY']}"
|
| 157 |
+
}
|
| 158 |
+
payload = {
|
| 159 |
+
"inputs": prompt,
|
| 160 |
+
"parameters": {
|
| 161 |
+
"temperature": 0.7,
|
| 162 |
+
"max_length": 250
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
model_url = "https://api-inference.huggingface.co/models/google/flan-t5-base"
|
| 166 |
+
try:
|
| 167 |
+
response = requests.post(model_url, headers=headers, json=payload)
|
| 168 |
+
result = response.json()
|
| 169 |
+
if isinstance(result, dict) and "error" in result:
|
| 170 |
+
return f"β API Error: {result['error']}"
|
| 171 |
+
return result[0]['generated_text']
|
| 172 |
+
except Exception as e:
|
| 173 |
+
return f"β οΈ Error getting suggestions: {e}"
|
| 174 |
+
|
| 175 |
+
# --- UI ---
|
| 176 |
+
st.title("π Slow Learner Prediction Tool")
|
| 177 |
+
st.subheader("Identify students who might need additional support")
|
| 178 |
+
|
| 179 |
+
with st.sidebar.form("student_form"):
|
| 180 |
+
st.markdown("### π― Core Student Features")
|
| 181 |
+
|
| 182 |
+
study_hours = st.number_input("Study Hours Per Day", 0.0, 24.0, 2.0, 0.5)
|
| 183 |
+
social_media = st.number_input("Social Media Hours", 0.0, 24.0, 1.0, 0.5)
|
| 184 |
+
attendance = st.number_input("Attendance Percentage", 0.0, 100.0, 90.0, 0.5)
|
| 185 |
+
sleep_hours = st.number_input("Sleep Hours Per Day", 0.0, 24.0, 7.0, 0.5)
|
| 186 |
+
exam_score = st.number_input("Exam Score", 0.0, 100.0, 60.0, 0.5)
|
| 187 |
+
mental_health_rating = st.slider("Mental Health Rating", 1, 5, 3)
|
| 188 |
+
participation = st.slider("Participation Rating", 1, 5, 3)
|
| 189 |
+
|
| 190 |
+
with st.expander("β Optional Features (Category Inputs)"):
|
| 191 |
+
gender = st.selectbox("Gender", categorical_inputs['gender'])
|
| 192 |
+
part_time = st.selectbox("Part-Time Job", categorical_inputs['part_time_job'])
|
| 193 |
+
diet = st.selectbox("Diet Quality", categorical_inputs['diet_quality'])
|
| 194 |
+
parent_edu = st.selectbox("Parental Education Level", categorical_inputs['parental_education_level'])
|
| 195 |
+
net_quality = st.selectbox("Internet Quality", categorical_inputs['internet_quality'])
|
| 196 |
+
extracurricular = st.selectbox("Extracurricular Participation", categorical_inputs['extracurricular_participation'])
|
| 197 |
+
|
| 198 |
+
use_ai = st.checkbox("π¬ Use AI Suggestions ", value=True)
|
| 199 |
+
submit_btn = st.form_submit_button("β¨ Predict Support Need")
|
| 200 |
+
|
| 201 |
+
# --- Main Panel ---
|
| 202 |
+
if submit_btn:
|
| 203 |
+
if scaler is None or model is None or feature_names is None:
|
| 204 |
+
st.error("Artifacts not loaded. Please check the model files.")
|
| 205 |
+
else:
|
| 206 |
+
with st.spinner("Analyzing student data..."):
|
| 207 |
+
user_inputs = {
|
| 208 |
+
'study_hours_per_day': study_hours,
|
| 209 |
+
'social_media_hours': social_media,
|
| 210 |
+
'attendance_percentage': attendance,
|
| 211 |
+
'sleep_hours': sleep_hours,
|
| 212 |
+
'exam_score': exam_score,
|
| 213 |
+
'mental_health_rating': mental_health_rating
|
| 214 |
+
}
|
| 215 |
+
cat_values = {
|
| 216 |
+
'gender': gender,
|
| 217 |
+
'part_time_job': part_time,
|
| 218 |
+
'diet_quality': diet,
|
| 219 |
+
'parental_education_level': parent_edu,
|
| 220 |
+
'internet_quality': net_quality,
|
| 221 |
+
'extracurricular_participation': extracurricular
|
| 222 |
+
}
|
| 223 |
+
input_df = prepare_input(user_inputs, cat_values, feature_names)
|
| 224 |
+
prediction, probability = predict_support(input_df, scaler, model)
|
| 225 |
+
risk_score = calculate_risk_score(study_hours, exam_score, attendance, participation, sleep_hours, social_media, probability)
|
| 226 |
+
|
| 227 |
+
if risk_score >= 30:
|
| 228 |
+
st.error(f"π¨ This student may be a slow learner (Risk Score: {risk_score}/100)")
|
| 229 |
+
else:
|
| 230 |
+
st.success("β
No significant learning difficulties detected.")
|
| 231 |
+
|
| 232 |
+
st.progress(risk_score / 100.0, text=f"Slow Learner Risk Score: {risk_score}/100")
|
| 233 |
+
|
| 234 |
+
suggestions = get_remedial_suggestions(
|
| 235 |
+
risk_score, probability, exam_score, attendance, participation,
|
| 236 |
+
study_hours, sleep_hours, social_media, part_time, extracurricular, mental_health_rating
|
| 237 |
+
)
|
| 238 |
+
|
| 239 |
+
if suggestions:
|
| 240 |
+
with st.expander("π‘ Suggested Remedial Actions", expanded=True):
|
| 241 |
+
for tip in suggestions:
|
| 242 |
+
st.markdown(tip)
|
| 243 |
+
|
| 244 |
+
if use_ai:
|
| 245 |
+
st.markdown("### π€ AI-Based Suggestions (Hugging Face)")
|
| 246 |
+
student_data = {
|
| 247 |
+
"Study Hours": study_hours,
|
| 248 |
+
"Exam Score": exam_score,
|
| 249 |
+
"Attendance": attendance,
|
| 250 |
+
"Participation": participation,
|
| 251 |
+
"Sleep Hours": sleep_hours,
|
| 252 |
+
"Social Media Hours": social_media,
|
| 253 |
+
"Part-time Job": part_time,
|
| 254 |
+
"Extracurricular Activities": extracurricular,
|
| 255 |
+
"Mental Health Rating": mental_health_rating
|
| 256 |
+
}
|
| 257 |
+
hf_advice = get_hf_suggestions(student_data)
|
| 258 |
+
st.markdown(hf_advice)
|
| 259 |
+
|
| 260 |
+
st.markdown("---")
|
| 261 |
+
st.caption("Disclaimer: This is an AI-based tool. Use results alongside academic judgment.")
|
random_forest_model.joblib
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:795d5c482e3ca62b82c467526d88ced48296220286c50aa1b73cb796751677db
|
| 3 |
+
size 6626643
|
scaler.joblib
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2d1f6bb2a962a03a316572dd2fdcb960a5fcbb692b83eaa6f68e67a6e38a07df
|
| 3 |
+
size 1727
|