hande-x commited on
Commit
7e00c24
Β·
verified Β·
1 Parent(s): 98f9459

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +58 -39
src/streamlit_app.py CHANGED
@@ -4,17 +4,25 @@ import pandas as pd
4
  import numpy as np
5
 
6
  # --- Configuration ---
7
- MODEL_PATH = 'src/kn_perormance_prediction.joblib'
8
- ENCODERS_PATH = 'src/label_encoders.joblib'
9
 
 
10
  FEATURES = [
11
- 'gender', 'race/ethnicity', 'parental level of education',
12
- 'lunch', 'test preparation course', 'math score',
13
- 'reading score', 'writing score'
 
 
 
 
 
 
 
14
  ]
15
 
16
  RACE_MAP = {
17
- 'group A': 1, 'group B': 2, 'group C': 3,
18
  'group D': 4, 'group E': 5
19
  }
20
 
@@ -22,36 +30,45 @@ RACE_MAP = {
22
  def load_assets():
23
  try:
24
  model = joblib.load(MODEL_PATH)
25
- encoders = joblib.load(ENCODERS_PATH) # Load the dict of encoders
26
  return model, encoders
27
  except Exception as e:
28
- st.error(f"Error loading assets. Ensure model and encoders are uploaded. Error: {e}")
29
  return None, None
30
 
 
31
  def preprocess_and_predict(model, encoders, input_data):
32
-
33
- # 1. Create a DataFrame for processing
34
  df_input = pd.DataFrame([input_data])
35
-
36
- # 2. Apply Custom Race/Ethnicity Mapping (as done in the original notebook)
37
  df_input['race/ethnicity'] = df_input['race/ethnicity'].map(RACE_MAP)
38
 
39
- # 3. Apply Label Encoding for other Categorical Features
40
  for col, le in encoders.items():
41
- # Use the loaded LabelEncoder objects to transform the input strings
42
  df_input[col] = le.transform(df_input[col])
43
-
44
- # 4. Prepare the final input array
 
 
 
 
 
 
 
 
 
45
  final_input_array = df_input[FEATURES].values
46
-
47
- # 5. Predict the grade (O, A, B, C, D, E)
48
  prediction_label = model.predict(final_input_array)
49
-
50
  return prediction_label[0]
51
 
52
- # --- Streamlit Interface ---
 
53
  st.set_page_config(page_title="Student Performance", layout="centered")
54
- st.title("πŸ“š Student Final Grade Predictor (A-E)")
55
  st.markdown("Enter student characteristics and scores to predict the final letter grade.")
56
 
57
  model, encoders = load_assets()
@@ -59,36 +76,38 @@ model, encoders = load_assets()
59
  if model is not None and encoders is not None:
60
  st.sidebar.header("Student Information")
61
 
62
- # --- INPUT WIDGETS ---
63
  gender = st.sidebar.selectbox("Gender:", options=['male', 'female'])
64
  race = st.sidebar.selectbox("Race/Ethnicity:", options=list(RACE_MAP.keys()))
65
- parental_education = st.sidebar.selectbox("Parental Education:", options=['some high school', 'high school', 'some college', 'associate\'s degree', 'bachelor\'s degree', 'master\'s degree'])
 
 
 
 
 
 
66
  lunch = st.sidebar.selectbox("Lunch:", options=['standard', 'free/reduced'])
67
  prep_course = st.sidebar.selectbox("Test Prep Course:", options=['none', 'completed'])
68
 
69
  st.sidebar.header("Scores (0-100)")
70
- math = st.sidebar.slider("Math Score:", min_value=0, max_value=100, value=70)
71
- reading = st.sidebar.slider("Reading Score:", min_value=0, max_value=100, value=75)
72
- writing = st.sidebar.slider("Writing Score:", min_value=0, max_value=100, value=72)
73
-
74
- # Collect inputs
75
  input_data = {
76
- 'gender': gender,
77
- 'race/ethnicity': race,
78
- 'parental level of education': parental_education,
79
- 'lunch': lunch,
80
- 'test preparation course': prep_course,
81
- 'math score': math,
82
- 'reading score': reading,
83
  'writing score': writing
84
  }
85
 
86
  if st.button("Predict Final Grade"):
87
- with st.spinner('Calculating prediction...'):
88
  predicted_grade = preprocess_and_predict(model, encoders, input_data)
89
 
90
  st.success("Prediction Successful!")
91
  st.markdown("### Predicted Letter Grade:")
92
- st.markdown(f"**{predicted_grade}**")
93
-
94
- st.info("The prediction is the most likely letter grade (O, A, B, C, D, E) based on the input features.")
 
4
  import numpy as np
5
 
6
  # --- Configuration ---
7
+ MODEL_PATH = 'src/kn_perormance_prediction.joblib'
8
+ ENCODERS_PATH = 'src/label_encoders.joblib'
9
 
10
+ # REAL features the model expects (first 10 columns of df during training)
11
  FEATURES = [
12
+ 'gender',
13
+ 'race/ethnicity',
14
+ 'parental level of education',
15
+ 'lunch',
16
+ 'test preparation course',
17
+ 'math score',
18
+ 'reading score',
19
+ 'writing score',
20
+ 'total_score',
21
+ 'percentage'
22
  ]
23
 
24
  RACE_MAP = {
25
+ 'group A': 1, 'group B': 2, 'group C': 3,
26
  'group D': 4, 'group E': 5
27
  }
28
 
 
30
  def load_assets():
31
  try:
32
  model = joblib.load(MODEL_PATH)
33
+ encoders = joblib.load(ENCODERS_PATH)
34
  return model, encoders
35
  except Exception as e:
36
+ st.error(f"Error loading model or encoders: {e}")
37
  return None, None
38
 
39
+
40
  def preprocess_and_predict(model, encoders, input_data):
41
+
 
42
  df_input = pd.DataFrame([input_data])
43
+
44
+ # 1. Map race/ethnicity exactly as in training
45
  df_input['race/ethnicity'] = df_input['race/ethnicity'].map(RACE_MAP)
46
 
47
+ # 2. Apply Label Encoding for categorical inputs
48
  for col, le in encoders.items():
 
49
  df_input[col] = le.transform(df_input[col])
50
+
51
+ # 3. Compute total_score and percentage (missing features)
52
+ df_input['total_score'] = (
53
+ df_input['math score'] +
54
+ df_input['reading score'] +
55
+ df_input['writing score']
56
+ )
57
+
58
+ df_input['percentage'] = df_input['total_score'] / 3
59
+
60
+ # 4. Final array in the correct feature order
61
  final_input_array = df_input[FEATURES].values
62
+
63
+ # 5. Predict grade
64
  prediction_label = model.predict(final_input_array)
65
+
66
  return prediction_label[0]
67
 
68
+
69
+ # --- Streamlit UI ---
70
  st.set_page_config(page_title="Student Performance", layout="centered")
71
+ st.title("πŸ“š Student Final Grade Predictor (A–E)")
72
  st.markdown("Enter student characteristics and scores to predict the final letter grade.")
73
 
74
  model, encoders = load_assets()
 
76
  if model is not None and encoders is not None:
77
  st.sidebar.header("Student Information")
78
 
 
79
  gender = st.sidebar.selectbox("Gender:", options=['male', 'female'])
80
  race = st.sidebar.selectbox("Race/Ethnicity:", options=list(RACE_MAP.keys()))
81
+ parental_education = st.sidebar.selectbox(
82
+ "Parental Education:",
83
+ options=[
84
+ 'some high school', 'high school', 'some college',
85
+ "associate's degree", "bachelor's degree", "master's degree"
86
+ ]
87
+ )
88
  lunch = st.sidebar.selectbox("Lunch:", options=['standard', 'free/reduced'])
89
  prep_course = st.sidebar.selectbox("Test Prep Course:", options=['none', 'completed'])
90
 
91
  st.sidebar.header("Scores (0-100)")
92
+ math = st.sidebar.slider("Math Score:", 0, 100, 70)
93
+ reading = st.sidebar.slider("Reading Score:", 0, 100, 75)
94
+ writing = st.sidebar.slider("Writing Score:", 0, 100, 72)
95
+
 
96
  input_data = {
97
+ 'gender': gender,
98
+ 'race/ethnicity': race,
99
+ 'parental level of education': parental_education,
100
+ 'lunch': lunch,
101
+ 'test preparation course': prep_course,
102
+ 'math score': math,
103
+ 'reading score': reading,
104
  'writing score': writing
105
  }
106
 
107
  if st.button("Predict Final Grade"):
108
+ with st.spinner("Calculating prediction..."):
109
  predicted_grade = preprocess_and_predict(model, encoders, input_data)
110
 
111
  st.success("Prediction Successful!")
112
  st.markdown("### Predicted Letter Grade:")
113
+ st.markdown(f"**{predicted_grade}**")