import streamlit as st import joblib import pandas as pd import numpy as np MODEL_PATH = 'src/xgb_grade_prediction.joblib' # The 5 features used for training FEATURES = ["G1", "G2", "studytime", "failures", "absences"] @st.cache_resource def load_xgb_model(): try: model = joblib.load(MODEL_PATH) return model except Exception as e: st.error(f"Error loading the XGBoost model. Ensure '{MODEL_PATH}' is uploaded and the 'xgboost' library is installed. Error: {e}") return None def predict_grade(model, input_data): input_df = pd.DataFrame([input_data])[FEATURES] prediction = model.predict(input_df) return round(float(prediction[0])) st.set_page_config(page_title="Student Grade Predictor", layout="centered") st.title("🎓 Student Final Grade (G3) Prediction") st.markdown("Enter student performance metrics to predict the final grade (G3).") model = load_xgb_model() if model is not None: st.sidebar.header("Student Metrics (0-20 Scale)") # --- INPUT WIDGETS --- # G1 and G2 (First and Second Period Grades) g1 = st.sidebar.slider("Period 1 Grade (G1):", min_value=0, max_value=20, value=10) g2 = st.sidebar.slider("Period 2 Grade (G2):", min_value=0, max_value=20, value=11) # Study Time (Categorical in original dataset, often 1-4) studytime = st.sidebar.slider("Study Time (Hours/Week Index):", min_value=1, max_value=4, value=2) # Failures (Past class failures) failures = st.sidebar.slider("Past Class Failures:", min_value=0, max_value=4, value=0) # Absences (Number of school absences) absences = st.sidebar.number_input("Absences (Days):", min_value=0, max_value=93, value=5) # Collect inputs input_data = { "G1": g1, "G2": g2, "studytime": studytime, "failures": failures, "absences": absences } st.subheader("Current Input Summary:") st.dataframe(pd.DataFrame([input_data]), hide_index=True) if st.button("Predict Final Grade (G3)"): with st.spinner('Calculating prediction...'): predicted_g3 = predict_grade(model, input_data) st.success("Prediction Successful!") st.markdown("### Predicted Final Grade (G3):") st.markdown(f"**{predicted_g3} / 20**") if predicted_g3 >= 10: st.balloons()