import streamlit as st import numpy as np import pandas as pd import joblib # Set page config st.set_page_config(page_title="Stress Detection using One-Class SVM", layout="centered") # Custom CSS for background and styles st.markdown( """ """, unsafe_allow_html=True ) st.title("Stress Detection") st.markdown("Select a mode to detect stress from sensor readings:") # Load model and scaler try: model = joblib.load("one_class_svm_stress_model.pkl") scaler = joblib.load("scaler.pkl") except Exception as e: st.error(f"Error loading model or scaler: {e}") st.stop() # Load or create hardcoded dataset try: df = pd.read_csv("simulated_stress_data.csv") df = df[['HR', 'HRV', 'EDA']].head(100) except: df = pd.DataFrame({ "HR": np.random.randint(60, 120, 100), "HRV": np.random.uniform(20, 80, 100), "EDA": np.random.uniform(0.1, 5.0, 100) }) # Radio button selection mode = st.radio("Choose input mode:", ["Manual Readings", "Generate Readings", "Test Dataset"], horizontal=True) # Manual Input if mode == "Manual Readings": hr = st.number_input("Heart Rate (HR)", min_value=60, max_value=120, value=80) hrv = st.number_input("Heart Rate Variability (HRV)", min_value=20.0, max_value=80.0, value=50.0) eda = st.number_input("Electrodermal Activity (EDA)", min_value=0.1, max_value=5.0, value=2.0) if st.button("Predict"): sample = np.array([[hr, hrv, eda]]) scaled = scaler.transform(sample) pred = model.predict(scaled) label = "Stress" if pred[0] == -1 else "No Stress" st.markdown( f"""
HR: {hr} bpm
HRV: {hrv:.2f} ms
EDA: {eda:.2f} µS
""", unsafe_allow_html=True ) st.subheader("Prediction") if label == "No Stress": st.success(label) else: st.error(label) # Generate Random Input elif mode == "Generate Readings": if st.button("Generate and Predict"): hr = np.random.randint(60, 120) hrv = np.random.uniform(20, 80) eda = np.random.uniform(0.1, 5.0) sample = np.array([[hr, hrv, eda]]) scaled = scaler.transform(sample) pred = model.predict(scaled) label = "Stress" if pred[0] == -1 else "No Stress" st.markdown( f"""
HR: {hr} bpm
HRV: {hrv:.2f} ms
EDA: {eda:.2f} µS
""", unsafe_allow_html=True ) st.subheader("Prediction") if label == "No Stress": st.success(label) else: st.error(label) # Test Dataset (Scrollable) elif mode == "Test Dataset": st.markdown("### Select a row from test dataset for prediction:") # Session state for pagination and prediction result if "page" not in st.session_state: st.session_state.page = 0 if "last_prediction" not in st.session_state: st.session_state.last_prediction = None st.session_state.last_row = None rows_per_page = 5 df_filtered = df total_pages = max(1, (len(df_filtered) - 1) // rows_per_page + 1) # CSS for table rows st.markdown(""" """, unsafe_allow_html=True) # Display scrollable table with st.container(): #st.markdown('
', unsafe_allow_html=True) col1, col2, col3, col4 = st.columns([3, 3, 3, 2]) col1.markdown("**HR**") col2.markdown("**HRV**") col3.markdown("**EDA**") col4.markdown("**Predict**") page_data = df_filtered.iloc[ st.session_state.page * rows_per_page : (st.session_state.page + 1) * rows_per_page ] for idx, row in page_data.iterrows(): row_style = "row-box" col1, col2, col3, col4 = st.columns([3, 3, 3, 2]) with col1: st.markdown(f'
{row["HR"]}
', unsafe_allow_html=True) with col2: st.markdown(f'
{row["HRV"]:.2f}
', unsafe_allow_html=True) with col3: st.markdown(f'
{row["EDA"]:.2f}
', unsafe_allow_html=True) with col4: if st.button("Select", key=f"select_{idx}"): sample = np.array([[row['HR'], row['HRV'], row['EDA']]]) sample_scaled = scaler.transform(sample) pred = model.predict(sample_scaled) label = "Stress" if pred[0] == -1 else "No Stress" st.session_state.last_prediction = label st.session_state.last_row = row st.markdown('
', unsafe_allow_html=True) # Tighter Pagination Controls col1, col2, col3 = st.columns([1.2, 1.2, 3]) with col1: if st.button("⬅️ Previous"): if st.session_state.page > 0: st.session_state.page -= 1 with col2: if st.button("Next ➡️"): if st.session_state.page < total_pages - 1: st.session_state.page += 1 with col3: st.markdown( f"
Page {st.session_state.page + 1} of {total_pages}
", unsafe_allow_html=True ) # Final prediction display at the end if st.session_state.last_prediction and st.session_state.last_row is not None: row = st.session_state.last_row label = st.session_state.last_prediction st.markdown("---") st.markdown("### Prediction") st.markdown( f"""
HR: {row['HR']} bpm
HRV: {row['HRV']:.2f} ms
EDA: {row['EDA']:.2f} µS
""", unsafe_allow_html=True ) if label == "No Stress": st.success(label) else: st.error(label)