import streamlit as st import pandas as pd import numpy as np import joblib # --- PAGE CONFIGURATION --- st.set_page_config( page_title="Steel Plate Defect Prediction", page_icon="🏗️", layout="wide") @st.cache_resource def load_artifacts(): artifacts = joblib.load('src/steel_defect_model.pkl') return artifacts try: artifacts = load_artifacts() models = artifacts['models'] scaler = artifacts['scaler'] feature_names = artifacts['features'] targets = artifacts['targets'] except FileNotFoundError: st.error("Model file 'steel_defect_model.pkl' not found.") st.stop() st.title("🏗️ Steel Plate Defect Prediction AI") st.markdown(""" This AI model predicts the probability of **7 different types of defects** in steel plates based on their geometric and radiometric properties. """) st.sidebar.header("Input Parameters") st.sidebar.info("Adjust the sliders to simulate different steel plate properties.") def user_input_features(): data = {} st.sidebar.subheader("1. Geometry") data['X_Minimum'] = st.sidebar.number_input('X Minimum', 0, 1700, 0) data['X_Maximum'] = st.sidebar.number_input('X Maximum', 0, 1700, 50) data['Y_Minimum'] = st.sidebar.number_input('Y Minimum', 0, 13000000, 600000) data['Y_Maximum'] = st.sidebar.number_input('Y Maximum', 0, 13000000, 600050) data['Pixels_Areas'] = st.sidebar.number_input('Pixels Areas', 0, 20000, 200) data['Steel_Plate_Thickness'] = st.sidebar.slider('Steel Plate Thickness', 40, 300, 80) st.sidebar.subheader("2. Luminosity") data['Sum_of_Luminosity'] = st.sidebar.number_input('Sum of Luminosity', 0, 12000000, 20000) data['Minimum_of_Luminosity'] = st.sidebar.slider('Minimum Luminosity', 0, 200, 80) data['Maximum_of_Luminosity'] = st.sidebar.slider('Maximum Luminosity', 0, 260, 130) data['Length_of_Conveyer'] = 1459 data['TypeOfSteel_A300'] = st.sidebar.selectbox('Type of Steel A300', [0, 1], index=0) data['Edges_Index'] = 0.35 data['Empty_Index'] = 0.4 data['Square_Index'] = 0.57 data['Outside_X_Index'] = 0.03 data['Edges_X_Index'] = 0.61 data['Edges_Y_Index'] = 0.83 data['Outside_Global_Index'] = 0.5 data['LogOfAreas'] = np.log(data['Pixels_Areas']) if data['Pixels_Areas'] > 0 else 0 data['Log_X_Index'] = 0 data['Log_Y_Index'] = 0 data['Orientation_Index'] = 0.1 data['Luminosity_Index'] = -0.13 data['SigmoidOfAreas'] = 0.5 df = pd.DataFrame(data, index=[0]) return df input_df = user_input_features() def preprocess_input(df): df = df.copy() df['X_Range'] = df['X_Maximum'] - df['X_Minimum'] df['Y_Range'] = df['Y_Maximum'] - df['Y_Minimum'] x_range = df['X_Range'].replace(0, 1) y_range = df['Y_Range'].replace(0, 1) df['Density'] = df['Pixels_Areas'] / (x_range * y_range) df['Aspect_Ratio'] = df['X_Range'] / y_range df['Luminosity_Range'] = df['Maximum_of_Luminosity'] - df['Minimum_of_Luminosity'] skewed_features = ['Pixels_Areas', 'Sum_of_Luminosity', 'X_Range', 'Y_Range', 'Aspect_Ratio'] for col in feature_names: if col not in df.columns: df[col] = 0 for feature in skewed_features: if feature in df.columns: df[feature] = np.log1p(df[feature].abs()) df = df[feature_names] return df if st.button('🔎 Analyze Steel Plate'): processed_df = preprocess_input(input_df) scaled_array = scaler.transform(processed_df) scaled_df = pd.DataFrame(scaled_array, columns=feature_names) results = {} for target in targets: model = models[target] prob = model.predict_proba(scaled_df)[0][1] results[target] = prob st.subheader("Analysis Results") results_df = pd.DataFrame(list(results.items()), columns=['Defect Type', 'Probability']) results_df = results_df.sort_values(by='Probability', ascending=False) top_defect = results_df.iloc[0] if top_defect['Probability'] > 0.5: st.error(f"⚠️ High Risk Detected: **{top_defect['Defect Type']}** ({top_defect['Probability']:.1%})") else: st.success("✅ No severe defects detected (All probabilities < 50%)") st.bar_chart(results_df.set_index('Defect Type')) with st.expander("See Detailed Probabilities"): st.dataframe(results_df.style.format({'Probability': '{:.2%}'}))