| | import streamlit as st |
| | import pandas as pd |
| | import joblib |
| | import matplotlib.pyplot as plt |
| |
|
| | |
| | |
| | |
| | st.set_page_config(page_title="Engine Health Monitor", layout="wide") |
| |
|
| | st.title("π Engine Predictive Maintenance Dashboard") |
| |
|
| | st.write( |
| | "Predict engine health using sensor data. " |
| | "Adjust the decision threshold to balance false alarms vs missed failures." |
| | ) |
| |
|
| | |
| | |
| | |
| | @st.cache_resource |
| | def load_model(): |
| | return joblib.load("best_model.pkl") |
| |
|
| | model = load_model() |
| | feature_names = model.feature_names_in_ |
| |
|
| | |
| | |
| | |
| | st.sidebar.header("β Prediction Settings") |
| |
|
| | threshold = st.sidebar.slider( |
| | "Failure Decision Threshold", |
| | min_value=0.10, |
| | max_value=0.90, |
| | value=0.50, |
| | step=0.01, |
| | help="Lower β detect more faults\nHigher β reduce false alarms" |
| | ) |
| |
|
| | st.sidebar.markdown("---") |
| | st.sidebar.write("**Engine Condition Meaning**") |
| | st.sidebar.write("0 β Normal") |
| | st.sidebar.write("1 β Faulty") |
| |
|
| | |
| | |
| | |
| | def get_severity(prob): |
| | if prob < 0.4: |
| | return "π’ Low Risk" |
| | elif prob < 0.7: |
| | return "π‘ Moderate Risk" |
| | else: |
| | return "π΄ High Risk" |
| |
|
| | |
| | |
| | |
| | st.header("π§ Manual Prediction") |
| |
|
| | cols = st.columns(3) |
| | inputs = [] |
| |
|
| | for i, feature in enumerate(feature_names): |
| | with cols[i % 3]: |
| | val = st.number_input(feature, value=0.0) |
| | inputs.append(val) |
| |
|
| | if st.button("Predict Engine Condition"): |
| |
|
| | input_df = pd.DataFrame([inputs], columns=feature_names) |
| |
|
| | prob = model.predict_proba(input_df)[0][1] |
| | prediction = 1 if prob >= threshold else 0 |
| | severity = get_severity(prob) |
| |
|
| | |
| | if prediction == 1: |
| | st.error("β Engine Likely Faulty") |
| | else: |
| | st.success("β
Engine Operating Normally") |
| |
|
| | st.write(f"### Failure Probability: **{prob:.3f}**") |
| | st.write(f"### Severity Level: {severity}") |
| |
|
| | |
| | fig, ax = plt.subplots() |
| | ax.barh(["Risk"], [prob]) |
| | ax.set_xlim(0,1) |
| | ax.set_title("Failure Risk Level") |
| | st.pyplot(fig) |
| |
|
| | |
| | |
| | |
| | st.header("π Batch Prediction") |
| |
|
| | uploaded_file = st.file_uploader("Upload CSV", type=["csv"]) |
| |
|
| | if uploaded_file is not None: |
| | try: |
| | df = pd.read_csv(uploaded_file) |
| |
|
| | if len(df) > 20000: |
| | st.warning("β Maximum 10,000 rows allowed.") |
| | else: |
| | missing_cols = [col for col in feature_names if col not in df.columns] |
| |
|
| | if missing_cols: |
| | st.error(f"Missing columns: {missing_cols}") |
| | else: |
| | df = df[feature_names] |
| |
|
| | probs = model.predict_proba(df)[:, 1] |
| | df["Failure_Probability"] = probs |
| | df["Prediction"] = (probs >= threshold).astype(int) |
| | df["Severity"] = df["Failure_Probability"].apply(get_severity) |
| |
|
| | st.success("β
Predictions completed") |
| |
|
| | st.dataframe(df.head()) |
| |
|
| | csv = df.to_csv(index=False).encode("utf-8") |
| |
|
| | st.download_button( |
| | "Download Results", |
| | csv, |
| | "engine_predictions.csv", |
| | "text/csv" |
| | ) |
| |
|
| | except Exception as e: |
| | st.error(f"Error: {e}") |
| |
|
| | |
| | |
| | |
| | st.markdown("---") |
| | st.subheader("π Model Information") |
| |
|
| | st.write("β Algorithm: Random Forest") |
| | st.write("β Handles feature correlation & non-linearity") |
| | st.write("β Optimized for predictive maintenance") |
| |
|
| | st.info( |
| | "Tip: Lower threshold if missing failures is costly.\n" |
| | "Raise threshold if false alarms are costly." |
| | ) |
| |
|
| | st.markdown("---") |
| | st.caption("Built for predictive maintenance monitoring") |
| |
|