Files
predictive_analysis/src/utils/model_utils.py
T
2025-09-28 00:37:22 +03:00

108 lines
4.4 KiB
Python

"""
Model loading and data preprocessing utilities
"""
import streamlit as st
import pandas as pd
import pickle
from typing import Dict, Any, List
@st.cache_data
def load_model_and_info():
"""Load the trained model and preprocessing information"""
try:
with open('random_forest_model.pkl', 'rb') as f:
model = pickle.load(f)
with open('preprocessing_info.pkl', 'rb') as f:
preprocessing_info = pickle.load(f)
with open('feature_names.pkl', 'rb') as f:
feature_names = pickle.load(f)
return model, preprocessing_info, feature_names
except FileNotFoundError:
st.error("❌ Model files not found! Please run 'train_and_save_model.py' first.")
st.stop()
def preprocess_input(user_input: Dict[str, Any], preprocessing_info: Dict[str, Any]) -> pd.DataFrame:
"""Preprocess user input to match the training data format"""
# Create a DataFrame with the user input
input_df = pd.DataFrame([user_input])
# Get categorical columns that need one-hot encoding
categorical_columns = [
'Marital status', 'Application mode', 'Course', 'Daytime/evening attendance',
'Previous qualification', 'Nationality', 'Mothers qualification',
'Fathers qualification', 'Mothers occupation', 'Fathers occupation',
'Gender', 'Displaced', 'Educational special needs', 'Debtor',
'Tuition fees up to date', 'Scholarship holder', 'International',
'Application order'
]
# Perform one-hot encoding for categorical columns
for column in categorical_columns:
if column in input_df.columns:
# Get dummies with prefix
dummies = pd.get_dummies(input_df[column], prefix=column)
# Concatenate with original data
input_df = pd.concat([input_df, dummies], axis=1)
# Drop original column
input_df.drop(columns=[column], inplace=True)
# Ensure all training features are present
feature_names = preprocessing_info['feature_names']
# Add missing columns with 0 values
for feature in feature_names:
if feature not in input_df.columns:
input_df[feature] = 0
# Select only the features used in training and in the same order
input_df = input_df[feature_names]
return input_df
def validate_input(user_input: Dict[str, Any]) -> List[str]:
"""Validate user input and return list of issues"""
validation_issues = []
# Check for unrealistic combinations
if user_input['Age at enrollment'] < 17:
validation_issues.append("⚠️ Age seems too low for enrollment")
if user_input['Curricular units 1st sem (approved)'] > user_input['Curricular units 1st sem (enrolled)']:
validation_issues.append("⚠️ Approved units exceed enrolled units (1st sem)")
if user_input['Curricular units 2nd sem (approved)'] > user_input['Curricular units 2nd sem (enrolled)']:
validation_issues.append("⚠️ Approved units exceed enrolled units (2nd sem)")
return validation_issues
def generate_recommendations(predicted_outcome: str, user_input: Dict[str, Any]) -> List[str]:
"""Generate personalized recommendations based on prediction and input"""
recommendations = []
if predicted_outcome == "Dropout":
if user_input['Curricular units 1st sem (approved)'] == 0:
recommendations.append("📚 **Academic Support:** Provide tutoring for struggling courses")
if user_input['Scholarship holder'] == 0:
recommendations.append("💰 **Financial Aid:** Consider scholarship opportunities")
if user_input['Age at enrollment'] > 25:
recommendations.append("🕐 **Flexible Scheduling:** Offer evening or part-time options")
if user_input['Debtor'] == 1:
recommendations.append("💳 **Financial Counseling:** Address outstanding debts")
elif predicted_outcome == "Graduate":
recommendations.append("🎯 **Success Indicators:** This student shows strong potential for graduation")
recommendations.append("🔄 **Continue Support:** Maintain current academic support systems")
else: # Enrolled
recommendations.append("📈 **Regular Monitoring:** Schedule periodic academic check-ins")
recommendations.append("🎯 **Goal Setting:** Help establish clear academic objectives")
return recommendations