import streamlit as st import pandas as pd import numpy as np import pickle import os from datetime import datetime from App import StreamlitUI def setup_page_config(): """Configure the Streamlit page""" st.set_page_config( page_title="Model Implementation", page_icon="🤖", layout="wide" ) def load_model_and_scaler(model_file, scaler_file): try: # Create a temporary directory if it doesn't exist temp_dir = 'temp_uploads' if not os.path.exists(temp_dir): os.makedirs(temp_dir) # Generate unique filenames timestamp = datetime.now().strftime('%Y%m%d_%H%M%S') temp_model_path = os.path.join(temp_dir, f'model_{timestamp}.pkl') temp_scaler_path = os.path.join(temp_dir, f'scaler_{timestamp}.pkl') # Save uploaded files with open(temp_model_path, 'wb') as f: f.write(model_file.getbuffer()) with open(temp_scaler_path, 'wb') as f: f.write(scaler_file.getbuffer()) # Load the files using pickle with open(temp_model_path, 'rb') as f: model = pickle.load(f) with open(temp_scaler_path, 'rb') as f: scaler = pickle.load(f) # Clean up os.remove(temp_model_path) os.remove(temp_scaler_path) return model, scaler except Exception as e: st.error(f"Error loading model or scaler: {str(e)}") return None, None def predict(model, scaler, features): try: # Convert features to numpy array and reshape features_array = np.array(features).reshape(1, -1) # Scale features features_scaled = scaler.transform(features_array) # Make prediction prediction = model.predict(features_scaled) # Get prediction probabilities if available try: probabilities = model.predict_proba(features_scaled) return prediction[0], probabilities[0] except: return prediction[0], None except Exception as e: st.error(f"Error making prediction: {str(e)}") return None, None def generate_random_features(feature_names): """Generate random but realistic values for features""" random_values = {} # Get ranges from default configs in App.py feature_ranges = {} for feature_name in feature_names: min_val = float('inf') max_val = float('-inf') # Calculate min/max across all classes in default configs for class_config in StreamlitUI().default_configs.values(): mean = class_config['mean'] std = class_config['std'] # Get index of matching feature try: idx = StreamlitUI().default_features.index(feature_name) feature_min = mean[idx] - 3*std[idx] # 3 std deviations for 99.7% coverage feature_max = mean[idx] + 3*std[idx] min_val = min(min_val, feature_min) max_val = max(max_val, feature_max) except ValueError: continue # If feature not found in defaults, use reasonable fallback range if min_val == float('inf'): min_val, max_val = 0, 100 feature_ranges[feature_name] = (min_val, max_val) for feature in feature_names: # Default range if feature not in predefined ranges min_val, max_val = 0, 100 # Check if any of the known features are in the feature name for key, (min_range, max_range) in feature_ranges.items(): if key.lower() in feature.lower(): min_val, max_val = min_range, max_range break random_values[feature] = round(np.random.uniform(min_val, max_val), 2) return random_values def show(): st.title("Model Implementation") # Initialize session state for random values if not exists if 'random_values' not in st.session_state: st.session_state.random_values = {} # Keep file uploaders in sidebar st.sidebar.subheader("Upload Model Files") model_file = st.sidebar.file_uploader("Upload Model (.pkl)", type=['pkl']) scaler_file = st.sidebar.file_uploader("Upload Scaler (.pkl)", type=['pkl']) # Only proceed if both files are uploaded if model_file and scaler_file: model, scaler = load_model_and_scaler(model_file, scaler_file) if model and scaler: st.sidebar.success("Model and scaler loaded successfully!") # Get feature names from scaler feature_names = None if hasattr(scaler, 'feature_names_in_'): feature_names = scaler.feature_names_in_ elif hasattr(model, 'feature_names_in_'): feature_names = model.feature_names_in_ if feature_names is None: feature_names_input = st.sidebar.text_input( "Enter feature names (comma-separated)", "feature1, feature2, feature3" ) feature_names = [f.strip() for f in feature_names_input.split(",")] st.sidebar.info("Feature names were not found in the model/scaler. Using manually entered names.") # Create two main columns for the page layout input_col, result_col = st.columns(2) # Left column for feature inputs with input_col: st.subheader("Enter Feature Values") # Add randomization button col1, col2 = st.columns([1, 2]) with col1: if st.button("🎲 Randomize"): # Generate new random values st.session_state.random_values = generate_random_features(feature_names) # Update session state for each feature for feature in feature_names: st.session_state[f"input_{feature}"] = st.session_state.random_values[feature] with col2: st.markdown("
Generate realistic random values
", unsafe_allow_html=True) # Create feature inputs in a grid layout feature_values = {} input_cols = st.columns(2) # 2 columns for feature inputs for idx, feature in enumerate(feature_names): with input_cols[idx % 2]: # Initialize session state for this input if not exists if f"input_{feature}" not in st.session_state: st.session_state[f"input_{feature}"] = 0.0 feature_values[feature] = st.number_input( f"{feature}", key=f"input_{feature}", step=1.0, format="%.2f" ) # Make prediction button predict_clicked = st.button("Make Prediction") # Right column for prediction results with result_col: st.subheader("Prediction Results") # Make prediction when values are available or button is clicked if predict_clicked or st.session_state.random_values: # Prepare features in correct order features = [feature_values[feature] for feature in feature_names] # Get prediction prediction, probabilities = predict(model, scaler, features) if prediction is not None: st.write(f"Predicted Class: **{prediction}**") # Display probabilities if available if probabilities is not None: st.write("Class Probabilities:") prob_df = pd.DataFrame({ 'Class': model.classes_, 'Probability': probabilities }) # Display as bar chart st.bar_chart( prob_df.set_index('Class') ) else: st.info("Enter feature values and click 'Make Prediction' to see results.") else: st.sidebar.info("Please upload both model and scaler files to proceed.") if __name__ == "__main__": setup_page_config() show()