harshith1411's picture
Upload 10 files
90bbde0 verified
"""
🧠 Autism Spectrum Disorder Screening System
Professional Explainable AI Web Application with SHAP
"""
import streamlit as st
import pandas as pd
import numpy as np
import pickle
import shap
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler
import warnings
warnings.filterwarnings('ignore')
# ============================================================================
# PAGE CONFIGURATION
# ============================================================================
st.set_page_config(
page_title="🧠 Autism Spectrum Screening | AI-Powered",
page_icon="🧠",
layout="wide",
initial_sidebar_state="expanded"
)
# ============================================================================
# PROFESSIONAL STYLING
# ============================================================================
st.markdown("""
<style>
/* Main theme colors */
:root {
--primary: #6366f1;
--secondary: #ec4899;
--success: #10b981;
--warning: #f59e0b;
--danger: #ef4444;
--info: #3b82f6;
}
/* Global styles */
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
/* Metric cards */
.metric-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
text-align: center;
margin: 10px 0;
}
.metric-value {
font-size: 2.5em;
font-weight: bold;
margin: 10px 0;
}
/* Risk boxes */
.risk-high {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
}
.risk-medium {
background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
}
.risk-low {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}
.risk-box {
color: white;
padding: 30px;
border-radius: 15px;
text-align: center;
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
margin: 20px 0;
}
.risk-percentage {
font-size: 3.5em;
font-weight: 900;
margin: 15px 0;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.risk-label {
font-size: 1.5em;
font-weight: bold;
margin-top: 10px;
}
/* Info boxes */
.info-box {
background-color: #eff6ff;
border-left: 4px solid #3b82f6;
padding: 15px;
border-radius: 8px;
margin: 15px 0;
color: #000 !important;
}
.success-box {
background-color: #ecfdf5;
border-left: 4px solid #10b981;
padding: 15px;
border-radius: 8px;
margin: 15px 0;
color: #000 !important;
}
.warning-box {
background-color: #fffbeb;
border-left: 4px solid #f59e0b;
padding: 15px;
border-radius: 8px;
margin: 15px 0;
color: #000 !important;
}
.danger-box {
background-color: #fef2f2;
border-left: 4px solid #ef4444;
padding: 15px;
border-radius: 8px;
margin: 15px 0;
color: #000 !important;
}
.demographic-label {
color: white !important;
font-weight: 600;
}
.question-label {
color: white !important;
font-weight: 500;
}
/* Section styling */
.section-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white !important;
padding: 20px;
border-radius: 10px;
margin: 20px 0 15px 0;
font-size: 1.8em;
font-weight: bold;
}
.section-subheader {
color: white !important;
font-size: 1.2em;
font-weight: bold;
margin: 15px 0 10px 0;
}
.section-instructions {
background-color: rgba(102, 126, 234, 0.1);
color: white !important;
padding: 10px 15px;
border-left: 4px solid #667eea;
border-radius: 5px;
margin-bottom: 15px;
}
/* Buttons */
.stButton > button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 8px;
padding: 12px 24px;
font-size: 16px;
font-weight: 600;
width: 100%;
transition: all 0.3s ease;
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
}
.stButton > button:hover {
box-shadow: 0 8px 24px rgba(102, 126, 234, 0.5);
transform: translateY(-2px);
}
/* Header styling */
h1 {
color: #1f2937;
text-align: center;
margin-bottom: 30px;
font-size: 2.5em;
font-weight: 900;
}
h2 {
color: #374151;
border-bottom: 3px solid #667eea;
padding-bottom: 10px;
margin-top: 30px;
}
h3 {
color: #4b5563;
}
/* Tabs styling */
.stTabs [data-baseweb="tab-list"] {
gap: 10px;
}
.stTabs [data-baseweb="tab-list"] button {
background-color: #f3f4f6;
border-radius: 8px;
padding: 10px 20px;
}
.stTabs [data-baseweb="tab-list"] button[aria-selected="true"] {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
/* Form styling */
.stForm {
background-color: #f9fafb;
padding: 20px;
border-radius: 12px;
border: 1px solid #e5e7eb;
}
/* Sidebar */
.sidebar .sidebar-content {
background-color: #f8f9fa;
}
/* Footer */
.footer {
text-align: center;
padding: 20px;
border-top: 1px solid #e5e7eb;
color: #6b7280;
font-size: 0.9em;
margin-top: 40px;
}
</style>
""", unsafe_allow_html=True)
# ============================================================================
# LOAD MODELS AND DATA
# ============================================================================
@st.cache_resource
def load_models():
try:
with open('models/rf_model.pkl', 'rb') as f:
model = pickle.load(f)
with open('models/scaler.pkl', 'rb') as f:
scaler = pickle.load(f)
with open('models/le_dict.pkl', 'rb') as f:
le_dict = pickle.load(f)
with open('models/feature_names.pkl', 'rb') as f:
feature_names = pickle.load(f)
with open('models/shap_explainer.pkl', 'rb') as f:
explainer = pickle.load(f)
with open('models/shap_values.pkl', 'rb') as f:
shap_values_data = pickle.load(f)
return model, scaler, le_dict, feature_names, explainer, shap_values_data
except Exception as e:
st.error(f"❌ Error loading models: {str(e)}")
return None, None, None, None, None, None
model, scaler, le_dict, feature_names, explainer, shap_values_data = load_models()
models_ready = model is not None
# ============================================================================
# HEADER
# ============================================================================
st.markdown("""
<div style="text-align: center; margin-bottom: 40px;">
<h1>🧠 Autism Spectrum Disorder Screening</h1>
<p style="font-size: 1.2em; color: #6b7280; margin-top: -20px;">
<strong>AI-Powered Screening with Explainable Intelligence</strong>
</p>
<hr style="margin: 20px 0;">
</div>
""", unsafe_allow_html=True)
# ============================================================================
# SIDEBAR NAVIGATION
# ============================================================================
with st.sidebar:
st.markdown("### 🎯 Navigation Menu")
page = st.radio(
"Select Option:",
["🏠 Home", "πŸ“‹ Screening", "πŸ“Š Analytics", "❓ FAQ", "πŸ“š About"],
label_visibility="collapsed"
)
st.markdown("---")
st.markdown("""
### ℹ️ Quick Info
- **Status**: βœ… Production Ready
- **Model**: Random Forest
- **Accuracy**: 92.5%
- **Features**: 18
- **Training Data**: 704 records
""")
# ============================================================================
# HOME PAGE
# ============================================================================
if page == "🏠 Home":
col1, col2 = st.columns(2)
with col1:
st.markdown("""
### πŸ‘‹ Welcome!
This is a professional autism spectrum screening tool powered by
**Artificial Intelligence** and **Explainable AI (SHAP)**.
#### ✨ Key Features:
- πŸ€– **AI-Powered**: Trained on 704 patient records
- πŸ“Š **Explainable**: SHAP values explain every prediction
- 🎯 **Accurate**: 92.5% model accuracy
- πŸ”’ **Private**: No data stored
- ⚑ **Fast**: Instant results
- πŸ’» **Professional**: Healthcare-grade interface
""")
with col2:
# Display metrics
col2a, col2b = st.columns(2)
with col2a:
st.markdown("""
<div class="metric-card">
<div>πŸ“š Training Samples</div>
<div class="metric-value">704</div>
</div>
""", unsafe_allow_html=True)
st.markdown("""
<div class="metric-card">
<div>🎯 Accuracy</div>
<div class="metric-value">92.5%</div>
</div>
""", unsafe_allow_html=True)
with col2b:
st.markdown("""
<div class="metric-card">
<div>🧠 Features</div>
<div class="metric-value">18</div>
</div>
""", unsafe_allow_html=True)
st.markdown("""
<div class="metric-card">
<div>⚑ Response</div>
<div class="metric-value">&lt;1s</div>
</div>
""", unsafe_allow_html=True)
st.markdown("---")
# Workflow explanation
st.markdown("### πŸ”„ How It Works")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.markdown("""
#### 1️⃣ Input
Fill out the screening questionnaire with AQ-10 assessment and demographic info
""")
with col2:
st.markdown("""
#### 2️⃣ Process
AI model processes your responses and generates prediction
""")
with col3:
st.markdown("""
#### 3️⃣ Analysis
SHAP explainability shows which factors influenced the result
""")
with col4:
st.markdown("""
#### 4️⃣ Report
Get clear risk assessment with professional recommendations
""")
st.markdown("---")
# Important disclaimers
st.markdown("""
<div class="danger-box">
⚠️ <strong>IMPORTANT DISCLAIMER</strong><br>
This tool is for SCREENING purposes ONLY and NOT for clinical diagnosis.
Always consult with qualified healthcare professionals for:
- Accurate diagnosis
- Treatment decisions
- Clinical recommendations
</div>
""", unsafe_allow_html=True)
# ============================================================================
# SCREENING PAGE
# ============================================================================
elif page == "πŸ“‹ Screening":
if not models_ready:
st.error("❌ Models not loaded. Please check model files.")
else:
st.markdown("# πŸ“‹ AUTISM SPECTRUM QUOTIENT SCREENING")
st.markdown("## Complete Assessment & Demographics")
st.markdown("---")
st.markdown('''
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
border-radius: 10px;
margin: 20px 0 15px 0;
font-size: 1.8em;
font-weight: bold;
text-align: left;">
🧠 AQ-10 ASSESSMENT QUESTIONS
</div>
''', unsafe_allow_html=True)
st.markdown('''
<div style="background-color: rgba(102, 126, 234, 0.1);
color: white;
padding: 10px 15px;
border-left: 4px solid #667eea;
border-radius: 5px;
margin-bottom: 15px;">
<strong>Instructions:</strong> Rate each statement on a scale of 0 (Disagree) to 1 (Agree)
</div>
''', unsafe_allow_html=True)
st.markdown("")
col1, col2 = st.columns(2)
with col1:
st.markdown('<div class="section-subheader">Questions 1-5</div>', unsafe_allow_html=True)
st.markdown('<p class="question-label">1. Prefer focusing on details</p>', unsafe_allow_html=True)
A1 = st.slider("1. Prefer focusing on details", 0, 1, 0, key="A1", label_visibility="collapsed")
st.markdown('<p class="question-label">2. Must have sameness and routine</p>', unsafe_allow_html=True)
A2 = st.slider("2. Must have sameness and routine", 0, 1, 0, key="A2", label_visibility="collapsed")
st.markdown('<p class="question-label">3. Prefer reading systematically</p>', unsafe_allow_html=True)
A3 = st.slider("3. Prefer reading systematically", 0, 1, 0, key="A3", label_visibility="collapsed")
st.markdown('<p class="question-label">4. Feel anxious in social situations</p>', unsafe_allow_html=True)
A4 = st.slider("4. Feel anxious in social situations", 0, 1, 0, key="A4", label_visibility="collapsed")
st.markdown('<p class="question-label">5. Prefer one-to-one conversation</p>', unsafe_allow_html=True)
A5 = st.slider("5. Prefer one-to-one conversation", 0, 1, 0, key="A5", label_visibility="collapsed")
with col2:
st.markdown('<div class="section-subheader">Questions 6-10</div>', unsafe_allow_html=True)
st.markdown('<p class="question-label">6. Notice small environmental changes</p>', unsafe_allow_html=True)
A6 = st.slider("6. Notice small environmental changes", 0, 1, 0, key="A6", label_visibility="collapsed")
st.markdown('<p class="question-label">7. Trouble focusing while changing activities</p>', unsafe_allow_html=True)
A7 = st.slider("7. Trouble focusing while changing activities", 0, 1, 0, key="A7", label_visibility="collapsed")
st.markdown('<p class="question-label">8. Often daydream</p>', unsafe_allow_html=True)
A8 = st.slider("8. Often daydream", 0, 1, 0, key="A8", label_visibility="collapsed")
st.markdown('<p class="question-label">9. Focused on one topic at a time</p>', unsafe_allow_html=True)
A9 = st.slider("9. Focused on one topic at a time", 0, 1, 0, key="A9", label_visibility="collapsed")
st.markdown('<p class="question-label">10. Difficult having small talk</p>', unsafe_allow_html=True)
A10 = st.slider("10. Difficult having small talk", 0, 1, 0, key="A10", label_visibility="collapsed")
st.markdown("---")
# ============= DEMOGRAPHIC INFORMATION SECTION =============
st.markdown('''
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
border-radius: 10px;
margin: 20px 0 15px 0;
font-size: 1.8em;
font-weight: bold;
text-align: left;">
πŸ“‹ DEMOGRAPHIC INFORMATION
</div>
''', unsafe_allow_html=True)
st.markdown('''
<div style="background-color: rgba(102, 126, 234, 0.1);
color: white;
padding: 10px 15px;
border-left: 4px solid #667eea;
border-radius: 5px;
margin-bottom: 15px;">
<strong>Instructions:</strong> Please provide the following details about yourself
</div>
''', unsafe_allow_html=True)
col1, col2 = st.columns(2)
with col1:
st.markdown('<p class="demographic-label">Age</p>', unsafe_allow_html=True)
age = st.number_input("Age", min_value=1, max_value=120, value=30, label_visibility="collapsed")
st.markdown('<p class="demographic-label">Ethnicity</p>', unsafe_allow_html=True)
ethnicity = st.selectbox("Ethnicity", [
"white European", "latino", "asian", "black",
"middle eastern", "mixed", "others"
], label_visibility="collapsed")
st.markdown('<p class="demographic-label">Jaundice at Birth</p>', unsafe_allow_html=True)
jundice = st.selectbox("Jaundice at Birth", ["no", "yes"], label_visibility="collapsed")
st.markdown('<p class="demographic-label">Used App Before</p>', unsafe_allow_html=True)
used_app = st.selectbox("Used App Before", ["no", "yes"], label_visibility="collapsed")
with col2:
st.markdown('<p class="demographic-label">Gender</p>', unsafe_allow_html=True)
gender = st.selectbox("Gender", ["m", "f"], label_visibility="collapsed")
st.markdown('<p class="demographic-label">Country</p>', unsafe_allow_html=True)
country = st.selectbox("Country", [
"United States", "United Kingdom", "Canada", "Australia",
"India", "Brazil", "others"
], label_visibility="collapsed")
st.markdown('<p class="demographic-label">Family History of Autism</p>', unsafe_allow_html=True)
autism_family = st.selectbox("Family History of Autism", ["no", "yes"], label_visibility="collapsed")
st.markdown('<p class="demographic-label">Screening Type</p>', unsafe_allow_html=True)
screening_type = st.selectbox("Screening Type", ["adult", "clinical"], label_visibility="collapsed")
st.markdown("---")
# Display live score (NOT inside form - updates in real-time)
current_score = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10
col_score1, col_score2 = st.columns(2)
with col_score1:
st.metric("Your AQ-10 Score", f"{current_score}/10", delta=None)
with col_score2:
if current_score >= 7:
risk_text = "πŸ”΄ HIGH RISK PROFILE"
risk_color = "#ef4444"
elif current_score >= 5:
risk_text = "🟑 MEDIUM RISK PROFILE"
risk_color = "#f59e0b"
else:
risk_text = "🟒 LOW RISK PROFILE"
risk_color = "#10b981"
st.markdown(f'<p style="font-size: 18px; color: {risk_color}; font-weight: bold;">{risk_text}</p>', unsafe_allow_html=True)
st.markdown("---")
st.markdown('''
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
border-radius: 10px;
margin: 20px 0 15px 0;
font-size: 1.8em;
font-weight: bold;
text-align: left;">
πŸ“€ Submit Assessment
</div>
''', unsafe_allow_html=True)
# Use regular button instead of form
if st.button("ANALYZE & GET RESULTS", use_container_width=True, key="submit_btn"):
try:
# Prepare input data
input_dict = {
'A1_prefer_detail_not_big_picture': A1,
'A2_must_have_sameness': A2,
'A3_prefer_reading_systematically': A3,
'A4_feel_anxious_in_social': A4,
'A5_prefer_talking_one_to_one': A5,
'A6_notice_small_changes': A6,
'A7_trouble_focus_on_changing': A7,
'A8_often_daydream': A8,
'A9_focused_on_one_topic': A9,
'A10_difficult_small_talk': A10,
'age': age,
'gender': gender,
'ethnicity': ethnicity,
'jundice': jundice,
'autism_family_member': autism_family,
'country': country,
'used_app_before': used_app,
'screening_type': screening_type
}
input_df = pd.DataFrame([input_dict])
# Encode categorical variables
input_encoded = input_df.copy()
# Define value mappings for categorical fields - case insensitive lookup
value_mappings = {
'gender': {
'm': 'M', 'f': 'F', 'male': 'M', 'female': 'F'
},
'ethnicity': {
'white european': 'White', 'white': 'White',
'latino': 'Others', 'latin american': 'Others',
'asian': 'Asian',
'black': 'Black', 'african american': 'Black',
'middle eastern': 'Others', 'middle eastern/north african': 'Others',
'mixed': 'Others',
'others': 'Others', 'other': 'Others'
},
'country': {
'united states': 'USA', 'usa': 'USA', 'us': 'USA',
'united kingdom': 'UK', 'uk': 'UK',
'canada': 'Canada',
'australia': 'USA', # Map to USA as default for unknown countries
'india': 'India',
'brazil': 'USA',
'others': 'USA', 'other': 'USA'
},
'screening_type': {
'adult': 'Questionnaire', 'questionnaire': 'Questionnaire',
'clinical': 'Interview', 'interview': 'Interview'
},
'jundice': {
'yes': 'yes', 'no': 'no',
'y': 'yes', 'n': 'no'
},
'autism_family_member': {
'yes': 'yes', 'no': 'no',
'y': 'yes', 'n': 'no'
},
'used_app_before': {
'yes': 'yes', 'no': 'no',
'y': 'yes', 'n': 'no'
}
}
# Handle categorical encoding with robust error handling
for col in input_df.columns:
if col in le_dict:
try:
input_encoded[col] = le_dict[col].transform(input_df[col])
except ValueError as e:
original_val = str(input_df[col].values[0]).strip()
# Get encoder's valid classes
valid_classes = le_dict[col].classes_
# Try mapping if available
if col in value_mappings:
mapped_val = value_mappings[col].get(original_val.lower(), None)
if mapped_val and mapped_val in valid_classes:
input_encoded[col] = le_dict[col].transform([mapped_val])
else:
# If mapping didn't work, try exact case match
if original_val in valid_classes:
input_encoded[col] = le_dict[col].transform([original_val])
else:
# Last resort: case-insensitive search in valid classes
for vc in valid_classes:
if vc.lower() == original_val.lower():
input_encoded[col] = le_dict[col].transform([vc])
break
else:
raise ValueError(f"No valid mapping for '{original_val}' in {col}. Valid options: {list(valid_classes)}")
else:
# For columns without mapping, try case-insensitive match
for vc in valid_classes:
if vc.lower() == original_val.lower():
input_encoded[col] = le_dict[col].transform([vc])
break
else:
raise ValueError(f"Invalid value '{original_val}' for {col}. Valid options: {list(valid_classes)}")
# Scale numeric features
# Only scale the 11 numeric columns that were scaled during training
numeric_cols = ['A1_prefer_detail_not_big_picture', 'A2_must_have_sameness',
'A3_prefer_reading_systematically', 'A4_feel_anxious_in_social',
'A5_prefer_talking_one_to_one', 'A6_notice_small_changes',
'A7_trouble_focus_on_changing', 'A8_often_daydream',
'A9_focused_on_one_topic', 'A10_difficult_small_talk', 'age']
input_scaled = input_encoded.copy()
input_scaled[numeric_cols] = scaler.transform(input_encoded[numeric_cols])
# Reorder columns to match feature_names exactly
input_scaled = input_scaled[feature_names]
# Verify shape before prediction
if input_scaled.shape[1] != len(feature_names):
raise ValueError(f"Feature count mismatch: got {input_scaled.shape[1]}, expected {len(feature_names)}")
# Get prediction
pred_proba = model.predict_proba(input_scaled)[0]
autism_prob = pred_proba[1]
# DEBUG: Show what we're sending to model
st.write("πŸ“Š **DEBUG INFO:**")
st.write(f"AQ-10 Score: {A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10}/10")
st.write(f"Age: {age}, Gender: {gender}, Ethnicity: {ethnicity}")
st.write(f"Model Input Shape: {input_scaled.shape}")
st.write(f"Prediction Probabilities: Class 0 (No Autism)={pred_proba[0]:.4f}, Class 1 (Autism)={pred_proba[1]:.4f}")
# Risk classification
if autism_prob >= 0.7:
risk_level = "πŸ”΄ HIGH RISK"
risk_class = "risk-high"
recommendation = "high"
elif autism_prob >= 0.5:
risk_level = "🟑 MEDIUM RISK"
risk_class = "risk-medium"
recommendation = "medium"
else:
risk_level = "🟒 LOW RISK"
risk_class = "risk-low"
recommendation = "low"
# Display results
st.markdown("---")
st.markdown("### 🎯 Screening Results")
# Main risk box
st.markdown(f"""
<div class="risk-box {risk_class}">
<div class="risk-percentage">{autism_prob*100:.1f}%</div>
<div class="risk-label">{risk_level}</div>
<div style="margin-top: 15px; font-size: 0.95em; opacity: 0.95;">
Autism Spectrum Screening Score
</div>
</div>
""", unsafe_allow_html=True)
# Metrics
col1, col2, col3 = st.columns(3)
with col1:
st.metric("🧠 Autism Probability", f"{autism_prob*100:.1f}%")
with col2:
st.metric("βœ… No Autism Probability", f"{pred_proba[0]*100:.1f}%")
with col3:
st.metric("πŸ“Š Model Confidence", f"{max(pred_proba)*100:.1f}%")
# ============================================================
# CLINICAL RECOMMENDATIONS SECTION
# ============================================================
st.markdown("---")
st.markdown("### πŸ“‹ Recommended Next Steps")
if recommendation == "high":
st.markdown("<div style='background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: black; padding: 25px; border-radius: 12px; border-left: 5px solid #dc2626; box-shadow: 0 4px 12px rgba(245, 87, 108, 0.3);'><h3 style='margin-top: 0; color: black;'>πŸ”΄ HIGH RISK PROFILE</h3><h4 style='color: black;'>Recommended Actions:</h4><ul><li><strong>Schedule consultation with autism specialist</strong> within 1-2 weeks</li><li><strong>Prepare documentation:</strong> Family history, symptom timeline, developmental milestones</li><li><strong>Share this report</strong> with your healthcare provider</li><li><strong>Request formal diagnostic evaluation</strong> using DSM-5 criteria</li></ul><h4 style='color: black;'>Clinical Indicators Noted:</h4><ul><li>Strong autism spectrum traits detected</li><li>Recommend urgent professional assessment</li><li>Multiple screening factors present</li></ul><p style='margin-bottom: 0; font-style: italic; font-size: 0.9em;'>⚠️ <strong>Important:</strong> This is a screening tool, not a diagnosis. Only a qualified medical professional can diagnose autism.</p></div>", unsafe_allow_html=True)
elif recommendation == "medium":
st.markdown("<div style='background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); color: black; padding: 25px; border-radius: 12px; border-left: 5px solid #f59e0b; box-shadow: 0 4px 12px rgba(245, 158, 11, 0.3);'><h3 style='margin-top: 0; color: black;'>🟑 MEDIUM RISK PROFILE</h3><h4 style='color: black;'>Recommended Actions:</h4><ul><li><strong>Schedule follow-up assessment</strong> within 6-12 months</li><li><strong>Monitor for symptom changes</strong> over next 3-6 months</li><li><strong>Consider clinical evaluation</strong> if symptoms worsen or new concerns arise</li><li><strong>Discuss results</strong> with your primary healthcare provider</li></ul><h4 style='color: black;'>Clinical Indicators Noted:</h4><ul><li>Moderate autism spectrum traits present</li><li>Pattern suggests further assessment may be beneficial</li><li>Consider evaluation based on symptom severity</li></ul><p style='margin-bottom: 0; font-style: italic; font-size: 0.9em;'>⚠️ <strong>Important:</strong> This is a screening tool, not a diagnosis. Consult healthcare professionals for clinical decisions.</p></div>", unsafe_allow_html=True)
else: # LOW RISK
st.markdown("<div style='background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: black; padding: 25px; border-radius: 12px; border-left: 5px solid #10b981; box-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);'><h3 style='margin-top: 0; color: black;'>🟒 LOW RISK PROFILE</h3><h4 style='color: black;'>Recommended Actions:</h4><ul><li><strong>No immediate clinical concern</strong> based on current screening</li><li><strong>Rescreen</strong> if new symptoms develop in future</li><li><strong>Contact healthcare provider</strong> only if symptoms emerge</li><li><strong>Routine monitoring</strong> through regular health check-ups</li></ul><h4 style='color: black;'>Clinical Indicators Noted:</h4><ul><li>Minimal autism spectrum traits detected</li><li>Screening suggests low probability of autism spectrum disorder</li><li>Current presentation does not warrant urgent referral</li></ul><p style='margin-bottom: 0; font-style: italic; font-size: 0.9em;'>βœ… <strong>Note:</strong> Negative screening does not completely rule out autism. Consult professionals if concerns arise.</p></div>", unsafe_allow_html=True)
# Disclaimer
st.markdown("---")
st.markdown("""
<div style="background-color: #fee2e2;
border-left: 4px solid #dc2626;
padding: 15px;
border-radius: 8px;
color: #7f1d1d;">
<strong>⚠️ IMPORTANT MEDICAL DISCLAIMER</strong><br>
This tool provides screening assistance only and should NOT be used for self-diagnosis.
Autism Spectrum Disorder diagnosis requires comprehensive evaluation by qualified healthcare professionals including psychiatrists, psychologists, or neurologists.
Always consult with medical professionals for accurate diagnosis and treatment recommendations.
</div>
""", unsafe_allow_html=True)
# Visualization
col1, col2 = st.columns(2)
with col1:
fig, ax = plt.subplots(figsize=(8, 6))
colors = ['#10b981', '#ef4444']
ax.pie([pred_proba[0], pred_proba[1]], labels=['No ASD', 'ASD'],
autopct='%1.1f%%', colors=colors, explode=(0.05, 0.05), startangle=90)
ax.set_title('Prediction Probability Distribution', fontweight='bold', fontsize=12)
st.pyplot(fig)
with col2:
fig, ax = plt.subplots(figsize=(8, 6))
ax.barh(['No ASD', 'ASD'], pred_proba, color=['#10b981', '#ef4444'])
ax.set_xlabel('Probability', fontweight='bold')
ax.set_title('Risk Comparison', fontweight='bold', fontsize=12)
for i, v in enumerate(pred_proba):
ax.text(v + 0.02, i, f'{v:.1%}', va='center', fontweight='bold')
st.pyplot(fig)
# SHAP Explanation
st.markdown("---")
st.markdown("### πŸ“Š Feature Contribution Analysis (SHAP)")
st.markdown("*Shows which factors most influenced this prediction*")
try:
shap_vals = explainer.shap_values(input_scaled)
if isinstance(shap_vals, list):
shap_class1 = np.array(shap_vals[1])[0]
else:
shap_class1 = shap_vals[:, :, 1][0]
contributions = pd.DataFrame({
'Feature': feature_names,
'Impact': np.abs(shap_class1)
}).sort_values('Impact', ascending=True).tail(10)
fig, ax = plt.subplots(figsize=(10, 6))
colors = ['#ef4444' if shap_class1[feature_names.index(f)] > 0 else '#10b981'
for f in contributions['Feature']]
ax.barh(range(len(contributions)), contributions['Impact'], color=colors)
ax.set_yticks(range(len(contributions)))
ax.set_yticklabels(contributions['Feature'])
ax.set_xlabel('Contribution Magnitude', fontweight='bold')
ax.set_title('Top 10 Features Influencing This Prediction', fontweight='bold')
ax.invert_yaxis()
plt.tight_layout()
st.pyplot(fig)
except Exception as e:
st.warning(f"Could not generate SHAP visualization: {str(e)}")
# Recommendations
st.markdown("---")
st.markdown("### πŸ’‘ Professional Recommendations")
if recommendation == "low":
st.markdown("<div class='success-box' style='color: #000;'><strong style='color: #000;'>βœ… LOW RISK ASSESSMENT</strong><br><span style='color: #000;'>Based on the screening assessment, the likelihood of autism spectrum disorder appears low. Continue with routine monitoring and healthy practices.</span></div>", unsafe_allow_html=True)
elif recommendation == "medium":
st.markdown("<div class='warning-box' style='color: #000;'><strong style='color: #000;'>⚠️ MEDIUM RISK ASSESSMENT</strong><br><span style='color: #000;'>Some indicators are present. Professional consultation is recommended. Consider scheduling an appointment with a specialist for formal evaluation.</span></div>", unsafe_allow_html=True)
else: # high
st.markdown("<div class='danger-box' style='color: #000;'><strong style='color: #000;'>πŸ”΄ HIGH RISK ASSESSMENT</strong><br><span style='color: #000;'>Multiple indicators detected. Professional consultation is highly recommended. Please schedule an appointment with an autism specialist for comprehensive evaluation and diagnosis.</span></div>", unsafe_allow_html=True)
st.success("βœ… Analysis Complete! Review the results above.")
except Exception as e:
st.error(f"❌ Error during analysis: {str(e)}")
st.info("πŸ’‘ Tip: Please check that all fields are filled correctly.")
# For debugging
#st.write(f"Debug Info: {e}")
#st.write(f"Input data: {input_dict}")
# ============================================================================
# ANALYTICS PAGE
# ============================================================================
elif page == "πŸ“Š Analytics":
st.markdown("### πŸ“Š Model Analytics & Performance")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("πŸ“š Training Samples", "704")
with col2:
st.metric("🎯 Model Accuracy", "92.5%")
with col3:
st.metric("🧠 Total Features", "18")
with col4:
st.metric("πŸ”„ Model Type", "Random Forest")
st.markdown("---")
st.markdown("### 🌟 Top Contributing Features")
try:
if isinstance(shap_values_data, np.ndarray) and shap_values_data.ndim == 3:
shap_class1 = shap_values_data[:, :, 1]
mean_shap = np.abs(shap_class1).mean(axis=0)
else:
mean_shap = np.abs(shap_values_data[1]).mean(axis=0)
top_features = pd.DataFrame({
'Feature': feature_names,
'Importance': mean_shap
}).sort_values('Importance', ascending=False).head(10)
fig, ax = plt.subplots(figsize=(10, 6))
ax.barh(range(len(top_features)), top_features['Importance'], color='#667eea')
ax.set_yticks(range(len(top_features)))
ax.set_yticklabels(top_features['Feature'])
ax.set_xlabel('Mean |SHAP Value|', fontweight='bold')
ax.set_title('Top 10 Most Important Features for ASD Prediction', fontweight='bold')
ax.invert_yaxis()
plt.tight_layout()
st.pyplot(fig)
st.markdown("### πŸ“ˆ Feature Importance Breakdown")
for idx, row in top_features.iterrows():
st.write(f"**{idx+1}. {row['Feature']}** - Importance: {row['Importance']:.4f}")
except:
st.warning("Feature importance data not available")
# ============================================================================
# FAQ PAGE
# ============================================================================
elif page == "❓ FAQ":
st.markdown("### ❓ Frequently Asked Questions")
with st.expander("❓ What is this screening tool?"):
st.write("""
This is an AI-powered autism spectrum screening tool that uses machine learning
(Random Forest) and explainable AI (SHAP) to assess the likelihood of autism
spectrum disorder based on AQ-10 assessment and demographic information.
""")
with st.expander("❓ Is this a clinical diagnosis?"):
st.write("""
NO. This tool is for SCREENING purposes only. It is NOT a clinical diagnosis.
A qualified healthcare professional must perform formal evaluation for definitive diagnosis.
""")
with st.expander("❓ How accurate is this tool?"):
st.write("""
The model achieves 92.5% accuracy on test data. However, individual predictions
may vary and should always be validated by healthcare professionals.
""")
with st.expander("❓ What do the SHAP values mean?"):
st.write("""
SHAP (SHapley Additive exPlanations) values show how much each feature
contributed to the prediction. Longer bars indicate stronger influence on the result.
""")
with st.expander("❓ Is my data private and secure?"):
st.write("""
Yes. No data is stored on any server or database. All processing happens
locally on your device. Your information is completely private.
""")
with st.expander("❓ What should I do with my results?"):
st.write("""
Use these results as a conversation starter with healthcare providers.
Share your screening results with specialists who can perform proper evaluation
and provide professional recommendations.
""")
with st.expander("❓ How long does the screening take?"):
st.write("""
The screening assessment and analysis takes less than 1 minute.
The questionnaire itself takes about 5-10 minutes to complete.
""")
# ============================================================================
# ABOUT PAGE
# ============================================================================
elif page == "πŸ“š About":
col1, col2 = st.columns([2, 1])
with col1:
st.markdown("""
### 🧠 About Autism Spectrum Disorder
Autism Spectrum Disorder (ASD) is a neurodevelopmental condition that affects
how individuals communicate, behave, and interact socially. It exists on a spectrum,
with individuals showing varying levels of support needs.
**Key characteristics may include:**
- Differences in social communication
- Repetitive behaviors or interests
- Sensory sensitivities
- Unique strengths in specific areas
Early screening and intervention can significantly improve outcomes and quality of life.
### πŸ€– About This Application
**Technology Stack:**
- **Python 3.14.2**: Programming language
- **Streamlit**: Web application framework
- **Scikit-learn**: Machine learning library
- **SHAP**: Model explainability tool
- **Pandas & NumPy**: Data manipulation
- **Matplotlib & Seaborn**: Visualization
**Model Details:**
- **Algorithm**: Random Forest Classifier
- **Training Data**: 704 patient records
- **Features**: 18 screening and demographic features
- **Accuracy**: 92.5% on test set
- **Explainability**: SHAP-based feature importance
### πŸ“– About SHAP
SHAP (SHapley Additive exPlanations) is a game-theoretic approach to explain
machine learning predictions. It provides interpretable explanations by computing
the contribution of each feature to each prediction.
""")
with col2:
st.markdown("""
### πŸ”— Resources
**For More Information:**
- American Psychiatric Association
- National Institute of Mental Health
- Autism Society
- World Health Organization
### πŸ‘¨β€βš•οΈ Healthcare Professionals
This tool is designed to support clinical decision-making but should always
be used in conjunction with professional judgment and formal diagnostic criteria.
### πŸ“ž Support
For questions or technical support, please contact the development team.
---
**Version:** 1.0
**Status:** βœ… Production Ready
**Last Updated:** March 2026
""")
# ============================================================================
# FOOTER
# ============================================================================
st.markdown("---")
st.markdown("""
<div style="text-align: center; padding: 20px; color: #6b7280; font-size: 0.9em; border-top: 1px solid #e5e7eb;">
<strong>πŸ₯ Autism Spectrum Disorder Screening System</strong><br>
Powered by Explainable AI (SHAP) | Machine Learning | Streamlit<br>
<em>For screening purposes only | Always consult healthcare professionals</em><br>
Β© 2026 All Rights Reserved | Status: βœ… Production Ready
</div>
""", unsafe_allow_html=True)