StudentPerformancePrediction / src /streamlit_app.py
hande-x's picture
Update src/streamlit_app.py
7e00c24 verified
Raw
History Blame Contribute Delete
3.54 kB
import streamlit as st
import joblib
import pandas as pd
import numpy as np
# --- Configuration ---
MODEL_PATH = 'src/kn_perormance_prediction.joblib'
ENCODERS_PATH = 'src/label_encoders.joblib'
# REAL features the model expects (first 10 columns of df during training)
FEATURES = [
'gender',
'race/ethnicity',
'parental level of education',
'lunch',
'test preparation course',
'math score',
'reading score',
'writing score',
'total_score',
'percentage'
]
RACE_MAP = {
'group A': 1, 'group B': 2, 'group C': 3,
'group D': 4, 'group E': 5
}
@st.cache_resource
def load_assets():
try:
model = joblib.load(MODEL_PATH)
encoders = joblib.load(ENCODERS_PATH)
return model, encoders
except Exception as e:
st.error(f"Error loading model or encoders: {e}")
return None, None
def preprocess_and_predict(model, encoders, input_data):
df_input = pd.DataFrame([input_data])
# 1. Map race/ethnicity exactly as in training
df_input['race/ethnicity'] = df_input['race/ethnicity'].map(RACE_MAP)
# 2. Apply Label Encoding for categorical inputs
for col, le in encoders.items():
df_input[col] = le.transform(df_input[col])
# 3. Compute total_score and percentage (missing features)
df_input['total_score'] = (
df_input['math score'] +
df_input['reading score'] +
df_input['writing score']
)
df_input['percentage'] = df_input['total_score'] / 3
# 4. Final array in the correct feature order
final_input_array = df_input[FEATURES].values
# 5. Predict grade
prediction_label = model.predict(final_input_array)
return prediction_label[0]
# --- Streamlit UI ---
st.set_page_config(page_title="Student Performance", layout="centered")
st.title("📚 Student Final Grade Predictor (A–E)")
st.markdown("Enter student characteristics and scores to predict the final letter grade.")
model, encoders = load_assets()
if model is not None and encoders is not None:
st.sidebar.header("Student Information")
gender = st.sidebar.selectbox("Gender:", options=['male', 'female'])
race = st.sidebar.selectbox("Race/Ethnicity:", options=list(RACE_MAP.keys()))
parental_education = st.sidebar.selectbox(
"Parental Education:",
options=[
'some high school', 'high school', 'some college',
"associate's degree", "bachelor's degree", "master's degree"
]
)
lunch = st.sidebar.selectbox("Lunch:", options=['standard', 'free/reduced'])
prep_course = st.sidebar.selectbox("Test Prep Course:", options=['none', 'completed'])
st.sidebar.header("Scores (0-100)")
math = st.sidebar.slider("Math Score:", 0, 100, 70)
reading = st.sidebar.slider("Reading Score:", 0, 100, 75)
writing = st.sidebar.slider("Writing Score:", 0, 100, 72)
input_data = {
'gender': gender,
'race/ethnicity': race,
'parental level of education': parental_education,
'lunch': lunch,
'test preparation course': prep_course,
'math score': math,
'reading score': reading,
'writing score': writing
}
if st.button("Predict Final Grade"):
with st.spinner("Calculating prediction..."):
predicted_grade = preprocess_and_predict(model, encoders, input_data)
st.success("Prediction Successful!")
st.markdown("### Predicted Letter Grade:")
st.markdown(f"**{predicted_grade}**")